jaxb
  1. jaxb
  2. JAXB-899

java.lang.NoSuchFieldError: theInstance

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.2.6
    • Component/s: None
    • Labels:
      None

      Description

      In order to solve the memory leak problem described and solved in http://java.net/jira/browse/JAXB-844
      I tried to upgrade my application from using JAXB 2.1.4 to using JAXB 2.2.5.
      However, now I encounter the following problem in one of my programs
      that uses code generated by JAXB 1.0.4:

      Caused by: javax.xml.bind.JAXBException
       - with linked exception:
      [java.lang.NoSuchFieldError: theInstance]
          at com.sun.xml.bind.ContextFactory_1_0_1.createContext(ContextFactory_1_0_1.java:100)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
          at java.lang.reflect.Method.invoke(Unknown Source)
          at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
          at javax.xml.bind.ContextFinder.find(Unknown Source)
          at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
          at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
          at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
          at mypackage.JAXBContextWrapper.getInstance(JAXBContextWrapper.java:57)
          at mypackage.JAXBObjectWrapper.getUnmarshallerStatic(JAXBObjectWrapper.java:161)
          at mypackage.JAXBObjectWrapper.unmarshalStatic(JAXBObjectWrapper.java:184)
          at mypackage.JAXBObjectWrapper.<init>(JAXBObjectWrapper.java:67)
          ... 11 more
      Caused by: java.lang.NoSuchFieldError: theInstance
          at mypackage.generated.jaxb104.impl.runtime.DefaultJAXBContextImpl.<init>(DefaultJAXBContextImpl.java:50)
          at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
          at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
          at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
          at java.lang.reflect.Constructor.newInstance(Unknown Source)
          at com.sun.xml.bind.ContextFactory_1_0_1.createContext(ContextFactory_1_0_1.java:94)
          ... 24 more
      

      Part of the source code created by JAXB 1.0.4 looks as follows:

      mypackage.generated.jaxb104.impl.runtime.DefaultJAXBContextImpl
      
          public DefaultJAXBContextImpl( String contextPath, ClassLoader classLoader )
              throws JAXBException {
      
              this( GrammarInfoFacade.createGrammarInfoFacade( contextPath, classLoader ) );
      
              // initialize datatype converter with ours
              DatatypeConverter.setDatatypeConverter(DatatypeConverterImpl.theInstance);
          }
      

      Part of the source of class com.sun.xml.bind.DatatypeConverterImpl in JAXB 2.1.4 looks as follows:

      * This class is responsible for whitespace normalization.
       *
       * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul>
       * @version $Revision: 1.9.6.5 $
       * @since JAXB1.0
       */
      public final class DatatypeConverterImpl implements DatatypeConverterInterface {
      
          /**
           * To avoid re-creating instances, we cache one instance.
           */
          public static final DatatypeConverterInterface theInstance = new DatatypeConverterImpl();
      
          protected DatatypeConverterImpl() {
          }
      

      However, part of the source of the same class in JAXB 2.2.5 looks as follows:

       * This class is responsible for whitespace normalization.
       *
       * @author <ul><li>Ryan Shoemaker, Martin Grebac</li></ul>
       * @since JAXB1.0
       * @deprecated in JAXB 2.2.4 - use javax.xml.bind.DatatypeConverterImpl instead
       * or let us know why you can't
       */
      public final class DatatypeConverterImpl {
      
          protected DatatypeConverterImpl() {
              // shall not be used
          }
      

      Obviously, the field theInstance is now missing. This breaks the JAXB 1.0.4 generated code.

      1. compile_errors.jpg
        65 kB

        Activity

        Hide
        Martin Grebac added a comment -

        Hi, jaxb1 is long time deprecated. Would you be able to migrate to jaxb2, migrate to using javax.xml.bind.DatatypeConverterImpl, or at least submit a reproducible testcase here?

        Show
        Martin Grebac added a comment - Hi, jaxb1 is long time deprecated. Would you be able to migrate to jaxb2, migrate to using javax.xml.bind.DatatypeConverterImpl, or at least submit a reproducible testcase here?
        Hide
        hartmannt added a comment -

        jaxb1 is long time deprecated.

        This is new to me. According to the current "JAXB Users Guide" on http://jaxb.java.net/guide/
        chapter "7.3. Running JAXB 1.0 and 2.x side by side" still says

        "You can always run an application X that uses JAXB 1.0 and another application Y that uses JAXB 2.x side by side, in the same classloader.
        To do this, remove the runtime jars from JAXB 1.0 from X, and instead use jaxb-impl.jar and jaxb1-mpl.jar from JAXB 2.0.x.
        Those two jars are designed to be compatible with earlier 1.0 versions of the runtime."

        This is exactly the way I use JAXB in my application.

        Would you be able to migrate to jaxb2 ?

        In principle yes and I plan to do that in the future. However, this will be a very time consuming process as there are many projects that use JAXB1.

        Would you be able to migrate to using javax.xml.bind.DatatypeConverterImpl ?

        How do I do that ?

        Would you be able to at least submit a reproducible testcase here?

        Yes. I prepared an eclipse project which demonstrates the problem.
        The configuration I used is JDK1.6.0_31 and Eclipse 3.7.2 on Windows7.
        The jars in folder lib104 are used in ant-script build.xml to generate the Java clsses from the schema Properties.xsd.
        The jars in folder lib214 are used to compile the generated java sources from the previous step.
        If these jars are also used during runtime, either using "TestJAXB899 214.launch" from within Eclipse
        or runwith214.bat from the windows command line, the output is like in output214.log,
        i.e. no exception occurs.

        However, if the jars in folder 225 are used during runtime, either using "TestJAXB899 225.launch" from within Eclipse
        or runwith225.bat from the windows command line, the output is like in output225.log,
        i.e. the exception "java.lang.NoSuchFieldError: theInstance" occurs.

        Show
        hartmannt added a comment - jaxb1 is long time deprecated. This is new to me. According to the current "JAXB Users Guide" on http://jaxb.java.net/guide/ chapter "7.3. Running JAXB 1.0 and 2.x side by side" still says "You can always run an application X that uses JAXB 1.0 and another application Y that uses JAXB 2.x side by side, in the same classloader. To do this, remove the runtime jars from JAXB 1.0 from X, and instead use jaxb-impl.jar and jaxb1-mpl.jar from JAXB 2.0.x. Those two jars are designed to be compatible with earlier 1.0 versions of the runtime." This is exactly the way I use JAXB in my application. Would you be able to migrate to jaxb2 ? In principle yes and I plan to do that in the future. However, this will be a very time consuming process as there are many projects that use JAXB1. Would you be able to migrate to using javax.xml.bind.DatatypeConverterImpl ? How do I do that ? Would you be able to at least submit a reproducible testcase here? Yes. I prepared an eclipse project which demonstrates the problem. The configuration I used is JDK1.6.0_31 and Eclipse 3.7.2 on Windows7. The jars in folder lib104 are used in ant-script build.xml to generate the Java clsses from the schema Properties.xsd. The jars in folder lib214 are used to compile the generated java sources from the previous step. If these jars are also used during runtime, either using "TestJAXB899 214.launch" from within Eclipse or runwith214.bat from the windows command line, the output is like in output214.log, i.e. no exception occurs. However, if the jars in folder 225 are used during runtime, either using "TestJAXB899 225.launch" from within Eclipse or runwith225.bat from the windows command line, the output is like in output225.log, i.e. the exception "java.lang.NoSuchFieldError: theInstance" occurs.
        Hide
        hartmannt added a comment -

        complete eclipse project

        Show
        hartmannt added a comment - complete eclipse project
        Hide
        hartmannt added a comment -

        If I use the jars from folder lib225 to compile the generated java sources I even get compile errors because of the missing field theInstance. See screenshot for details.

        Show
        hartmannt added a comment - If I use the jars from folder lib225 to compile the generated java sources I even get compile errors because of the missing field theInstance. See screenshot for details.
        Hide
        Martin Grebac added a comment -

        Thanks for the testcase - good catch with the docs, we didn't update those.

        To use the default javax.xml.bind.DatatypeConverterImpl just comment out the DatatypeConverter.setDatatypeConverter calls in your code.

        I'll see if we can make this compatible without need to have 2 DTCs.

        Show
        Martin Grebac added a comment - Thanks for the testcase - good catch with the docs, we didn't update those. To use the default javax.xml.bind.DatatypeConverterImpl just comment out the DatatypeConverter.setDatatypeConverter calls in your code. I'll see if we can make this compatible without need to have 2 DTCs.
        Hide
        Martin Grebac added a comment -

        The api does not allow easy reuse, so I gave back the methods/instance field with deprecation notion. And potentially best fix would be to reuse the javax DTC from RI DTC in the future, however that requires little javax update since currently it's not possible to be reused in RI.
        Will update docs on jaxb1 and also note we will stop bundling jaxb1-impl.jar with jaxb standalone releases (will provide a maven link to the legacy jar in the doc).

        Show
        Martin Grebac added a comment - The api does not allow easy reuse, so I gave back the methods/instance field with deprecation notion. And potentially best fix would be to reuse the javax DTC from RI DTC in the future, however that requires little javax update since currently it's not possible to be reused in RI. Will update docs on jaxb1 and also note we will stop bundling jaxb1-impl.jar with jaxb standalone releases (will provide a maven link to the legacy jar in the doc).

          People

          • Assignee:
            Martin Grebac
            Reporter:
            hartmannt
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: