2 Replies Latest reply on Jul 21, 2010 10:53 AM by jbatista

    JBoss5 class loader and Axis2

    jbatista

      Dear all,

       

      I'm having some troubles that seem to trace back to class loading.

      I've created a bottom-up webservice example in Eclipse Galileo to illustrate. I am using:

      • Sun Java 1.6.0-13, 32-bit.
      • JBoss 5.0.1.GA. (I've tried both in MS Windows XP and in Linux, makes no  difference.)
      • Apache Axis2 1.4.

       

      Code, server-side

      /**

      * 1. Server-side class.

      * This is in a Dynamic Web Project (here called "MobilePhoneInfo") and is deployed as a Web Service, all done in Eclipse.

      */

      package mobile.test;

      import java.io.IOException;
      import java.io.InputStream;
      import java.net.MalformedURLException;
      import java.net.URL;

      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;
      import javax.xml.parsers.ParserConfigurationException;
      import javax.xml.xpath.XPath;
      import javax.xml.xpath.XPathConstants;
      import javax.xml.xpath.XPathExpressionException;
      import javax.xml.xpath.XPathFactory;

      import org.w3c.dom.Document;
      import org.xml.sax.InputSource;
      import org.xml.sax.SAXException;
      public class MobilePhoneInfo {
          public String getMobilePhoneInfo(String url, String path) {
              String result=null;
              try {
                  if(url==null  || url.length()==0)    throw new Exception("null/empty URL");
                  if(path==null || path.length()==0)    throw new Exception("null/empty XPath");
                  InputStream input = new URL(url).openStream();
                  if(input!=null) {
                      InputSource source = new InputSource(input);
                      DocumentBuilderFactory docFact = DocumentBuilderFactory.newInstance();
                      docFact.setNamespaceAware(false);
                      DocumentBuilder parser = docFact.newDocumentBuilder();
                      Document doc = parser.parse(source);
                      XPath xpath = XPathFactory.newInstance().newXPath();

                      // server-side call fails here
                      result = (String) xpath.evaluate(path,doc,XPathConstants.STRING);
                      input.close();
                  } else throw new Exception("null InputStream from given URL "+url);
              }
              catch (XPathExpressionException e) { e.printStackTrace(); }
              catch (SAXException e) { e.printStackTrace(); }
              catch (ParserConfigurationException e) { e.printStackTrace(); }
              catch (MalformedURLException e) { e.printStackTrace(); }
              catch (IOException e) { e.printStackTrace(); }
              catch (Exception e) { e.printStackTrace(); }
             
              return result;
          }
          //
          public static void main(String[] args) {
              MobilePhoneInfo info = new MobilePhoneInfo();
              String url = "http://wap.samsungmobile.com/uaprof/GT-B7300.xml";
              String xpath1 = "/RDF/Description/component/Description[@ID='HardwarePlatform']/Vendor";
              String xpath2 = "/RDF/Description/component/Description[@ID='HardwarePlatform']/Model";
              String vendor; String model;
              vendor = info.getMobilePhoneInfo(url,xpath1);
              model = info.getMobilePhoneInfo(url,xpath2);
              System.out.println("Result:\t"+vendor+" "+model);
          }
      }

       

      Code, client-side

      /**

      * 2. Client-side class.

      * Stub class is built from the WSDL specification of the deployed web service.

      */

      package mobile.test;

      import java.rmi.RemoteException;

      import org.apache.axis2.AxisFault;
      import org.apache.axis2.context.ConfigurationContext;

      import mobile.test.MobilePhoneInfoStub.GetMobilePhoneInfo;
      import mobile.test.MobilePhoneInfoStub.GetMobilePhoneInfoResponse;

      public class MobilePhoneInfoClient {
          private static final String strEndpoint = "http://localhost:8080/MobilePhoneInfo/services/MobilePhoneInfo.MobilePhoneInfoHttpSoap12Endpoint";

          public static void main(String[] args) {
              try {
                  MobilePhoneInfoStub stub = new MobilePhoneInfoStub(strEndpoint);
                  GetMobilePhoneInfo input = new GetMobilePhoneInfo();
                  String url = "http://wap.samsungmobile.com/uaprof/GT-B7300.xml";
                  String path_vendor = "/RDF/Description/component/Description[@ID='HardwarePlatform']/Vendor";
                  String path_model = "/RDF/Description/component/Description[@ID='HardwarePlatform']/Model";
                  input.setUrl(url);
                  GetMobilePhoneInfoResponse output;
                  input.setPath(path_vendor);

                  // call fails here
                  output = (GetMobilePhoneInfoResponse) stub.getMobilePhoneInfo(input);
                  String vendor = output.get_return();
                  input.setPath(path_model);
                  output = (GetMobilePhoneInfoResponse) stub.getMobilePhoneInfo(input);
                  String model = output.get_return();
                  System.out.println(vendor+" "+model);
              }
              catch (AxisFault e) { e.printStackTrace(); }
              catch (RemoteException e) { e.printStackTrace(); }
          }

      }

       

      Logged error, server side

       

      INFO  [STDOUT] [ERROR] loader constraint violation: when resolving field "STRING" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/xpath/XPathConstants, and the class loader (instance of <bootloader>) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
      java.lang.reflect.InvocationTargetException
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:597)
          at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:194)
          at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:102)
          at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
          at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:100)
          at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:176)
          at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:275)
          at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:131)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
          at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
          at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
          at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
          at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
          at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
          at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
          at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
          at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
          at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
          at java.lang.Thread.run(Thread.java:619)
      Caused by: java.lang.LinkageError: loader constraint violation: when resolving field "STRING" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/xpath/XPathConstants, and the class loader (instance of <bootloader>) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
          at mobile.test.MobilePhoneInfo.getMobilePhoneInfo(MobilePhoneInfo.java:39)
          ... 33 more
      15:57:18,615 INFO  [STDOUT] [ERROR] loader constraint violation: when resolving field "STRING" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/xpath/XPathConstants, and the class loader (instance of <bootloader>) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
      org.apache.axis2.AxisFault: loader constraint violation: when resolving field "STRING" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/xpath/XPathConstants, and the class loader (instance of <bootloader>) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
          at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:158)
          at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
          at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:100)
          at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:176)
          at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:275)
          at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:131)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
          at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
          at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
          at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
          at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
          at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
          at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
          at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
          at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
          at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
          at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
          at java.lang.Thread.run(Thread.java:619)
      Caused by: java.lang.reflect.InvocationTargetException
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          at java.lang.reflect.Method.invoke(Method.java:597)
          at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:194)
          at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:102)
          ... 27 more
      Caused by: java.lang.LinkageError: loader constraint violation: when resolving field "STRING" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the referring class, javax/xml/xpath/XPathConstants, and the class loader (instance of <bootloader>) for the field's resolved type, javax/xml/namespace/QName, have different Class objects for that type
          at mobile.test.MobilePhoneInfo.getMobilePhoneInfo(MobilePhoneInfo.java:39)
          ... 33 more

       

       

      Further details

       

      The javax.xml.namespace.QName class used by the static XPathConstants.STRING object seems to be in many different .jar files.

      For example, the relevant ones seem to be the Java JDK's rt.jar and, specific of Axis2, in axis2-saaj-api-1.4.jar. So at some point one version of QName is used somewhere and this collides with the attempted loading of QName from Axis2.

       

      I've found some posts elswhere explaining that the creation/inclusion of a jboss-web.xml file in the project's WEB-INF directory should allow the control of exactly how the class loader (only one?!) will pick the classes, but I'm not exactly sure if this is the correct way (I haven't met much success) and whether this is a dead-end. I've tried something like this:

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 5.0//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_5_0.dtd">
      <jboss-web>
          <class-loading java2ClassLoadingCompliance="false">
              <loader-repository>mobile.test:loader=MobilePhoneInfoEAR.ear</loader-repository>
          </class-loading>
      </jboss-web>

      I'm not even too sure if, given the projects' layouts, the XML contains the correct information.

       

      I would very much like to thank in advance for people able to share some insight on this matter.

       

      Regards,

      jbatista

        • 1. Re: JBoss5 class loader and Axis2
          jaikiran

          Are you packaging any jar file(s) containing javax.xml.*  in your application? If yes, remove them from the application packaging.

          1 of 1 people found this helpful
          • 2. Re: JBoss5 class loader and Axis2
            jbatista

            Hi jaikiran pai,

            Are you packaging any jar file(s) containing javax.xml.*  in your application? If yes, remove them from the application packaging.

            As it happens, the deployed Axis2 *.jar files did have a few java.xml.namespace.* classes, which I removed by hand. I tried with Axis2 1.4.1 and redeployed the *.war, and the error no longer appears. So I have to say that this Works For Me.

             

            BTW, do you know if JBoss's class loader can be configured to "ignore" certain packages that are deployed, or to choose which packages should be loaded from the JDK instead of the deployed resources?