2014-11-06 2 views
2

Я использую CUPS4J для моего проекта, который зависит от http-client, http-core и slf4j.java.lang.LinkageError на Websphere при попытке загрузить HttpUriRequest

Для разрешения зависимостей, которые мы используем Maven, и я определил зависимости следующим образом:

<dependency> 
    <groupId>cups4j</groupId> 
    <artifactId>cups4j</artifactId> 
    <version>0.6.4</version> 
</dependency> 

<dependency> 
    <groupId>org.apache.httpcomponents</groupId> 
    <artifactId>httpclient</artifactId> 
    <version>4.0.3</version> 
</dependency> 

<dependency> 
    <groupId>org.apache.httpcomponents</groupId> 
    <artifactId>httpcore</artifactId> 
    <version>4.1</version> 
</dependency> 

<dependency> 
    <groupId>org.slf4j</groupId> 
    <artifactId>slf4j-api</artifactId> 
    <version>1.7.7</version> 
</dependency> 

cups4j зависимость на нашем Artifactory сервере (я не мог найти его в Интернете).

Все работает как шарм, если я создаю образец main, чтобы напечатать некоторый документ и запустить его как приложение Java.

Когда я публикую свои классы на сервере Websphere и вызываю этот метод с веб-страницы, он генерирует java.lang.LinkageError.

Это соответствующая часть StackTrace:

Caused by: java.lang.LinkageError: loader constraint violation: loader "org/eclipse/osgi/internal/baseadaptor/[email protected]" previously initiated loading for a different type with name "org/apache/http/client/methods/HttpUriRequest" defined by loader "com/ibm/ws/classloader/[email protected]" 
    at java.lang.ClassLoader.defineClassImpl(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:260) 
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:188) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:580) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:550) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:481) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass_LockClassName(ClasspathManager.java:460) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:447) 
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216) 
    at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:393) 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:469) 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422) 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410) 
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:612) 
    at org.apache.http.impl.client.AbstractHttpClient.determineTarget(AbstractHttpClient.java:584) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:708) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:700) 
    at org.cups4j.operations.IppOperation.sendRequest(IppOperation.java:207) 
    at org.cups4j.operations.IppOperation.request(IppOperation.java:76) 
    at org.cups4j.CupsPrinter.print(CupsPrinter.java:113) 
    at it.dropcomp.tasks.print.PrinterService.printPDF(PrinterService.java:160) 

Это метод, который печатает PDF (внутри it.dropcomp.tasks.print.PrinterService):

public void printPDF() throws RemoteServiceException { 
    /* 
    * generatedPDF is defined as File, and it's properly initialized 
    * before calling this method. 
    */ 
    if(generatedPDF == null) { 
     throw new RemoteServiceException("You must generate a file first!"); 
    } 
    try { 
     CupsPrinter selectedPrinter = new CupsPrinter(
      new URL(Constants.PRINTER_FULL_URL), 
      Constants.PRINTER_NAME, true 
     ); 
     InputStream is = new FileInputStream(generatedPDF); 
     PrintJob pj = new PrintJob.Builder(is).build(); 
     selectedPrinter.print(pj); //this is line 160 
    } catch (Exception e) { 
     LOG.error("Exception", e); 
     throw new RemoteServiceException(e); 
    } 
} 

Кажется, что HttpUriRequest уже существует и делает конфликт с тот, который предоставляется библиотекой httpclient из Apache, но если я попытаюсь удалить эту зависимость от pom.xml, я получаю NoClassDefFoundException для этого класса.

Если это имеет значение, моя IDE - Eclipse Luna.

Как я могу решить это исключение?

ответ

0

WebSphere также использует библиотеку httpclient, которая может конфликтовать с той, которую вы предоставляете. Попробуйте создать изолированную общую библиотеку в консоли администратора через Environment > Shared Libraries. Поместите http-*, slf4j и cups4j банки и свяжите эту общую библиотеку с вашим приложением.

+0

К сожалению, я не могу. Я должен использовать Maven для разрешения зависимостей, я работаю в команде, и руководитель группы хочет, чтобы это было сделано таким образом. Я читал, что могу сообщить maven, что библиотека предоставлена, чтобы она не включала банку, когда приложение развертывается на сервере. Я постараюсь с этим подходом, возможно, это решает проблему. Спасибо! – BackSlash

+0

@BackSlash Вы все еще можете «строить» с помощью maven, с этим нет проблем, но, как вы писали, вам нужно пометить эти зависимости как предоставленные и не включать в приложение, но, к сожалению, настроить его на сервере приложений как библиотеку. Вы можете попытаться изменить только загрузчик классов в настройках приложения на Parent Last, но это скорее не решит вашу проблему. – Gas

Смежные вопросы