hummusw :
I created a subclass of VBox that I want to marshall using an adapter, but JAXB throws IllegalAnnonationExceptions, saying that it cannot handle interfaces. Am I using the adapter incorrectly here?
I am writing this in Java 1.8 with the built-in versions of JavaFX and JAXB.
A minimal, reproducible example:
import javafx.scene.layout.VBox;
import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.nio.file.Files;
import java.nio.file.Paths;
class Foo extends VBox {
private int bar;
public Foo(int bar) {
this.bar = bar;
}
public int getBar() {
return bar;
}
}
class XMLfoo {
public int bar;
}
class XMLfooAdapter extends XmlAdapter<XMLfoo, Foo> {
@Override public Foo unmarshal(XMLfoo xmLfoo) {
return new Foo(xmLfoo.bar);
}
@Override public XMLfoo marshal(Foo foo) {
XMLfoo out = new XMLfoo();
out.bar = foo.getBar();
return out;
}
}
public class TestFoo {
@XmlJavaTypeAdapter(XMLfooAdapter.class) private static Foo foo = new Foo(1);
public static void main(String[] args) throws Exception{
JAXB.marshal(foo, Files.newBufferedWriter(Paths.get("foo.xml")));
}
}
Stacktrace:
Exception in thread "main" javax.xml.bind.DataBindingException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
javafx.event.EventDispatcher is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at javafx.event.EventDispatcher
at public final javafx.event.EventDispatcher javafx.scene.Node.getEventDispatcher()
at javafx.scene.Node
at javafx.scene.shape.Shape
at public final javafx.scene.shape.Shape javafx.scene.layout.Region.getShape()
at javafx.scene.layout.Region
at javafx.scene.layout.Pane
at javafx.scene.layout.VBox
at Foo
javafx.scene.input.InputMethodRequests is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at javafx.scene.input.InputMethodRequests
at public final javafx.scene.input.InputMethodRequests javafx.scene.Node.getInputMethodRequests()
at javafx.scene.Node
at javafx.scene.shape.Shape
at public final javafx.scene.shape.Shape javafx.scene.layout.Region.getShape()
at javafx.scene.layout.Region
at javafx.scene.layout.Pane
at javafx.scene.layout.VBox
at Foo
javafx.event.EventHandler is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at javafx.event.EventHandler
at public final javafx.event.EventHandler javafx.scene.Node.getOnContextMenuRequested()
at javafx.scene.Node
at javafx.scene.shape.Shape
at public final javafx.scene.shape.Shape javafx.scene.layout.Region.getShape()
at javafx.scene.layout.Region
at javafx.scene.layout.Pane
at javafx.scene.layout.VBox
at Foo
at javax.xml.bind.JAXB._marshal(JAXB.java:574)
at javax.xml.bind.JAXB.marshal(JAXB.java:456)
at Foo.main(Foo.java:23)
Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
javafx.event.EventDispatcher is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at javafx.event.EventDispatcher
at public final javafx.event.EventDispatcher javafx.scene.Node.getEventDispatcher()
at javafx.scene.Node
at javafx.scene.shape.Shape
at public final javafx.scene.shape.Shape javafx.scene.layout.Region.getShape()
at javafx.scene.layout.Region
at javafx.scene.layout.Pane
at javafx.scene.layout.VBox
at Foo
javafx.scene.input.InputMethodRequests is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at javafx.scene.input.InputMethodRequests
at public final javafx.scene.input.InputMethodRequests javafx.scene.Node.getInputMethodRequests()
at javafx.scene.Node
at javafx.scene.shape.Shape
at public final javafx.scene.shape.Shape javafx.scene.layout.Region.getShape()
at javafx.scene.layout.Region
at javafx.scene.layout.Pane
at javafx.scene.layout.VBox
at Foo
javafx.event.EventHandler is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at javafx.event.EventHandler
at public final javafx.event.EventHandler javafx.scene.Node.getOnContextMenuRequested()
at javafx.scene.Node
at javafx.scene.shape.Shape
at public final javafx.scene.shape.Shape javafx.scene.layout.Region.getShape()
at javafx.scene.layout.Region
at javafx.scene.layout.Pane
at javafx.scene.layout.VBox
at Foo
at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:445)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:462)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at javax.xml.bind.JAXB$Cache.<init>(JAXB.java:112)
at javax.xml.bind.JAXB.getContext(JAXB.java:139)
at javax.xml.bind.JAXB._marshal(JAXB.java:563)
... 2 more
hummusw :
Got it working based on Slaw's comment:
import javafx.scene.layout.VBox;
import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlRootElement;
import java.nio.file.Files;
import java.nio.file.Paths;
class Foo extends VBox {
private int bar;
public Foo(int bar) {
this.bar = bar;
}
// To get a Foo back from a XMLfoo
public Foo(XMLfoo xmLfoo) {
this.bar = xmLfoo.bar;
}
public int getBar() {
return bar;
}
// To convert from Foo to XMLfoo
public XMLfoo toXML() {
XMLfoo out = new XMLfoo();
out.bar = bar;
return out;
}
}
@XmlRootElement(name = "Foo")
class XMLfoo {
public int bar;
}
public class TestFoo {
public static void main(String[] args) throws Exception {
JAXB.marshal((new Foo(1)).toXML(), Files.newBufferedWriter(Paths.get("foo.xml")));
Foo foo = new Foo(JAXB.unmarshal(Files.newBufferedReader(Paths.get("foo.xml")), XMLfoo.class));
}
}
Will create foo.xml
that contains
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Foo>
<bar>1</bar>
</Foo>