You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Freeman Yue Fang (Jira)" <ji...@apache.org> on 2021/09/30 16:30:00 UTC

[jira] [Commented] (CXF-8603) ClassLoaderUtils.setThreadContextClassloader attempts to set null class loader

    [ https://issues.apache.org/jira/browse/CXF-8603?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17422896#comment-17422896 ] 

Freeman Yue Fang commented on CXF-8603:
---------------------------------------

Hi [~punched_card],

Thanks for raising this up!

If we take a close look at the Thread.setContextClassLoader method
{code}
/**
     * Sets the context ClassLoader for this Thread. The context
     * ClassLoader can be set when a thread is created, and allows
     * the creator of the thread to provide the appropriate class loader,
     * through {@code getContextClassLoader}, to code running in the thread
     * when loading classes and resources.
     *
     * <p>If a security manager is present, its {@link
     * SecurityManager#checkPermission(java.security.Permission) checkPermission}
     * method is invoked with a {@link RuntimePermission RuntimePermission}{@code
     * ("setContextClassLoader")} permission to see if setting the context
     * ClassLoader is permitted.
     *
     * @param  cl
     *         the context ClassLoader for this Thread, or null  indicating the
     *         system class loader (or, failing that, the bootstrap class loader)
     *
     * @throws  SecurityException
     *          if the current thread cannot set the context ClassLoader
     *
     * @since 1.2
     */
    public void setContextClassLoader(ClassLoader cl) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
        }
        contextClassLoader = cl;
    }
{code}

So when the cl == null(normally means it's the  the bootstrap class loader), the Thread subclass can fail it.

So I think we can add a NPE guard in cxf ClassLoaderUtils, so that can honour different Thread subclass implementations.

Are you interested in sending a PR?

Best Regards
Freeman


> ClassLoaderUtils.setThreadContextClassloader attempts to set null class loader
> ------------------------------------------------------------------------------
>
>                 Key: CXF-8603
>                 URL: https://issues.apache.org/jira/browse/CXF-8603
>             Project: CXF
>          Issue Type: Bug
>    Affects Versions: 3.3.11
>            Reporter: Archie Patrick
>            Priority: Major
>
> Created a custom connector for a SOAP Service using CXF for Oracle Identity Manager using their Identity Connector Framework (ICF).  Their framework has a Context Class Loader "watcher" that detects  that the ClassLoaderUtils.setThreadContextClassLoader() method is attempting to set a "null" loader.  This happens when a call is made to invoke a SOAP message:
>     public void testService() {
>         try {
>             IPersonnelManagement2014 port = getPersonnelManagementPort2014();
>             PersonnelManagementViewUser2Response response = port.viewUser("xxxxx", "external", null, null, null, null);
>  
> See stacktrace below:
> SEVERE: Attempting to set the CCL of thread 'pool-1-thread-9' to nullSEVERE: Attempting to set the CCL of thread 'pool-1-thread-9' to nulljava.lang.Throwable at org.identityconnectors.framework.server.impl.CCLWatchThread.setContextClassLoader(CCLWatchThread.java:59) at org.apache.cxf.common.classloader.ClassLoaderUtils.setThreadContextClassloader(ClassLoaderUtils.java:70) at org.apache.cxf.helpers.XPathUtils.getValue(XPathUtils.java:73) at org.apache.cxf.interceptor.ClientFaultConverter.setStackTrace(ClientFaultConverter.java:245) at org.apache.cxf.interceptor.ClientFaultConverter.handleMessage(ClientFaultConverter.java:84) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112) at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:137) at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.handleMessage(SOAPHandlerInterceptor.java:70) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:829) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1696) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1570) at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1371) at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:671) at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:441) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:356) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140) at com.sun.proxy.$Proxy40.viewUser(Unknown Source) at com.icsynergy.epic.wsclient.WSClient.testService(WSClient.java:550)
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)