I'm getting the following stack trace when using jets3t which uses
httpclient:

Caused by: java.lang.IllegalStateException: Invalid class name:
org.jets3t.service.utils.RestUtils$ConnManagerFactory
        at
org.apache.http.impl.client.AbstractHttpClient.createClientConnectionManager(AbstractHttpClient.java:319)
~[druid-selfcontained-2f990f7.jar:2f990f7]
        at
org.apache.http.impl.client.AbstractHttpClient.getConnectionManager(AbstractHttpClient.java:465)
~[druid-selfcontained-2f990f7.jar:2f990f7]
        at
org.apache.http.impl.client.AbstractHttpClient.createHttpContext(AbstractHttpClient.java:285)
~[druid-selfcontained-2f990f7.jar:2f990f7]
        at
org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:799)
~[druid-selfcontained-2f990f7.jar:2f990f7]
        at
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
~[druid-selfcontained-2f990f7.jar:2f990f7]
        at
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
~[druid-selfcontained-2f990f7.jar:2f990f7]
        at
org.jets3t.service.impl.rest.httpclient.RestStorageService.performRequest(RestStorageService.java:328)
~[?:?]
        at
org.jets3t.service.impl.rest.httpclient.RestStorageService.performRequest(RestStorageService.java:279)
~[?:?]
        at
org.jets3t.service.impl.rest.httpclient.RestStorageService.performRestHead(RestStorageService.java:1052)
~[?:?]
        at
org.jets3t.service.impl.rest.httpclient.RestStorageService.getObjectImpl(RestStorageService.java:2264)
~[?:?]
        at
org.jets3t.service.impl.rest.httpclient.RestStorageService.getObjectDetailsImpl(RestStorageService.java:2193)
~[?:?]
        at
org.jets3t.service.S3Service.getObjectDetails(S3Service.java:2574) ~[?:?]
        at
org.jets3t.service.S3Service.getObjectDetails(S3Service.java:1773) ~[?:?]


Looking into it, it seems httpclient doesn't take classloaders into
consideration when looking for connection manager factories:
https://github.com/apache/httpclient/blob/4.5.2/httpclient/src/main/java-deprecated/org/apache/http/impl/client/AbstractHttpClient.java#L332

As such, the only connection manager factories that can be used must be in
the same classloader as AbstractHttpClient. If something like jets3t is
loaded in a child classloader with AbstractHttpClient's classloader as a
parent, then jets3t will not work with the exception shown above.

The correct solution would be to set the thread context classloader before
calling things which end up calling Class.forName, and having the library
(httpclient in this case) be aware of the context classloader.

But currently there is no way for me to force httpclient to be aware of any
classloader other than the one used to load AbstractHttpClient

Is there any workaround? Or am I mis-reading the problem here?

Reply via email to