Search code examples
jaxbeclipselinkjaxb2moxy

errors using xjc:superClass with XmlTransient annotation on super class with EclipseLink Moxy (jaxb 2.1 generated code)



i'm using xjc:superClass and an @javax.xml.bind.annotation.XmlTransient annotation on the super class.

i'm trying to switch over to Moxy and I get this error:

'Exception Description: Property [aspectStyleBlock] in class [com.aplia.q4.document.ValueStyle] references a class [com.aplia.q4.domain.AbstractBlock] that is marked transient, which is not allowed.
 - with linked exception:
[Exception [EclipseLink-50057] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.JAXBException
' . 

This all works fine under jaxb 2.1

If I remove the XmlTransient annotation on the superclass, I instead get this error:

'ava.lang.RuntimeException: javax.xml.bind.JAXBException
 - with linked exception:
[java.lang.NullPointerException]
....

'Caused by: javax.xml.bind.JAXBException
 - with linked exception:
[java.lang.NullPointerException]
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:825)
    at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:136)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:142)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:129)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:93)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:83)
    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 javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:331)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
    at com.aplia.q4.service.hosting.impl.JAXBAdapter.<init>(JAXBAdapter.java:35)
    ... 27 more
Caused by: java.lang.NullPointerException
    at org.eclipse.persistence.jaxb.compiler.MappingsGenerator.generateChoiceCollectionMapping(MappingsGenerator.java:686)
    at org.eclipse.persistence.jaxb.compiler.MappingsGenerator.generateMapping(MappingsGenerator.java:434)
    at org.eclipse.persistence.jaxb.compiler.MappingsGenerator.generateMappings(MappingsGenerator.java:1996)
    at org.eclipse.persistence.jaxb.compiler.MappingsGenerator.generateMappings(MappingsGenerator.java:1957)
    at org.eclipse.persistence.jaxb.compiler.MappingsGenerator.generateProject(MappingsGenerator.java:193)
    at org.eclipse.persistence.jaxb.compiler.Generator.generateProject(Generator.java:174)
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:830)
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:823)
    ... 41 more'

I have about 100 classes generated from schema (I don't control the schema). I tried to use http://jaxb2-commons.dev.java.net/basic/inheritance to implement an interface instead of xjc:superclass, but it will require me to list out all of my 100 classes, since bindings xpath can't match on multiple nodes. Reluctant to do so unless it is the only way to fix the problem.

This is blocking my efforts to convert to Moxy impl.

Details about my setup & why i chose to add the XmlTransient annotation:

from https://sites.google.com/site/codingkb/java-2/jaxb/jaxb-4

" causes @XmlValue is not allowed on a class that derives another class You'd like your autogenerated JAXB classes to extend a common parent class... So you add something like this to your XSD:

Unfortunately, when you go to compile, you get an error message: Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions @XmlValue is not allowed on a class that derives another class.

The solution is to add an annotation to the base class: @javax.xml.bind.annotation.XmlTransient public class JAXBSuperClass { ... }"

My pom file (relevant parts only):

<dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.1.13</version>
        <scope>runtime</scope>
    </dependency>

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.7.4</version>
            <executions>
                <execution>
                    <id>generate-q4-document-jaxb</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <extension>true</extension>
                        <args>
                            <arg>-Xboolean-getter</arg>
                            <arg>-Xinheritance</arg>
                        </args>
                        <plugins>
                            <plugin>
                                    <groupId>org.jvnet.jaxb2_commons</groupId>
                                   <artifactId>jaxb2-basics</artifactId>
                                   <version>0.5.3</version>
                               </plugin>
                            <plugin>
                                <groupId>com.nebulent.xjc</groupId>
                                <artifactId>boolean-getter</artifactId>
                                <version>1.0</version>
                            </plugin>
                        </plugins>
                        <schemaDirectory>${project.build.directory}/generated-sources/schema</schemaDirectory>
                        <bindingDirectory>${basedir}/src/main/resources/jaxb-bindings</bindingDirectory>
                        <forceRegenerate>true</forceRegenerate>
                    </configuration>
                </execution>
            </executions>
        </plugin>

let me know if you need a schema, or any other info.

thanks in advance!


Solution

  • Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

    There are a couple issues related to your question:


    Issue #1 - MOXy exception

    Could you provide a small sample that demonstrates the issue that you are seeing?

    UPDATE 1: I believe the issue that you are seeing is related to the following EclipseLink bug:

    UPDATE 2: We have fixed the bug in both the EclipseLink 2.3.3 (available May 10 download) and 2.4.0 (available May 11 download) streams. You download these from the following location:


    Issue #2 - @XmlValue on a Subclass

    The JAXB RI can not handle this use case:

    Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
    @XmlValue is not allowed on a class that derives another class.
        this problem is related to the following location:
            at public java.lang.String forum10437666.Child.getValue()
            at forum10437666.Child
    
        at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
        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 javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
        at forum10437666.ValueDemo.main(ValueDemo.java:11)
    

    EclipseLink JAXB (MOXy) can as long as the parent class does not map any of its fields/properties to XML elements:

    Parent

    The parent class only contains mappings to XML attributes.

    package forum10437666;
    
    import javax.xml.bind.annotation.XmlAttribute;
    
    public class Parent {
    
        private int id;
    
        @XmlAttribute
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
    }
    

    Child

    Child extends Parent and has a property mapped with @XmlValue.

    package forum10437666;
    
    import javax.xml.bind.annotation.XmlValue;
    
    public class Child extends Parent {
    
        private String value;
    
        @XmlValue
        public String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    
    }
    

    ValueDemo

    package forum10437666;
    
    import javax.xml.bind.*;
    import javax.xml.namespace.QName;
    
    public class ValueDemo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Child.class);
    
            Child child = new Child();
            child.setId(123);
            child.setValue("ABC");
    
            JAXBElement<Child> je = new JAXBElement<Child>(new QName("child"), Child.class, child);
            Marshaller marshaller = jc.createMarshaller();
            marshaller.marshal(je, System.out);
        }
    
    }
    

    Output

    <?xml version="1.0" encoding="UTF-8"?>
    <child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="123">ABC</child>