You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Charles Allen <ch...@metamarkets.com> on 2016/03/02 23:22:43 UTC

classloader issues in httpclient from jets3t in different classloader

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?

Re: classloader issues in httpclient from jets3t in different classloader

Posted by Alexey Panchenko <al...@gmail.com>.
That was fast. I am just curious why making changes here :-) if
- those classes were deprecated long ago? (the "java-deprecated" folder
kind of reminds of that)
- the code on jets3t master looks better and use newer httpclient APIs (its
probably not released yet)

On Thu, Mar 3, 2016 at 12:31 PM, Gary Gregory <ga...@gmail.com>
wrote:

> Closing the loop: This should be fixed in trunk now. See
> https://issues.apache.org/jira/browse/HTTPCLIENT-1727
>
> Gary
>
> On Wed, Mar 2, 2016 at 2:22 PM, Charles Allen <
> charles.allen@metamarkets.com
> > wrote:
>
> > 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?
> >
>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>

Re: classloader issues in httpclient from jets3t in different classloader

Posted by Gary Gregory <ga...@gmail.com>.
Closing the loop: This should be fixed in trunk now. See
https://issues.apache.org/jira/browse/HTTPCLIENT-1727

Gary

On Wed, Mar 2, 2016 at 2:22 PM, Charles Allen <charles.allen@metamarkets.com
> wrote:

> 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?
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory