java 为什么JAXB会说“xxx是接口,而JAXB不能处理接口”。即使生成的类不是接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11503237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 05:21:44  来源:igfitidea点击:

Why does JAXB say "xxx is an interface, and JAXB can't handle interfaces". Even though the generated class is not an interface

javabindingjaxb

提问by Alok Chandna

I used JAXB to bind my xsd's and then tried creating the JAXBContext:

我使用 JAXB 来绑定我的 xsd,然后尝试创建 JAXBContext:

JAXBContext jaxbContext = JAXBContext.newInstance("my package name");

But JAXB gives 180 IllegalAnnotationsException.

但是 JAXB 给出了 180 IllegalAnnotationsException。

Most of the exceptions have the following messages:

大多数异常都有以下消息:

  1. XXX is an interface, and JAXB can't handle interfaces
  2. XXX does not have a no-arg default constructor
  3. @XmlAttribute/@XmlValue need to reference a Java type that maps to text in XML.
  1. XXX是接口,JAXB不能处理接口
  2. XXX 没有无参数的默认构造函数
  3. @XmlAttribute/@XmlValue 需要引用映射到 XML 文本的 Java 类型。

When I look at the classes generated none of them are interfaces and I can't understand why JAXB is interpreting them as interfaces.

当我查看生成的类时,它们都不是接口,我不明白为什么 JAXB 将它们解释为接口。

Here's is the stack trace of one of the errors reported by JAXB :

这是 JAXB 报告的错误之一的堆栈跟踪:

com.sc.md.datatypes.schemas.csemessage.EnvelopeType is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
    at com.sc.md.datatypes.schemas.csemessage.EnvelopeType
    at protected com.sc.md.datatypes.schemas.csemessage.EnvelopeType com.sc.md.datatypes.schemas.csemessage.cseMessage.envelope
    at com.sc.md.datatypes.schemas.csemessage.cseMessage
com.sc.md.datatypes.schemas.csemessage.EnvelopeType does not have a no-arg default constructor.
this problem is related to the following location:
    at com.sc.md.datatypes.schemas.csemessage.EnvelopeType
    at protected com.sc.md.datatypes.schemas.csemessage.EnvelopeType com.sc.md.datatypes.schemas.csemessage.cseMessage.envelope
    at com.sc.md.datatypes.schemas.csemessage.cseMessage

And this is how the type is defined in xsd :

这是在 xsd 中定义类型的方式:

<xs:complexType name="EnvelopeType">
    <xs:sequence>
        <xs:element name="Sent" type="DateTimeType"/>
        <xs:element name="Identifier" type="String_1_14"/>
        <xs:element name="AcknowledgementCode" type="AcknowledgementCodeType"/>
    </xs:sequence>

<xs:simpleType name="AcknowledgementCodeType">
    <xs:restriction base="xs:string">
        <xs:enumeration value="m"/>
        <xs:enumeration value="p"/>
    </xs:restriction>
</xs:simpleType>

Here is the pom.xml I have used to generate the binding :

这是我用来生成绑定的 pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cs</groupId>
<artifactId>cs-jaxb</artifactId>
<packaging>jar</packaging>
<dependencies>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.2.4-1</version>
    </dependency>
</dependencies>
<name>cs jaxb</name>
<version>1.0.0</version>
<parent>
    <artifactId>hip-jaxb-parent</artifactId>
    <groupId>com.cs</groupId>
    <version>0.0.1-SNAPSHOT</version>
</parent>
<build>
    <defaultGoal>install</defaultGoal>
    <plugins>
        <plugin>

            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.8.0</version>
            <executions>
                <execution>

                    <id>CS</id>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <schemaDirectory>src/main/resources/</schemaDirectory>
                        <schemaIncludes>
                            <include>**/*.xsd</include>
                        </schemaIncludes>

                    </configuration>
                </execution>

            </executions>
        </plugin>
        <plugin>
            <inherited>true</inherited>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
    </plugins>
</build>

Please be patient with me since its the first time I'm asking a question on the web :)

请耐心等待,因为这是我第一次在网上提问:)

回答by Alok Chandna

Thanks to all, it was as usual a big mistake on my part, but anyways I enjoyed using stackoverflow for the first time and will make a point to snoop around here.

多亏了所有人,这对我来说和往常一样是一个大错误,但无论如何我第一次喜欢使用 stackoverflow 并且会在这里窥探一下。

The problem was with my classpath.I was referring to a xmlbeans binding project, which had the java source with the same package and classes as the ones generated by jaxb, which were included as a jar on my classpath. So I had 2 classes with same name and package, but to my misery JAXB was picking the Xmlbeans class and I didn't realise that for 2 days.This is one of the oldest errors in Java and I apologise for the blunder.If anyone needs any clarification please drop a comment.

问题出在我的类路径上。我指的是一个 xmlbeans 绑定项目,它的 java 源与 jaxb 生成的包和类具有相同的包和类,这些包和类作为 jar 包含在我的类路径中。所以我有 2 个具有相同名称和包的类,但让我痛苦的是 JAXB 选择了 Xmlbeans 类,我两天没有意识到这一点。这是 Java 中最古老的错误之一,我为这个错误道歉。如果有人需要任何说明,请发表评论。

回答by Robert

Have you annotated all root classes with the @XmlRootElementannotation?

您是否使用注释对所有根类进行了@XmlRootElement注释?

See: Unofficial JAXB Guide - Mapping interfaces - Java.net

请参阅:非官方 JAXB 指南 - 映射接口 - Java.net

Second, I would recommend you not to create your JAXBContext via JAXBContext.newInstance("my package name");. It is better to specify the root classes explicitly. Therefore if you have two root classes named ClassAand ClassBuse it this way:

其次,我建议您不要通过JAXBContext.newInstance("my package name");. 最好明确指定根类。因此,如果您有两个根类命名ClassAClassB以这种方式使用它:

JAXBContext.newInstance(new Class[] {ClassA.class, ClassB.class});

回答by bdoughan

I suspect that you are trying to use a JAXB 1 (JSR-31) model with a JAXB 2 (JSR-222) runtime. In JAXB 1 implementations generated spec defined interfaces backed by implementation specific impl clases. In JAXB 2 this became spec defined classes with standard annotations that are compatible with all implementations. Most JAXB 2 implementations support their own JAXB 1 models, but some additional config may be necessary, if you try to use a JAXB 1 model with a difference JAXB 2 provider you may see this type of error.

我怀疑您正在尝试将 JAXB 1 ( JSR-31) 模型与 JAXB 2 ( JSR-222) 运行时一起使用。在 JAXB 1 实现中,生成的规范定义的接口由实现特定的 impl 类支持。在 JAXB 2 中,这成为规范定义的类,带有与所有实现兼容的标准注释。大多数 JAXB 2 实现都支持它们自己的 JAXB 1 模型,但可能需要一些额外的配置,如果您尝试使用具有不同 JAXB 2 提供程序的 JAXB 1 模型,您可能会看到此类错误。