2013-01-24 4 views
2

J'ai trois objets immuables de tiers (Foo, Bar, BarFactory) et binding.xml. Je voudrais marquer des objets immuables de tierce partie dans binding.xml, mais JAXB requiert un constructeur de zéro argument. Est-il impossible de rassembler ces classes dans JAXB et MOXy?Comment marquer un objet immuable tiers dans JAXB (Eclipse MOXy)

Foo, Bar, BarFactory, codes de démo binding.xml et sont ci-dessous.

package example.bindingfile; 

public class Foo{ 
    public static Foo getInstance(int value1, float value2){ 
     return new Foo(value1, value2); 
    } 
    private final int value1; 
    private final float value2; 
    private Foo(int value1, float value2){ 
     this.value1 = value1; 
     this.value2 = value2; 
    } 
    public int getValue1(){ 
     return value1; 
    } 
    public float getValue2(){ 
     return value2; 
    } 
} 

package example.bindingfile; 
public class Bar{ 
    private final int value; 
    Bar(int value){ 
     this.value = value; 
    } 
    public int getValue(){ 
     return value; 
    } 
} 

package example.bindingfile; 
public class BarFactory{ 
    private BarFactory(){} 
    public static Bar getInstance(int value){ 
     return new Bar(value); 
    } 
} 

binding.xml, la classe ClassExtractor personnalisée et la classe démo sont indiquées ci-dessous.

--- binding.xml

<?xml version="1.0"?> 
    <xml-bindings 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/oxm http://www.eclipse.org/eclipselink/xsds/eclipselink_oxm_2_3.xsd" 
    version="2.3" 
    package-name="example.bindingfile"> 
    <xml-schema 
     namespace="http://www.example.com/bindingfile" 
     element-form-default="QUALIFIED"/> 
    <java-types> 
     <!-- 
     <java-type name="Foo" xml-accessor-type="FIELD"> 
      <xml-root-element/> 
      <xml-type prop-order="value1 value2"/> 
      <java-attributes> 
       <xml-element java-attribute="value1" name="val1"/> 
       <xml-element java-attribute="value2" name="val2"/> 
      </java-attributes> 
     </java-type> 
     --> 
     <java-type name="Bar" xml-accessor-type="PROPERTY"> 
      <xml-root-element/> 
      <!--<xml-java-type-adapter value="example.bindingfile.BarAdapter"/>--> 
      <xml-type prop-order="value"/> 
      <xml-class-extractor class="example.bindingfile.BarExtractor"/> 
      <java-attributes> 
       <xml-element java-attribute="value" name="Value"/> 
      </java-attributes> 
     </java-type> 
    </java-types> 
</xml-bindings> 
package example.bindingfile; 

import org.eclipse.persistence.descriptors.ClassExtractor; 
import org.eclipse.persistence.descriptors.MethodClassExtractor; 
import org.eclipse.persistence.sessions.Record; 
import org.eclipse.persistence.sessions.Session; 

public class BarExtractor extends MethodClassExtractor{ 
    public BarExtractor(){} 
    @Override public Class extractClassFromRow(Record databaseRow, Session session){ 
     return BarFactory.class; 
    } 
    @Override public String getClassExtractionMethodName(){ 
     return "getInstance"; 
    } 
} 
package example.bindingfile; 

import java.io.File; 
import java.util.*; 
import javax.xml.bind.*; 
import org.eclipse.persistence.jaxb.JAXBContextFactory; 

public class Demo{ 
    public static void main(String[] args) throws Exception{ 
     Map<String, Object> properties = new HashMap<String, Object>(1); 
     List<Object> bindingFileList = new ArrayList<Object>(1); 
     bindingFileList.add("example/bindingfile/binding.xml"); 
     properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, bindingFileList); 
     JAXBContext jc = JAXBContext.newInstance(new Class[]{Bar.class}, properties); 
    //JAXBContext jc = JAXBContext.newInstance(Bar.class); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(BarFactory.getInstance(1), System.out); 
    } 
} 

et example.bindingfile.Demo jeter ci-dessous Exception.

Exception in thread "main" javax.xml.bind.JAXBException: 
Exception Description: The class example.bindingfile.Bar requires a zero argument constructor or a specified factory method. Note that non-static inner classes do not have zero argument constructors and are not supported. 
- with linked exception: 
[Exception [EclipseLink-50001] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.JAXBException 
Exception Description: The class example.bindingfile.Bar requires a zero argument constructor or a specified factory method. Note that non-static inner classes do not have zero argument constructors and are not supported.] 
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:926) 
    at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:163) 
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:171) 
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:158) 
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:118) 
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:108) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248) 
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235) 
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:385) 
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637) 
    at example.bindingfile.Demo.main(Demo.java:16) 
Caused by: Exception [EclipseLink-50001] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.JAXBException 
Exception Description: The class example.bindingfile.Bar requires a zero argument constructor or a specified factory method. Note that non-static inner classes do not have zero argument constructors and are not supported. 
    at org.eclipse.persistence.exceptions.JAXBException.factoryMethodOrConstructorRequired(JAXBException.java:142) 
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.finalizeProperties(AnnotationsProcessor.java:826) 
    at org.eclipse.persistence.jaxb.compiler.XMLProcessor.processXML(XMLProcessor.java:412) 
    at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:145) 
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:922) 
    ... 14 more 

Répondre

0

Actuellement, vous pouvez soutenir des objets immuables dans EclipseLink MOXy (et toutes les autres JAXB (JSR-222) mises en œuvre en utilisant un XmlAdapter. Lorsque le XmlAdapter est utilisé pour convertir entre l'objet immuable et une version mutable de celui-ci.

La demande d'amélioration suivante a été ouverte pour prendre en charge nativement les constructeurs multi-arguments dans MOXy. voter pour cette amélioration afin d'aider à la faire progresser en priorité.

Questions connexes