[JAXB-899] java.lang.NoSuchFieldError: theInstance Created: 05/May/12  Updated: 11/May/12  Resolved: 11/May/12

Status: Resolved
Project: jaxb
Component/s: None
Affects Version/s: None
Fix Version/s: 2.2.6

Type: Bug Priority: Major
Reporter: hartmannt Assignee: Martin Grebac
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: JPEG File compile_errors.jpg     Zip Archive JAXB899.zip    

 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.



 Comments   
Comment by Martin Grebac [ 09/May/12 ]

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?

Comment by hartmannt [ 10/May/12 ]

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.

Comment by hartmannt [ 10/May/12 ]

complete eclipse project

Comment by hartmannt [ 11/May/12 ]

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.

Comment by Martin Grebac [ 11/May/12 ]

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.

Comment by Martin Grebac [ 11/May/12 ]

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).

Generated at Mon Jul 06 05:35:35 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.