4 Replies Latest reply: Mar 22, 2012 2:37 AM by 870199 RSS

    LinkageError: have different Class objects for the type javax/xml/namespace

    870199
      In order to be able to connect to a Webservice, we have a standalone client written as follows, which works fine.

      URL wsdlLocation = new URL(wsdlURL);
      javax.xml.namespace.QName serviceName = new QName("http://nbi2.service.xyz.123.com/", "NBIService");
      javax.xml.ws.Service s = Service.create(wsdlLocation, serviceName);
      nbiService = s.getPort(NBIService.class);

      But when i run it from one other environment [Java 6] I get following error in line: javax.xml.ws.Service s = Service.create(wsdlLocation, serviceName);

      java.lang.LinkageError: loader constraint violation:
      when resolving method "javax.xml.ws.Service.create(Ljava/net/URL;Ljavax/xml/namespace/QName;)Ljavax/xml/ws/Service;"
      the class loader (instance of xyz/instrumentation/datasourcemgr/NonDelegatingJarClassLoader) of the current class, xyz/abc/nbiclientutils/NBI2ServiceWSClientProxy,
      and the class loader (instance of <bootloader>) for resolved class, javax/xml/ws/Service,
      have different Class objects for the type javax/xml/namespace/QName used in the signature

      I found that Java 6's rt.jar also two version's of class QName:
      One with package: com\sun\org\apache\xalan\internal\xsltc\compiler
      Another with: javax\xml\namespace

      I hope that's not an issue here, I checked the code javax.xml.ws.Service in link: http://www.docjar.com/html/api/javax/xml/ws/Service.java.html
      That class also imports the same "javax/xml/namespace/QName"

      So may be two different versions of QName has been created in VM

      Please advise, how to get over this issue??

      Edited by: 867196 on Mar 21, 2012 9:08 AM
        • 1. Re: LinkageError: have different Class objects for the type javax/xml/namespace
          gimbal2
          867196 wrote:
          I found that Java 6's rt.jar also two version's of class QName:
          One with package: com\sun\org\apache\xalan\internal\xsltc\compiler
          Another with: javax\xml\namespace
          No, those are two different classes which just happen to have the same classname. But because they have different packages, no worries - they are completely different classes to the JVM. The code is expecting the javax.xml.namespace one, so the xalan class can never be an issue.

          The error you get seems to indicate that two copies of exactly the same class have been loaded, by two different classloaders. That is a conflicting problem as even though they are the same class, when loaded by different classloaders they are still treated as different classes by Java. When a class loaded by classloader A gets an instance of the object created from the conflicting class as loaded by Classloader B, you are in classpath hell.

          Long story short is that apparently you have the same QName class on the classpath twice; one coming from the JDK and one coming from somewhere else. Are you deploying any XML based libraries with your application, such as JAXB or JAX-WS? Are there perhaps any libraries in the lib/ext folder that shouldn't be there?
          • 2. Re: LinkageError: have different Class objects for the type javax/xml/namespace
            870199
            ThankU very much for reply

            Answer your question is: Yes
            There are two Jars that have same Class and Same package

            One is: weblogic-9.23.jar
            Another is: JDK 6 rt.jar

            But i need to have both!

            Also, i quickly modified my weblogic-9.23.jar and removed QName class from it, then started getting below error:
            java.lang.NoClassDefFoundError: Could not initialize class com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory

            at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:786)
                 at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:236)
                 at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:107)
                 at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:226)
                 at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:189)
                 at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:159)
                 at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:83)


            Even if the "class com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory" exist in rt.jar :-(
            Also, there is one custom class loader in place, pasting the code below, could this cause any issue???

            Please advise..

            /**
            * Classloaders normally use a delegation model where loading a class
            * involves checking the boostrap classloader, then the system loader
            * then the parent classloader.
            *
            * In order to force the use of the motive classloader, a nondelegating
            * model is used. This means the current classloader is checked before
            * tossing the request up to the parent, system, bootstrap classloaders.
            *
            *
            *
            */

            public class ABC extends URLClassLoader {



            ABC(URL[] urls, ClassLoader parentClassloader) throws IOException{
            super(urls,parentClassloader);
            }


            /*
            * Override loadclass to check current classloader before systemclassloader
            *
            * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
            */
            protected synchronized Class loadClass(String name, boolean resolve)
            throws ClassNotFoundException {
            //Do we already have this class in our cache?
            Class c = findLoadedClass(name);
            if (c == null) {
            try {
            //Lets try to load this ourselves
            c = findClass(name);

            } catch (ClassNotFoundException cnfe) {
            //The current classloader can't handle this class,
            //pass the request up to the parent classloader
            return super.loadClass(name, resolve);
            }
            }
            if (resolve) {
            resolveClass(c);
            }
            return c;
            }

            Edited by: 867196 on Mar 21, 2012 11:07 AM

            Edited by: 867196 on Mar 21, 2012 11:14 AM
            • 3. Re: LinkageError: have different Class objects for the type javax/xml/namespace
              jtahlborn
              Yes, that classloader could be the issue. in general, not delegating classloading to the parent loader first is a bad idea.
              • 4. Re: LinkageError: have different Class objects for the type javax/xml/namespace
                870199
                Is there a way that before the class loader (instance of xyz/instrumentation/datasourcemgr/ABC) of the my class, xyz/abc/nbiclientutils/NBI2ServiceWSClientProxy
                Loads javax.xml.namespace.QName i do a check that if there is any instance of "javax.xml.namespace.QName" class loaded by other classloader (<bootloader>), If yes, then delete that and proceed ..?? Pls suggest

                Edited by: 867196 on Mar 22, 2012 12:36 AM

                Edited by: 867196 on Mar 22, 2012 12:37 AM