MOXy un/marshal an object belonging to two different lists - jaxb

This is my scenario.
I have a NodeElement class with two lists, inLinks and outLinks.
the Link class has two refrences to NodeElement, one for source and the other for target.
#XmlAccessorType(XmlAccessType.FIELD)
class NodeLement{
#XmlElement(name="link")
#XmlElementWrapper
private List<Link> inLinks = new ArrayList<Link>();
#XmlElement(name="link")
#XmlElementWrapper
private List<Link> outLinks = new ArrayList<Link>();
...
}
#XmlAccessorType(XmlAccessType.FIELD)
class Link{
#XmlInverseReference(mappedBy="inLinks")
private NodeElement source;
#XmlInverseReference(mappedBy="outLinks")
private NodeElement target;
public NodeElement getSource() {
return source;
}
public void setSource(NodeElement source) {
this.source = source;
this.source.getInLink().add(this);
}
public NodeElement getTarget() {
return target;
}
public void setTarget(NodeElement target) {
this.target = target;
this.target.getOutLink().add(this);
}
}
The test class
class test {
public static void main(String args[]) throws JAXBException, FileNotFoundException {
//rootelement
ContainerElement c = new ContainerElement();
Link link = new Link();
NodeElement target = new NodeElement();
NodeElement source = new NodeElement();
link.setSource(source);
link.setTarget(target);
c.addChild(target);
c.addChild(source);
JAXBContext jc = JAXBContext.newInstance(ContainerElement.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(c, new File(XML_MODEL));
}
}
The result :
<?xml version="1.0" encoding="UTF-8"?>
<containerElement>
<ID>427485825424142</ID>
<inLinks/>
<outLinks/>
<children>
<child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="NodeElement">
<ID>427520478709873</ID>
<inLinks/>
<outLinks>
<link xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Link">
<ID>427582226289815</ID>
</link>
</outLinks>
</child>
<child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="NodeElement">
<ID>427548409900894</ID>
<inLinks>
<link xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Link">
<ID>427582226289815</ID>
</link>
</inLinks>
<outLinks/>
</child>
</children>
</containerElement>
Obviously, i get two instances of Link when unmarshaling, each one has either the source or the target as null and the other target/source correctly set.
How could i fix this so the unmarshaling provides one instance of Link correctly initialized ?
I was thinking of using before and after marshal to resolve the relation between the source and the target but I am just learning JAXB, so any help would be appreciated

There are two kinds of way to represent relationships in XML:
Containment (i.e. #XmlElement) the referenced object is represented as child elements.
Reference (i.e. #XmlIDREF) the referenced object is represented with a foreign key (see: http://blog.bdoughan.com/2010/10/jaxb-and-shared-references-xmlid-and.html).
Every object (other than the root object) must be reachable through exacttly one containment relationship. Optionally it may be referenced by one or more reference relationships.
If you are looking to mix these concepts where the first time an object is encountered it is represented via containment and then subsequent times it is represented by reference then check out the following answer that contains a full example.
Can JAXB marshal by containment at first then marshal by #XmlIDREF for subsequent references?

Related

JAXB and MOXy xml and json marshalling of generic list in jersey

I'm making a little restful client in Jersey, and i have come into a little trouble with supporting both XML and JSON marshaling.
The specific problem is about marshaling an object that holds a few properties, with a generic list included.
I have the following class annotated as followed:
#XmlRootElement
public class Block<E> {
private String headerText;
private List<E> elements;
public Block() {
}
#XmlElement
public String getHeaderText() {
return headerText;
}
#XmlElementWrapper(name = "elements")
#XmlElements({
#XmlElement(name = "element", type=Foo.class),
#XmlElement(name = "element", type=Bar.class)
})
public List<E> getElements() {
return elements;
}
}
The XML comes out fine:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<block>
<elements>
<element>
<id>1</id>
<title>Title01</title>
</element>
<element>
<id>2</id>>
<title>Title02</title>
</element>
</elements>
<headerText>FooBarHeader</headerText>
</block>
but the JSON is formatted like this
{
-elements : {
-element: [
- {
id : 1
title : "Title01"
}
- {
id : 2
title : "Title02"
}
]
}
headerText : "HeaderText"
}
I would of course be interested in not having the "element" property in my JSON output, and only have elements: [{}...{}]
I have already setup a ContextResolver that creates a MOXyConfig with properties for JSON_WRAPPER_AS_ARRAY_NAME - and this works fine for fx. A List<String> where I only have to declare the property with #XmlElement instead of #XmlElements.
Anyone who know of a solution of this problem?
JSON_WRAPPER_AS_ARRAY_NAME Property
The effect of the JSON_WRAPPER_AS_ARRAY_NAME property (see: http://blog.bdoughan.com/2013/03/binding-to-json-xml-handling-collections.html) depends on whether the item names are significant or not,
Insignificant Item Names
Below we know that each item in the collection is an instance of Foo or an instance of a subclass of Foo.
#XmlElementWrapper(name = "elements")
#XmlElement(name = "element")
public List<E> getElements() {
return elements;
}
Significant Item Names
In the case of #XmlElements the item name is significant since it tells us which class we need to instantiate on the unmarshal and can not be excluded.
#XmlElementWrapper(name = "elements")
#XmlElements({
#XmlElement(name = "foo", type=Foo.class),
#XmlElement(name = "bar", type=Bar.class)
})
public List<E> getElements() {
return elements;
}
What You Can Do
You can use MOXy's externmal mapping document to override the mapping for the elements property to the following:
#XmlElementWrapper(name = "elements")
#XmlElement(name = "foo")
public List<E> getElements() {
return elements;
}
Then the JAXBContext for XML will be based on the annotations, and the JAXBContext for JSON will be based on the annotatons and external mapping document.
For More Information
http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html
http://blog.bdoughan.com/2011/09/mapping-objects-to-multiple-xml-schemas.html
Try registering another JSON Entity Provider, which will disable automatically Moxy for JSON marshalling (see the ref). If you enable e.g Jackson, you will have its own annotations to control how everything is marshalled.

Marshalling collections when using XmlElementWrapper

I have a collection on my class that uses #XmlElementWrapper to wrap the collection in a extra element.
So, my class looks something like this:
class A {
#XmlElement(name = "bee")
#XmlElementWrapper
public List<B> bees;
}
And my XML then looks something like:
<a>
<bees>
<bee>...</bee>
<bee>...</bee>
</bees>
</a>
Great, this is what I wanted. However, when I try and marshall into JSON, I get this:
{
"bees": {
"bee": [
....
]
}
}
And I don't want that extra "bee" key there.
Is it possible to somehow have MOXy ignore the XmlElement part when doing this marshalling? because I still need the name to be "bees" and not "bee", and I don't want both.
I'm using MOXy 2.4.1 and javax.persistence 2.0.0.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
oxm.xml
You could use MOXy's external mapping document to provide an alternate mapping for your JSON-binding (see: http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html).
<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum14002508">
<java-types>
<java-type name="A">
<java-attributes>
<xml-element java-attribute="bees" />
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
Demo
In the demo code below we will create two instances of JAXBContext. The first is build solely on the JAXB annotations that we will use for XML. The second is built on the JAXB annotations and uses MOXy's external mapping file to override the mapping for the bees property on the A class.
package forum14002508;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Demo {
public static void main(String[] args) throws Exception {
List<B> bees = new ArrayList<B>();
bees.add(new B());
bees.add(new B());
A a = new A();
a.bees = bees;
JAXBContext jc1 = JAXBContext.newInstance(A.class);
Marshaller marshaller1 = jc1.createMarshaller();
marshaller1.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller1.marshal(a, System.out);
Map<String, Object> properties = new HashMap<String, Object>(3);
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum14002508/oxm.xml");
properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
JAXBContext jc2 = JAXBContext.newInstance(new Class[] {A.class}, properties);
Marshaller marshaller2 = jc2.createMarshaller();
marshaller2.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller2.marshal(a, System.out);
}
}
Output
Below is the output from running the demo code that matches your use case.
<a>
<bees>
<bee/>
<bee/>
</bees>
</a>
{
"bees" : [ {
}, {
} ]
}
For More Information
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html

Jaxb EclipseLink/MOXy : Is it possible to specify the names of get/set methods

I have a quite simple question :
Say I have a model class defined like this :
public class Test{
private String testAttribute;
public Test(){
}
public String getFormattedTestAttribute(){
return testAttribute + "A nice formatted thingy"; //right, this is just an example
}
public void setTestAttribute(String value){
testAttribute = value;
}
}
You can see that I have a standard setter for testProperty but the getter has a different name : getFormattedTestProperty().
Is it possible into Jaxb/Moxy to specify which getter to use for a specific property ?
I'm using MOXy implementation with external metadata bindings file. The project which I'm working on used tu use Castor. Into Castor's mapping files, you could specify which getter/setter to use like that :
<field name="testAttribute"
get-method="getFormattedTestAttribute">
<bind-xml name="test-attribute" node="attribute"/>
</field>
Is the same kind of thing possible with moxy's external metadata ?
If that kind of customization isn't supported, is it possible to mark a field as read-only and another as write-only ? so I could declare a read-only property named "formattedTestAttribute" and a write-only property named "testAttribute" into the metadata bindings file ?
<!-- read only property -->
<xml-element java-attribute="formattedTestAttribute" xml-path="#test-attribute" />
<!-- write only property -->
<xml-element java-attribute="testAttribute" xml-path="#test-attribute" />
Please note that I have very limited control over the model classes.
Thanks in advance for your answers.
You could represent this in EclipseLink JAXB (MOXy)'s external mapping document as follows:
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum8834871">
<java-types>
<java-type name="Test" xml-accessor-type="PUBLIC_MEMBER">
<xml-root-element/>
<java-attributes>
<xml-element
java-attribute="testAttribute"
name="test-attribute">
<xml-access-methods
get-method="getFormattedTestAttribute"
set-method="setTestAttribute"/>
</xml-element>
<xml-transient java-attribute="formattedTestAttribute"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
Test
I have modified your Test class, to put some logic in the get/set methods.
package forum8834871;
public class Test{
private String testAttribute;
public Test(){
}
public String getFormattedTestAttribute(){
return "APPENDED_ON_GET " + testAttribute;
}
public void setTestAttribute(String value){
testAttribute = "APPENDED_ON_SET " + value;
}
}
Demo
package forum8834871;
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);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum8834871/oxm.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {Test.class}, properties);
File xml = new File("src/forum8834871/input.xml");
Unmarshaller unmarshaller = jc.createUnmarshaller();
Test test = (Test) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(test, System.out);
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<test>
<test-attribute>ORIGINAL</test-attribute>
</test>
Output
<?xml version="1.0" encoding="UTF-8"?>
<test>
<test-attribute>APPENDED_ON_GET APPENDED_ON_SET ORIGINAL</test-attribute>
</test>

JAXB-Eclipselink: Mapping abstract "getter" to XML

I am using the EclipseLink implementation (2.3) of JAXB to map POJOs to XML and encountering a problem with following usecase:
public abstract class A {
public abstract Set<X> getX();
// There is no setter
}
public class B extends A {
// Set via constructor
private Set<X> x;
#Override
public Set<X> getX();
}
I am defining the mapping itself completely in an external bindings-file, i set class A to be transient like so:
<java-type name="foo.A" xml-transient="true"/>
and for class B:
<java-type name="bar.B" xml-accessor-type="PROPERTY">
<xml-root-element name="B" />
<java-attributes>
<xml-element java-attribute="x" xml-path="..."/>
</java-attributes>
</java-type>
Now, upon marshalling i am getting the exception: "Duplicate Property named [x] found on class [bar.B]"
which in my opinion is coming from the abstract declaration in A, being inherited by B.
Setting the accessor-type for B to FIELD, gets rid of this error, unfortunately this is not an option because i do have an extra property in B to marshal which does not return a field but a calculated value, so i am stuck with PROPERTY (following works: setting accessor-type for B to FIELD and mapping the extra property with an #XmlPath annotation - but i dont want annotations in my code).
Being stuck with accessor-type PROPERTY for class B, my next attempt was:
<java-type name="foo.A" xml-accessor-type="NONE"/>
to prevent the abstract property from being inherited by B, which gets me:
Ignoring attribute [x] on class [bar.B] as no Property was generated for it.
Same is happening using this mapping:
<java-type name="foo.A" xml-accessor-type="PROPERTY">
<java-attributes>
<xml-transient java-attribute="x"/>
</java-attributes>
</java-type>
In both cases property 'x' is ignored.
I have really spent quite some time on this now - i cant imagine that its not possible to get this to work??
My workaround at the moment:
Leaving foo.A to be transient, specifying accessor-type FIELD for bar.B (which gets me property 'x' without problems) and mapping the extra property in B using an annotation in code.
But as mentioned before: I would like to solve this completely without annotations - anybody any idea? Blaise? :)
regards,
--qu
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
You appear to have hit a bug. You can track our progress on this issue at the following link. I have provided additional details on this issue below:
https://bugs.eclipse.org/367886
Using Annotations
If you were going to map this use case with JAXB/MOXy annotations you could set #XmlAccessorType(XmlAccessType.NONE) on the A class and do something like:
A
package forum8727402;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.NONE)
public abstract class A {
public abstract String getX();
}
B
package forum8727402;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement
public class B extends A {
#XmlPath("a/b/c/text()")
private String x;
public B() {
x = "Hello World";
}
#Override
public String getX() {
return x;
}
#XmlElement
public String getCalculatedValue() {
return "Calculated Value";
}
}
Demo
package forum8727402;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(B.class);
B b = new B();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(b, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8"?>
<b>
<a>
<b>
<c>Hello World</c>
</b>
</a>
<calculatedValue>Calculated Value</calculatedValue>
</b>
Using MOXy's External Mapping File
oxm.xml
Below is a MOXy external mapping file that represents the equivalent of the previously shown annotations:
<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum8727402">
<java-types>
<java-type name="A" xml-accessor-type="NONE"/>
<java-type name="B">
<xml-root-element/>
<java-attributes>
<xml-element java-attribute="x" xml-path="a/b/c/text()"/>
<xml-element java-attribute="calculatedValue"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
Demo
The code below demonstrates how to reference the mapping file:
package forum8727402;
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);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum8727402/oxm.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {A.class, B.class}, properties);
B b = new B();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(b, System.out);
}
}
Output
[EL Warning]: 2012-01-04 14:45:46.366--Ignoring attribute [x] on class [forum8727402.xml.B] as no Property was generated for it.
<?xml version="1.0" encoding="UTF-8"?>
<b>
<calculatedValue>Calculated Value</calculatedValue>
</b>

Add/Override behavior on Jaxb generated classes by extending them

I have a web server responding with xml data and a client consuming it.
Both share the same domain code. One of the domain objects looks like this:
#XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
#XmlRootElement(name = "image")
public class Image {
private String filename;
private ImageTypeEnum type;
#XmlElement(name = "imageUri")
public String getAbsoluteUri() {
// some complex computation
return uri;
}
}
When I try to unmarshal the response from the server into this object, since there's no setter for absoluteUri, I don't have the imageUri in the class. So I extend it like this:
public class FEImage extends Image{
private String imageUri;
public String getAbsoluteUri() {
return imageUri;
}
public void setAbsoluteUri(String imageUri) {
this.imageUri = imageUri;
}
}
My ObjectFactory
#XmlRegistry
public class ObjectFactory {
public Image createImage(){
return new FEImage();
}
}
My code to unmarshal is here:
JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setProperty("com.sun.xml.bind.ObjectFactory",new ObjectFactory());
((JAXBElement)unmarshaller.unmarshal((InputStream) response.getEntity())).getValue();
However, the setAbsoluteUri doesn't seem to be getting called in FEImage while unmarshalling. When I add a dummy setAbsoluteUri in Image.java, everything works as expected.
Can someone tell me how can I cleanly extend from Image.java?
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
A JAXB implementation is not required to use the ObjectFactory class when instantiating an object. You can configure instantiation to be done via a factory class using the #XmlType annotation:
#XmlType(factoryClass=ObjectFactory.class, factoryMethod="createImage")
public class Image {
private String filename;
private ImageTypeEnum type;
#XmlElement(name = "imageUri")
public String getAbsoluteUri() {
// some complex computation
return uri;
}
}
http://blog.bdoughan.com/2011/06/jaxb-and-factory-methods.html
If you do the above, then your JAXB implementation will still use the Image class to derive the metadata so it will not solve your problem. An alternate approach would be to use an XmlAdapter for this use case:
http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html
Better still, when a property on your domain object does not have a setter, you can tell your
JAXB implementation (EclipseLink MOXy, Metro, Apache JaxMe, etc) to use field (instance variable) access instead using #XmlAccessorType(XmlAccessType.FIELD):
#XmlAccessorType(XmlAccessType.FIELD)
public class Image {
}
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
UPDATE #1
If you are not able to modify the domain objects, then you may be interested in MOXy's externalized metadata. This extension provides a means via XML to provide JAXB metadata for classes where you cannot modify the source.
For More Information
http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html
http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy/Runtime/XML_Bindings
UPDATE #2 - Based on results of chat
Image
Below is the implementation of the Image class that I will use for this example. For the complex computation of getAbsoluteUri() I simply add the prefix "CDN" to the filename:
package forum7552310;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
#XmlRootElement(name = "image")
public class Image {
private String filename;
private ImageTypeEnum type;
#XmlElement(name = "imageUri")
public String getAbsoluteUri() {
return "CDN" + filename;
}
}
binding.xml
Below is the MOXy binding document I put together. In this file I do a few things:
Set XmlAccessorType to FIELD
Mark the absoluteURI property to be XmlTransient since we will be mapping the filename field instead.
Specify that an XmlAdapter will be used with the filename field. This is to apply the logic that is done in the getAbsoluteUri() method.
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum7552310">
<java-types>
<java-type name="Image" xml-accessor-type="FIELD">
<java-attributes>
<xml-element java-attribute="filename" name="imageUri">
<xml-java-type-adapter value="forum7552310.FileNameAdapter"/>
</xml-element>
<xml-transient java-attribute="absoluteUri"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
FileNameAdapter
Below is the implementation of the XmlAdapter that applies the same name algorithm as the getAbsoluteUri() method:
package forum7552310;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class FileNameAdapter extends XmlAdapter<String, String> {
#Override
public String marshal(String string) throws Exception {
return "CDN" + string;
}
#Override
public String unmarshal(String adaptedString) throws Exception {
return adaptedString.substring(3);
}
}
Demo
Below is the demo code demonstrating how to apply the binding file when creating the JAXBContext:
package forum7552310;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
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);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum7552310/binding.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {Image.class}, properties);
File xml = new File("src/forum7552310/input.xml");
Unmarshaller unmarshaller = jc.createUnmarshaller();
Image image = (Image) unmarshaller.unmarshal(xml);
System.out.println(image.getAbsoluteUri());
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(image, System.out);
}
}
jaxb.properties
You need to include a file named jaxb.properties with the following contents in the same package as your Image class:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
input.xml
Here is the XML input I used:
<?xml version="1.0" encoding="UTF-8"?>
<image>
<imageUri>CDNURI</imageUri>
</image>
Output
And here is the output from running the demo code:
CDNURI
<?xml version="1.0" encoding="UTF-8"?>
<image>
<imageUri>CDNURI</imageUri>
</image>

Resources