2

を拡張するクラスがありThread、その構成情報をxmlとして保存できるようにしたいと考えています。Thread他のすべてのプロパティとクラスにないものがあるため、これは明らかに機能しません。マーシャリング中に、素晴らしいスタック トレースを取得します。

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
java.lang.Thread$UncaughtExceptionHandler is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at java.lang.Thread$UncaughtExceptionHandler
        at public java.lang.Thread$UncaughtExceptionHandler java.lang.Thread.getUncaughtExceptionHandler()
        at java.lang.Thread
        at Test
java.lang.Thread$UncaughtExceptionHandler does not have a no-arg default constructor.
    this problem is related to the following location:
        at java.lang.Thread$UncaughtExceptionHandler
        at public java.lang.Thread$UncaughtExceptionHandler java.lang.Thread.getUncaughtExceptionHandler()
        at java.lang.Thread
        at Test

    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:451)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:283)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:126)
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1142)
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:130)
    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:445)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
    at Test.main(Test.java:22)

問題を示す簡単なクラスを次に示します。

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;



@XmlRootElement
public class Test extends Thread{

    @XmlAttribute
    public String something;

    public Test(){
    }

    public static void main(String[] args) throws JAXBException {
        Test test = new Test();
        test.something = "My Value";

        JAXBContext jaxbContext = JAXBContext.newInstance(Test.class);

        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        // output pretty printed
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        jaxbMarshaller.marshal(test, System.out);

    }

}

Test基本的に、継承されたものではなく、クラスにあるものだけを気にします。次のようなものです:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test something="My Value"/>

では、マーシャリング/アンマーシャリング中に基本クラスを無視するにはどうすればよいですか?

4

1 に答える 1

3

Thread を拡張し、Runnable を実装しないのはなぜですか?

とにかく、あなたの解決策は、スレッドまたはそれを拡張するクラスをマーシャリングおよびアンマーシャリングするのではなく、マーシャリングおよびアンマーシャリングする重要な状態データを保持する別の構成クラスを作成することだと思います。

例えば、

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

public class Test implements Runnable {

   private TestConfig config = new TestConfig();

   public Test() {
   }

   public void setConfigSomething(String something) {
      config.setSomething(something);
   }

   public TestConfig getConfig() {
      return config;
   }

   public void setConfig(TestConfig config) {
      this.config = config;
   }

   @Override
   public void run() {
      // foo
   }

   public static void main(String[] args) throws JAXBException {
      Test test = new Test();
      test.setConfigSomething("My Value");

      JAXBContext jaxbContext = JAXBContext.newInstance(TestConfig.class);

      Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
      jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      jaxbMarshaller.marshal(test.getConfig(), System.out);    
   }
}

@XmlRootElement
class TestConfig {
   private String something;

   @XmlAttribute
   public String getSomething() {
      return something;
   }

   public void setSomething(String something) {
      this.something = something;
   }
}

これにより、期待される出力が得られます。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<testConfig something="My Value"/>

別の可能な解決策は、XmlAdapter などのアダプター タイプを使用することであり、おそらく最良の解決策は、Blaise Doughan の提案に従って MOXyを使用することです。

于 2013-03-20T03:24:39.557 に答える