I have three 3rd party immutable objects(Foo, Bar, BarFactory) and binding.xml. I'd like to mark up 3rd party immutable objects in binding.xml, but JAXB require zero argument constructor. Is it impossible to marshall these classes in JAXB and MOXy?
Foo, Bar, BarFactory, demo codes binding.xml and are below.
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, customized ClassExtractor and demo class are below.
--- 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);
}
}
and example.bindingfile.Demo throw below 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