JBoss7: нарушение ограничений загрузчика с помощью ReastEasy и httpclient с пользовательским HttpRequestInterceptor

Я использую RestEasy Client Framework в @Named @ViewScoped Bean с JBoss-7.1.1-Final для извлечения данных из службы REST с пользовательским HttpRequestInterceptor:

RegisterBuiltin.register(ResteasyProviderFactory.getInstance());

DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.addRequestInterceptor(new PreemptiveAuthInterceptor("test","test"), 0);

ClientExecutor clientExecutor = new ApacheHttpClient4Executor(httpClient); //<---

//The error occurs above, the code below is only for completeness
MyRest rest = ProxyFactory.create(MyRest.class,
                                    "http://localhost:8080/rest",clientExecutor);

Это отлично работает в автономном клиентском приложении (также нормально, когда я удаляю ClientExecutor, но мне это нужно для аутентификации службы REST). Компонент находится в модуле WAR внутри модуля EAR, иерархия зависимостей resteasy сводится к следующему:

Resteasy зависимость

В WAR или EAR нет httpclient или httpcore. Внутри Bean я получаю следующее исключение:

java.lang.NoClassDefFoundError: org/apache/http/HttpRequestInterceptor

Кажется, это легко (хотя мне интересно, как упаковать resteasy), и я добавил org.apache.httpcomponents:httpclient с областью действия compile:

введите здесь описание изображения

Нет, я получаю следующее исключение:

java.lang.LinkageError: loader constraint violation: when resolving method   
  "org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor.<init>    
  (Lorg/apache/http/client/HttpClient;)V"
  the class loader (instance of org/jboss/modules/ModuleClassLoader)
      of the current class, my/TestBean, and
  the class loader (instance of org/jboss/modules/ModuleClassLoader)
      for resolved class, 
  org/jboss/resteasy/client/core/executors/ApacheHttpClient4Executor,
  have different Class objects for the type org/apache/http/client/HttpClient
  used in the signature my.TestBean.init(TestBean.java:65)

Обновление. Чтобы воспроизвести это, вам не нужны интерфейсы REST, ошибка возникает при создании экземпляра ApacheHttpClient4Executor, но вам может понадобиться пользовательский PreemptiveAuthInterceptor:

public class PreemptiveAuthInterceptor implements HttpRequestInterceptor
{
  private String username;
  private String password;

  public PreemptiveAuthInterceptor(String username, String password)
  {
    this.username=username;
    this.password=password;
  }

  @Override
  public void process(org.apache.http.HttpRequest request, HttpContext context) throws HttpException, IOException
  {
    AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);

    authState.setAuthScope(org.apache.http.auth.AuthScope.ANY);
    authState.setCredentials(new UsernamePasswordCredentials(username,password));
    authState.setAuthScheme(new BasicScheme());

  }
}

person Thor    schedule 15.05.2012    source источник
comment
Это было ошибкой некоторое время: issues.jboss.org/browse/AS7-2803   -  person Phyxx    schedule 02.08.2012


Ответы (4)


Чтобы избежать ошибки связывания при развертывании приложения на JBoss, настройте модуль org.apache.httpcomponents в папке модулей установки JBoss, но избегайте включения файлов JAR из HttpComponents в ваше приложение:

  1. Поместите необходимые JAR-файлы из HttpComponents в modules/org/apache/httpcomponents/main.
  2. Перечислите эти JAR-файлы в module.xml в этом каталоге.
  3. Добавьте Dependencies: org.apache.httpcomponents к MANIFEST.MF вашего компонента.

Обратите внимание, что модуль, упомянутый в шагах 1 и 2, уже существует. Однако вы можете включить дополнительные JARS (например, httpclient-cache-x.y.z.jar) или другие версии.

Разрешение классов в вашей среде разработки — это, конечно, другое дело.

person Eustachius Hamamelis    schedule 29.05.2012

У меня была такая же проблема в подобных обстоятельствах. Требуемый модуль HttpComponents уже находился в моем каталоге модулей JBoss (AS 7.1.1). Поэтому все, что мне нужно было сделать, чтобы решить эту проблему, это добавить запись манифеста, как описано Eustachius, что в Maven вы можете сделать так:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifestEntries>
                        <Dependencies>org.apache.httpcomponents</Dependencies>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

Конфигурация аналогична для maven-war-plugin.

person Katie J. Ots    schedule 02.08.2012

Если модуль необходим в тесте Arquillian...

Создайте arquillian-manifest.mf в src/test/resources со следующим:

Manifest-Version: 1.0
Dependencies: org.jboss.resteasy.resteasy-jaxrs,org.apache.httpcomponents

Затем, когда вы ShrinkWrap:

WebArchive war = ShrinkWrap.create...
    .addAsManifestResource("arquillian-manifest.mf", "MANIFEST.MF")
person Boris Pavlović    schedule 01.10.2012

Но добавьте зависимости: org.apache.httpcomponents в MANIFEST.MF вашего компонента.

вызывает исключение - вызвано: java.lang.IllegalStateException: JBAS014744: не найдено META-INF/services/org.jboss.as.controller.Extension для org.apache.httpcomponents:main в org.jboss.as.controller.parsing .ExtensionXml.loadModule(ExtensionXml.java:191) [jboss-as-controller-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]

person kanaparthikiran    schedule 31.10.2014