IllegalAnnotationExceptions occurs when trying to marshall a VBox subclass

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>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=146162&siteId=1