You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by bu...@apache.org on 2005/10/04 17:47:48 UTC

DO NOT REPLY [Bug 36913] New: - ClassLoader Problem with AXIS in Servlet Container WebSphere

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=36913>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=36913

           Summary: ClassLoader Problem with AXIS in Servlet Container
                    WebSphere
           Product: Commons
           Version: unspecified
          Platform: PC
        OS/Version: Windows XP
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Discovery
        AssignedTo: commons-dev@jakarta.apache.org
        ReportedBy: Torge.Harbig@reddot.de


please excuse bad englisch

Szenario: (ClassLoader)
  WebSphere
    OurServlet
      AXIS

We redirect AXIS Logging (org.apache.commons.logging.LogFactory) to our own
logFactory so that we can output messages of AXIS in our own logFiles. 

And we need to prepare service calls for AXIS so all access to AXIS is
indirected over our own Servlet (OurServlet) which loads AXIS using
Class.forName().newInstance()

In WebSphere we get an Exception that AXIS can not load our Logger (AXIS uses
Commons Discovery)

The Problem:
a) WebSphere itself uses Commons Discovery and loads Commons Discovery in the
?WebContainer?-ClassLoader. OurServlet and AXIS are loaded in a
?Servlet?-ClassLoader ...
b) Initializing AXIS / AXIS calls DiscoverSingleton.find() which searches for
the configured logger / but can not find it in the ?WebContainer?-ClassLoader.

It follows a short java file for testing/demonstrating the problem. Additionally
needed for Test is a Logger Implementation in a single jar File myLogger.jar
(look at the following source)

In the code the exception from commons Discovery is given and a solution we use
to solve this problem (but perhaps it is not the recommended way) / 

Can someone who understands the problem tell me how it should bo solved?
Thanks.

import java.net.URL;
import java.net.URLClassLoader;

import org.apache.commons.discovery.resource.ClassLoaders;
import org.apache.commons.discovery.tools.DefaultClassHolder;
import org.apache.commons.discovery.tools.DiscoverSingleton;
import org.apache.commons.discovery.tools.SPInterface;

public class ClassLoaderTest
{
  public static void main( String args[] )throws Exception
  { ClassLoaderTest clt = new ClassLoaderTest();
    clt.problem2();
  }

  static String libPath = "file:// **path** "; // set correct path here !!
  
  public void problem1()throws Exception
  { URL url1[] = new URL[] 
    { new URL( libPath+"commons-discovery.jar"), 
      new URL( libPath+"commons-logging.jar"), 
      new URL( libPath+"servlet.jar")
    };
    ClassLoader parentClassLoader 
    = new URLClassLoader( url1, getClass().getClassLoader() );
    
    URL url2[] = new URL[]
    { new URL( libPath+"axis.jar"),
      new URL( libPath+"axis-ant.jar"),
      new URL( libPath+"commons-logging.jar"),
      new URL( libPath+"commons-discovery.jar"),
      new URL( libPath+"log4j-1.2.8.jar"),
      new URL( libPath+"wsdl4j.jar"),
      new URL( libPath+"jaxrpc.jar"), 
      new URL( libPath+"xerces.jar"), 
      new URL( libPath+"saaj.jar"),
      new URL( libPath+"mylog.jar")  // jar with my logger class ...
    };
    
    ClassLoader childClassLoader = new URLClassLoader( url2, parentClassLoader );

    System.setProperty
    ( "org.apache.commons.logging.LogFactory"
      , "mylog.MyLogger"
    );
    Class axisServletClass = childClassLoader.loadClass(
"org.apache.axis.transport.http.AxisServlet" );
    Object axisServlet = axisServletClass.newInstance();
    
    /*
     * Problem: discovery can not load class mylog.MyLogger in mylog.jar because
     * it is in another class loader ...
     * 
     * AXIS uses DiscoverSingleton.find Method ...
     */

    /*
    java.lang.ExceptionInInitializerError
    at
org.apache.axis.transport.http.AxisServletBase.<clinit>(AxisServletBase.java:94)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
    at java.lang.Class.newInstance0(Class.java:308)
    at java.lang.Class.newInstance(Class.java:261)
    at ClassLoaderTest.problem(ClassLoaderTest.java:49)
    at ClassLoaderTest.main(ClassLoaderTest.java:13)

    Caused by: org.apache.commons.discovery.DiscoveryException: No
implementation defined for org.apache.commons.logging.LogFactory
    at org.apache.commons.discovery.tools.DiscoverClass.find(DiscoverClass.java:407)
    at
org.apache.commons.discovery.tools.DiscoverClass.newInstance(DiscoverClass.java:582)
    at
org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:418)
    at
org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:378)
    at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:84)
    at java.security.AccessController.doPrivileged(Native Method)
    at
org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:80)
    at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:72)
    ... 9 more
     */
  }
  
  public void problem2()throws Exception
  { URL url1[] = new URL[] 
    { new URL( libPath+"commons-discovery.jar"), 
      new URL( libPath+"commons-logging.jar"), 
      new URL( libPath+"servlet.jar")
    };
    ClassLoader parentClassLoader 
    = new URLClassLoader( url1, getClass().getClassLoader() );
    
    URL url2[] = new URL[]
    { new URL( libPath+"axis.jar"),
      new URL( libPath+"axis-ant.jar"),
      new URL( libPath+"commons-logging.jar"),
      new URL( libPath+"commons-discovery.jar"),
      new URL( libPath+"log4j-1.2.8.jar"),
      new URL( libPath+"wsdl4j.jar"),
      new URL( libPath+"jaxrpc.jar"), 
      new URL( libPath+"xerces.jar"), 
      new URL( libPath+"saaj.jar"),
      new URL( libPath+"mylog.jar")  // jar with my logger class ...
    };
    
    ClassLoader childClassLoader = new URLClassLoader( url2, parentClassLoader );

    System.setProperty
    ( "org.apache.commons.logging.LogFactory"
      , "mylog.MyLogger"
    );
    
    Thread.currentThread().setContextClassLoader( childClassLoader );
    Class axisServletClass = childClassLoader.loadClass(
"org.apache.axis.transport.http.AxisServlet" );
    Object axisServlet = axisServletClass.newInstance();
    
    /*
     * Problem: discovery can not load class mylog.MyLogger in mylog.jar because
     * it is in another class loader ...
     * 
     * AXIS uses DiscoverSingleton.find Method ...
     */

    /*
    java.lang.ExceptionInInitializerError
    at
org.apache.axis.transport.http.AxisServletBase.<clinit>(AxisServletBase.java:94)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
    at java.lang.Class.newInstance0(Class.java:308)
    at java.lang.Class.newInstance(Class.java:261)
    at ClassLoaderTest.problem(ClassLoaderTest.java:49)
    at ClassLoaderTest.main(ClassLoaderTest.java:13)

    Caused by: org.apache.commons.discovery.DiscoveryException: No
implementation defined for org.apache.commons.logging.LogFactory
    at org.apache.commons.discovery.tools.DiscoverClass.find(DiscoverClass.java:407)
    at
org.apache.commons.discovery.tools.DiscoverClass.newInstance(DiscoverClass.java:582)
    at
org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:418)
    at
org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:378)
    at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:84)
    at java.security.AccessController.doPrivileged(Native Method)
    at
org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:80)
    at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:72)
    ... 9 more
     */
  }

  public void solution()throws Exception
  { URL url1[] = new URL[] 
    { new URL( libPath+"commons-discovery.jar"), 
      new URL( libPath+"commons-logging.jar"), 
      new URL( libPath+"servlet.jar")
    };
    ClassLoader parentClassLoader 
    = new URLClassLoader( url1, getClass().getClassLoader() );
    
    URL url2[] = new URL[]
    { new URL( libPath+"axis.jar"),
      new URL( libPath+"axis-ant.jar"),
      new URL( libPath+"commons-logging.jar"),
      new URL( libPath+"commons-discovery.jar"),
      new URL( libPath+"log4j-1.2.8.jar"),
      new URL( libPath+"wsdl4j.jar"),
      new URL( libPath+"jaxrpc.jar"), 
      new URL( libPath+"xerces.jar"), 
      new URL( libPath+"saaj.jar"),
      new URL( libPath+"mylog.jar")  // jar with my logger class ...
    };
    
    ClassLoader childClassLoader = new URLClassLoader( url2, parentClassLoader );


    // Solution - preLoading Singleton ...
    Thread.currentThread().setContextClassLoader( childClassLoader );
    Class myLog = childClassLoader.loadClass( "mylog.MyLogger" );
    DefaultClassHolder defaultClassHolder = new DefaultClassHolder( myLog );
    
    Class loggerInterface = childClassLoader.loadClass(
"org.apache.commons.logging.LogFactory" );
    
    ClassLoaders classLoaders = new ClassLoaders();
    classLoaders.put( childClassLoader );
    Object o = DiscoverSingleton.find
      ( classLoaders, new SPInterface(loggerInterface), null, defaultClassHolder
      );
    
    // AXIS now loads the correct logger singleton ...
    Class axisServletClass = childClassLoader.loadClass(
"org.apache.axis.transport.http.AxisServlet" );
    Object axisServlet = axisServletClass.newInstance();      
  }
}

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org