Java 生成实现接口的JAXB类

Java 生成实现接口的JAXB类,java,xsd,jaxb,xjc,jaxb2-basics,Java,Xsd,Jaxb,Xjc,Jaxb2 Basics,我目前正在使用JAXB生成java类,以便解组XML。现在我想创建一个与第一个模式非常相似的新模式,并让生成的类实现相同的接口 例如,我有两个模式文件,它们用相似的标记定义XML: 成人.xsd kid.xsd 使用JAXB和XJC,我想生成两个类文件: public class Adult implements Person { ... public String getName() { ... } public int getAge() { ... }

我目前正在使用JAXB生成java类,以便解组XML。现在我想创建一个与第一个模式非常相似的新模式,并让生成的类实现相同的接口

例如,我有两个模式文件,它们用相似的标记定义XML:

成人.xsd


kid.xsd


使用JAXB和XJC,我想生成两个类文件:

public class Adult implements Person {
    ...
    public String getName() { ... }
    public int getAge() { ... }
    public String getJob { ... }
}

public class Kid implements Person {
    ...
    public String getName() { ... }
    public int getAge() { ... }
    public String getSchool { ... }
}
其中Person接口定义了
getName()
getAge()
方法

我已经研究了一些用于映射接口的方法,但这似乎只适用于您已经有了要映射到DOM的java类的情况

另外,我也尝试过使用它,但它似乎不起作用。这是我的xjb绑定文件:


我的包裹,你好
但这会产生以下错误:

$java-cp“lib/activation.jar;lib/InterfacesXJCPlugin.jar;lib/jaxb1 impl.jar;lib/jaxb api.jar;lib/jaxb xjc.jar;lib/jsr173_1.0_api.jar”com.sun.tools.xjc.xjc facade-p mypackage.myxml-extension-Xinterfaces xsd/成人.xsd-b binding.xjb
正在分析架构。。。
[错误]对“xs:schema/xs:complexType[@name='Person']”的XPath求值导致目标节点为空
文件的第8行:/C:/dev/jaxb/jaxb ri/binding.xjb
未能分析架构。
可以用JAXB生成一个实现接口的类吗

更新

我尝试过使用这个插件,但由于某些原因无法使它工作。这就是我调用xjc的方式,但好像插件jar没有从类路径中获取:

$java-cp“lib/xjc if ins.jar;lib/jaxb xjc.jar”com.sun.tools.xjc.xjcmeacade-p mypackage-extension-Xifins myschema.xsd-b binding.xjb
我得到一个错误:

无法识别的参数-Xifins

有什么想法吗?

某种描述的XJC plygin可以解决您的问题,只需找到一个有效的。他们的最佳来源是:

特别是,这一点:


接口插入插件的文档建议如下

[ 要从命令行使用接口插入插件调用xjc,您可以编写:

java -cp $JAXB_HOME/share/lib/xjc-if-ins.jar -extension -Xifins schema
]

我猜您调用了错误类的main方法-com.sun.tools.xjc.xjcafacade。您可能应该使用确切的语法重试

这里是另一个讨论类似问题的论坛的链接。

  • 我本想将此作为评论发表,但我没有足够的观点发表评论

对于您的情况来说,这可能有点过头了,但我已经使用AspectJ完成了这项工作(我们已经在该项目中使用了AspectJ,所以我们已经有了依赖性和公开性)

您可以声明一个方面,大致如下:

public aspect MyAspect
{
    declare parents: 
        com.foo.generated.Adult
    implements com.foo.Person;

    declare parents: 
        com.foo.generated.Kid
    implements com.foo.Person;
}
这将把接口
com.foo.Person
添加到类
com.foo.generated.maintal
com.foo.generated.Kid


对于您来说,这可能有些过分,但对我们来说是有效的。

在我的例子中,通过java-jar的命令行调用是有效的:

java-jar$somepath/jaxb-xjc.jar-classpath$somepath/xjc-if-ins.jar my.xsd-d$destdir-b$bindingconfig-p$desiredpackage-extension-Xifins

但是,在执行xjc ant任务时,错误仍然存在。给出的错误消息令人恼火,因为在我的例子中,真正的原因是ant试图加载的类文件中存在错误的版本号(请参见下面的stacktrace)。只有将以下内容添加到ANT_选项时,才会显示此正确的错误消息:
-Dcom.sun.tools.xjc.Options.findServices=true

[xjc] java.lang.UnsupportedClassVersionError: Bad version number in .class file
[xjc]     at java.lang.ClassLoader.defineClass1(Native Method)
[xjc]     at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
[xjc]     at org.apache.tools.ant.AntClassLoader.defineClassFromData(AntClassLoader.java:1134)
[xjc]     at org.apache.tools.ant.AntClassLoader.getClassFromStream(AntClassLoader.java:1320)
[xjc]     at org.apache.tools.ant.AntClassLoader.findClassInComponents(AntClassLoader.java:1376)
[xjc]     at org.apache.tools.ant.AntClassLoader.findClass(AntClassLoader.java:1336)
[xjc]     at org.apache.tools.ant.AntClassLoader.loadClass(AntClassLoader.java:1074)
[xjc]     at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
[xjc]     at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
[xjc]     at com.sun.tools.xjc.Options.findServices(Options.java:936)
[xjc]     at com.sun.tools.xjc.Options.getAllPlugins(Options.java:336)
[xjc]     at com.sun.tools.xjc.Options.parseArgument(Options.java:632)
[xjc]     at com.sun.tools.xjc.Options.parseArguments(Options.java:742)
[xjc]     at com.sun.tools.xjc.XJC2Task._doXJC(XJC2Task.java:444)
[xjc]     at com.sun.tools.xjc.XJC2Task.doXJC(XJC2Task.java:434)
[xjc]     at com.sun.tools.xjc.XJC2Task.execute(XJC2Task.java:369)
[xjc]     at com.sun.istack.tools.ProtectedTask.execute(ProtectedTask.java:55)
[xjc]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
[xjc]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[xjc]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[xjc]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[xjc]     at java.lang.reflect.Method.invoke(Method.java:585)
[xjc]     at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
[xjc]     at org.apache.tools.ant.Task.perform(Task.java:348)
[xjc]     at org.apache.tools.ant.Target.execute(Target.java:390)
[xjc]     at org.apache.tools.ant.Target.performTasks(Target.java:411)
[xjc]     at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1360)
[xjc]     at org.apache.tools.ant.Project.executeTarget(Project.java:1329)
[xjc]     at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[xjc]     at org.apache.tools.ant.Project.executeTargets(Project.java:1212)
[xjc]     at org.apache.tools.ant.Main.runBuild(Main.java:801)
[xjc]     at org.apache.tools.ant.Main.startAnt(Main.java:218)
[xjc]     at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
[xjc]     at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
[xjc]
[xjc] failure in the XJC task. Use the Ant -verbose switch for more details

不幸的是,其他一些答案中提到的接口注入插件似乎不再得到很好的支持。事实上,我很难找到下载的JAR

谢天谢地,提供了一种类似的机制,用于向生成的JAXB存根添加接口(请参阅)

继承插件文档有一个示例,显示了XML模式文件的外观。但是,由于无法修改架构,因此可以改用外部绑定文件:


我的包裹,你好
JAXB2基础插件文档包括将插件与Ant和Maven一起使用的说明。您也可以直接从命令行使用它,但该命令有点混乱(由于必须添加到类路径的JAR数量太多):

java-jarjaxb-xjc.jar
-类路径jaxb2-basics-0.5.3.jar,jaxb2-basics-runtime-0.5.3.jar,
jaxb2-basics-tools-0.5.3.jar,commons-beanutils-0.5.3.jar,
commons-lang.jar,commons-logging.jar
-p mypackage.myxml-extension-Xinheritance xsd/成人.xsd-b binding.xjb

JAXB2基础插件提供了许多其他实用程序,您可能会发现这些实用程序也很有用(例如自动生成equals、hashCode和toString方法)。

对我有效的答案是Jim Hurne使用JAXB2基础插件的示例。但他链接的文档似乎不再可用,因此仅供参考,以下是我配置maven插件的方式:

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.8.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    </execution>
            </executions>
            <configuration>
                <extension>true</extension>
                <args>
                    <arg>-Xinheritance</arg>
                </args>
                <bindingDirectory>src/main/resources/xjb</bindingDirectory>
                <bindingIncludes>
                    <include>**.xml</include> <!-- This Should reference the binding files you use to configure the inheritance -->
                </bindingIncludes>
                <schemaDirectory>src/main/resources/xsd</schemaDirectory>
                <generateDirectory>${project.build.directory}/generated-sources/jaxb</generateDirectory>
                <generatePackage>mypackage</generatePackage>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics</artifactId>
                        <version>0.5.3</version>
                    </plugin>
                </plugins>
            </configuration>
        </plugin>

org.jvnet.jaxb2.maven2
maven-jaxb2-plugin
0.8.2
生成
真的
-新遗传
src/main/resources/xjb
**.xml
src/main/resources/xsd
${project.build.directory}/generated sources/jaxb
我的包裹
org.jvnet.jaxb2_commons
jaxb2基础知识
<jxb:bindings version="1.0" 
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
  jxb:extensionBindingPrefixes="xjc">
    <jxb:bindings schemaLocation="adult.xsd" node="/xs:schema">
    <jxb:globalBindings>
        <xjc:superInterface name="com.example.model.Person"/>
    </jxb:globalBindings>
    </jxb:bindings>
</jxb:bindings>