I'm using the RestEasy Client Framework in a @Named @ViewScoped
Bean with JBoss-7.1.1-Final to retrieve data from a REST service with a custom 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);
This works fine in a standalone client application (also ok when I remove the ClientExecutor
, but I need it to authenticate REST service). The bean is in a WAR
module inside an EAR
, the dependency hierarchy of resteasy resolves to the following:
There are no httpclient
or httpcore
in the WAR
or EAR
. Inside the Bean I get the following exception:
java.lang.NoClassDefFoundError: org/apache/http/HttpRequestInterceptor
Seems to be easy (although I'm wondering about the resteasy packaging) and I added org.apache.httpcomponents:httpclient
with compile scope:
No I'm getting he following exception:
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)
Update To reproduce this you don't need REST interfaces, the error occurs while instantiating the ApacheHttpClient4Executor
, but you may need the custom 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());
}
}
To avoid the linkage error when deploying the application on JBoss, configure module org.apache.httpcomponents
within the modules folder of the JBoss installation, but avoid including the JARs from HttpComponents with your application:
modules/org/apache/httpcomponents/main
.module.xml
within this directory.Dependencies: org.apache.httpcomponents
to the MANIFEST.MF
of your component.Note that the module referred to in step 1 and 2 already exists. You may however want to include additional JARS (e.g. httpclient-cache-x.y.z.jar
) or different versions.
Resolving classes within your development environment is another matter of course.