Java 从XJC输出中省略@xmlsee

Java 从XJC输出中省略@xmlsee,java,jaxb,xjc,Java,Jaxb,Xjc,目前我正忙于一个使用XML消息传递的项目。我有一个通用模式,带有抽象类型和一些可重用的类型定义和元素。对于我正在处理的每一种消息,都有一个单独的模式(具有不同的目标命名空间)来导入通用模式。换句话说,它是一个两级层次结构。很简单 每个模式都用于生成Java类。每个模式对应一个包。代码生成由Maven JAXB 2.1插件处理。在使用代码时,我为每种消息类型创建一个单独的JAXBContext。JAXBContext是使用通用模式和特定消息类型的包名创建的,因此上下文应该只看到它必须处理的类 令我

目前我正忙于一个使用XML消息传递的项目。我有一个通用模式,带有抽象类型和一些可重用的类型定义和元素。对于我正在处理的每一种消息,都有一个单独的模式(具有不同的目标命名空间)来导入通用模式。换句话说,它是一个两级层次结构。很简单

每个模式都用于生成Java类。每个模式对应一个包。代码生成由Maven JAXB 2.1插件处理。在使用代码时,我为每种消息类型创建一个单独的
JAXBContext
JAXBContext
是使用通用模式和特定消息类型的包名创建的,因此上下文应该只看到它必须处理的类

令我惊讶的是,我注意到,当我将XML文档解组为bean,然后将它们封送回XML时,每个消息类型(=模式目标名称空间)都有名称空间声明。不知道JAXB是如何在上下文范围之外获得这些信息的,我发现一些
@xmlseea
注释放在一些抽象类定义上。这会导致JAXB查找有关目标包之外的类的信息

有没有办法避免生成
@xmlseeals
注释?环顾这里,我发现这是JAXB2.1的新功能。我可以切换到2.0版本的XJC插件,但我不确定这是否会产生不必要的副作用。另外,我希望以后继续关注新的JAXB版本。不需要的名称空间声明不是问题(XML仍然有效),但一旦添加更多的消息类型,就会造成混乱。而且,这也清楚地表明,我的JAXB上下文加载的类比我想象的要多,并且基本上是彼此的重复。我可以使用一个包含所有内容的上下文,但我有一个围绕这个分离构建的API


感谢阅读和提供的任何答案。

我也有同样的问题,我认为没有一个简单的答案。我找到了com.sun.tools.xjc.generator.bean.BeangGenerator类的源代码,该类似乎负责生成java源代码(jaxb-xjc-2.1.4.jar)。从第496行开始的代码如下所示:

     if(model.options.target.isLaterThan(SpecVersion.V2_1)) {
        // @XmlSeeAlso
        Iterator<CClassInfo> subclasses = cc.target.listSubclasses();
        if(subclasses.hasNext()) {
            XmlSeeAlsoWriter saw = cc.implClass.annotate2(XmlSeeAlsoWriter.class);
            while (subclasses.hasNext()) {
                CClassInfo s = subclasses.next();
                saw.value(getClazz(s).implRef);
            }
        }
    }
if(model.options.target.isLaterThan(SpecVersion.V2_1)){
//@xmlseewall
迭代器子类=cc.target.ListSubclass();
if(子类.hasNext()){
xmlsealsowriter saw=cc.implClass.annotate2(xmlsealsowriter.class);
while(子类.hasNext()){
cclassinfos=子类.next();
锯值(getClazz.implRef);
}
}
}

XMLSeeAllow注释似乎是硬编码的,不是可选的或可配置的(至少在JAXB 2.1.4中是这样)。

使用父模式和子模式的单独编译

如果单独编译父模式(不包括上下文中的子模式),
@xmlsee也
注释和
{@link ChildType}
将仅引用该模式中的JAXB类及其父模式。这实现了父/子模式的清晰分离

使用maven-jaxb2-plugin,可以通过限制包含的模式来实现这一点。假设您在src/xsd文件夹中有模式A.xsd和B.xsd,其中B.xsd导入具有不同名称空间的A.xsd。要仅生成父级(A.xsd),请使用以下配置:

<plugin>
  <groupId>org.jvnet.jaxb2.maven2</groupId>
  <artifactId>maven-jaxb2-plugin</artifactId>
  <version>0.8.2</version>
  <executions>
    <execution>
      <goals>
        <goal>generate</goal>
      </goals>
      <configuration>
        <schemaDirectory>${project.basedir}/src/xsd</schemaDirectory>
        <schemaIncludes>
          <include>A.xsd</include>
        </schemaIncludes>
        <episode>true</episode>
      </configuration>
    </execution>
  </executions>
</plugin>

org.jvnet.jaxb2.maven2

或者,当您生成子模式时(同样,对每个模式使用单独的编译),如果您不想这样做,您可以删除父包。您可以使用maven clean插件或maven antrun插件删除额外的父包以生成子包。我在剧集中遇到了一些麻烦-为孩子们生成了一个额外的
ObjectFactory
类-所以我用这种方式来实现我想要的结构


另一个需要注意的是
JAXBElementThanks!这对我来说已经足够确认没有关闭它的选项。也许有些实现可以做到这一点,但我希望保持JAXB代码实现的独立性。我在代码中添加了一个系统属性标志,允许您始终使用共享JAXB上下文(它知道捆绑包中生成的所有类)。至于多余的名称空间声明,我会找到解决方法。检查源代码的荣誉。极好的帖子。碰巧,我需要一些设置,由于架构的原因,需要单独编译父模式,这实际上解决了问题,正如您所说的。我通过在maven构建中排除多余的对象工厂来处理它们。不过,为了让一切正常工作,我们不得不使用自定义目录解析器做一些令人讨厌的事情。我将保留原始答案,因为这是一个解决方案,并且该解决方案确认没有关闭此选项的选项。但这是当之无愧的投票,希望这对任何有同样问题的人来说都能派上用场。