1. jaxp
  2. JAXP-17

Improve the error diagnostics with classloader related problems


    • Issuezilla Id:


      See the cited URL for the actual users that hit the problem. The error happens
      in the following cast:

      public static XMLOutputFactory newInstance()
      throws FactoryConfigurationError

      { return (XMLOutputFactory) FactoryFinder.find("javax.xml.stream.XMLOutputFactory", "com.bea.xml.stream.XMLOutputFactoryBase"); }

      ... because there are apparently two copies of JSR-173 APIs, so the
      XMLOutputFactory that Zephyr implements and the XMLOutputFactory used here are
      two different classes, hence the cast fails.

      This kind of problems are fairly common in multi-classloader environment, and
      most of the users would get really confused with this.

      In JAXB API, we have precautions for this kind of failures and provide error
      diagnostics. The code is cited below so that you can adapt a similar technique
      in the JAXP API.

      // this creates JAXBContext, but don't cast it just yet.
      Object context = m.invoke(null, classes, properties);
      if(!(context instanceof JAXBContext))

      { // the cast would fail, so generate an exception with a nice message handleClassCastException(context.getClass(), JAXBContext.class); }

      return (JAXBContext)context;

      private static void handleClassCastException(Class originalType, Class
      targetType) throws JAXBException

      { final URL targetTypeURL = which(targetType); throw new JAXBException(Messages.format(Messages.ILLEGAL_CAST, // we don't care where the impl class is, we want to know where JAXBContext lives in the impl // class' ClassLoader originalType.getClass().getClassLoader().getResource("javax/xml/bind/JAXBContext.class").toString(), targetTypeURL.toString())); }

      static URL which(Class clazz)

      { return which(clazz, clazz.getClassLoader()); }

      static URL which(Class clazz, ClassLoader loader) {

      String classnameAsResource = clazz.getName().replace('.', '/') + ".class";

      if(loader == null)

      { loader = ClassLoader.getSystemClassLoader(); }

      return loader.getResource(classnameAsResource);


        kohsuke created issue -
        kenaiadmin made changes -
        Field Original Value New Value
        issue.field.bugzillaimportkey 17 46701


          • Assignee:
          • Votes:
            0 Vote for this issue
            0 Start watching this issue


            • Created: