【问题标题】:Dealing with duplicate classes with multiple maven-jaxb2-plugin executions using different schemas with the same base schema使用具有相同基本模式的不同模式处理具有多个 maven-jaxb2-plugin 执行的重复类
【发布时间】:2022-01-20 19:10:44
【问题描述】:

我目前正在使用 maven-jaxb2-plugin v0.13.3。

插件配置有多个执行,每个处理 wsdl 文件。其中有几个是完全独立的,但有几个只是同一企业中的不同 wsdl,其架构导入了一个通用的基本架构。

请注意,我无法更改 wsdls 或架构。

原始代码使用“forceRegenerate”设置为 true,同时它们都写入同一个目标目录。这适用于命令行构建,但正如许多人现在所知,这会导致 Eclipse 中的无限构建循环。

我正在逐步解决这个问题。简单的步骤是将“forceRegenerate”设置为 false,并将后缀目录添加到每次执行的“generateDirectory”目录中,以使其唯一。然后,我必须更改 Eclipse 项目属性,以删除它们都写入的公共位置的原始源目录,并将其替换为每个现在唯一的源目录的单个 ref。

到目前为止,如果所有执行都引用完全独立的模式,这将可以正常工作。

如果这些执行中的两个或多个指定了一个 wsdl,该 wsdl 具有引用公共基本模式的模式,这里就是这种情况,我会在构建时遇到重复的类错误。

如果有帮助,这里有一些来自 pom 的示例代码,但有些省略:

<execution>
  <id>unifiedServices</id>
  <goals>
    <goal>generate</goal>
  </goals>
  <configuration>
    <specVersion>2.2</specVersion>
    <schemaDirectory>src/main/resources/schemas/csi_UnifiedServices_240.0_schema</schemaDirectory>
    <schemaIncludes>
      <include>*.wsdl</include>
    </schemaIncludes>
    <generateDirectory>target/generated-sources/jaxb/us</generateDirectory>
    <forceRegenerate>false</forceRegenerate>
  </configuration>
</execution>
<execution>
  <id>iuclp</id>
  <goals>
    <goal>generate</goal>
  </goals>
  <configuration>
    <specVersion>2.2</specVersion>
    <schemaDirectory>src/main/resources/schemas/csi_OrderAndSubscriptionManagementMobility</schemaDirectory>
    <schemaIncludes>
      <include>*.wsdl</include>
    </schemaIncludes>
    <generateDirectory>target/generated-sources/jaxb/osmm</generateDirectory>
    <forceRegenerate>false</forceRegenerate>
  </configuration>
</execution>

我看到很多帖子都在讨论这个的变体,其中很多都是指旧版本的插件。

有哪些实用的解决方案仍然可以满足我的限制(不能修改 wsdl/schema)?

更新

我正在按照第一个答案中的建议实施绑定文件。它不太工作,我不确定我做错了什么。

这是第一次执行的配置块(我只更改了一个执行块,一旦确定它正在生成合理的代码,我将处理其他执行块,然后更改代码中的引用)。

<configuration>
    <bindingDirectory>src/main/resources/bindings</bindingDirectory>
    <bindingIncludes>
        <bindingInclude>unifiedservices.xjb</bindingInclude>
    </bindingIncludes>
  <specVersion>2.2</specVersion>
  <schemaDirectory>src/main/resources/schemas/csi_UnifiedServices_240.0_schema</schemaDirectory>
  <schemaIncludes>
    <include>*.wsdl</include>
  </schemaIncludes>
  <generateDirectory>target/generated-sources/jaxb/us</generateDirectory>
  <forceRegenerate>false</forceRegenerate>
</configuration>

这是略微省略的绑定文件 (unifiedservices.xjb):

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2000/10/XMLSchema-instance"
    xs:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
    jxb:version="2.0">
    <jxb:bindings schemaLocation="http://.../Namespaces/UnifiedServices/Types/Public/CommonDataModel.xsd"
                  node="/xs:schema">
        <jxb:schemaBindings>
            <nameXmlTransform>
                <typeName suffix="us"/>
            </nameXmlTransform>
        </jxb:schemaBindings>
    </jxb:bindings>
</jxb:bindings>

这是略微省略的“CommonDataModel.xsd”的标题:

<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
 xmlns='http://.../Namespaces/UnifiedServices/Types/Public/CommonDataModel.xsd'
 targetNamespace='http://.../Namespaces/UnifiedServices/Types/Public/CommonDataModel.xsd'
 elementFormDefault='qualified'
 version='240.0.03'>

当我运行这个构建时,我得到了第一个错误:

[ERROR] Error while parsing schema(s).Location [ file:/C:/.../src/main/resources/bindings/unifiedservices.xjb{8,37}].
com.sun.istack.SAXParseException2: "http://.../Namespaces/UnifiedServices/Types/Public/CommonDataModel.xsd" is not a part of this compilation. Is this a mistake for "file:/C:/.../src/main/resources/schemas/csi_UnifiedServices_240.0_schema/CommonDataModel.xsd"?

更新

我更新了绑定文件,因此“schemaLocation”只是相关架构文件的相对路径,但现在我得到了一个不同的错误。

这是我的新绑定文件:

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2000/10/XMLSchema-instance"
    xs:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
    jxb:version="2.0">
    <jxb:bindings schemaLocation="../schemas/csi_UnifiedServices_240.0_schema/CommonDataModel.xsd"
                  node="/xs:schema">
        <jxb:schemaBindings>
            <nameXmlTransform>
                <typeName suffix="us"/>
            </nameXmlTransform>
        </jxb:schemaBindings>
    </jxb:bindings>
</jxb:bindings>

当我用这个构建时,我得到:

[ERROR] Error while parsing schema(s).Location [ file:/C:/.../src/main/resources/bindings/unifiedservices.xjb{8,37}].
com.sun.istack.SAXParseException2: XPath evaluation of "/xs:schema" results in empty target node

这是“CommonDataModel.xsd”文件的有些省略的标题:

<?xml version="1.0" encoding="UTF-8"?>
<!-- ... -->
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
 xmlns='http://.../Namespaces/UnifiedServices/Types/Public/CommonDataModel.xsd'
 targetNamespace='http://.../Namespaces/UnifiedServices/Types/Public/CommonDataModel.xsd'
 elementFormDefault='qualified'
 version='240.0.03'>

我不得不问自己这个相对路径是否正确。我想如果它是错误的,我会收到更具体的错误消息。为了稍微确认一下,我运行了 SysInternals ProcessMonitor,查看“CommonDataModel.xsd”,它们都在同一个文件中,并且都成功了。

更新

我想我找到了最后一个问题的可能原因。下面指出了一个问题:XPath evaluation in JAXB binding file results in empty target node.

所以,我确保两个“xs”命名空间是相同的。这摆脱了 xjc 错误。但是,它似乎也没有做任何事情。

我当前的绑定文件是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xs:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
    jxb:version="2.0">
    <jxb:bindings schemaLocation="../schemas/csi_UnifiedServices_240.0_schema/CommonDataModel.xsd"
                  node="/xs:schema">
        <jxb:schemaBindings>
            <jxb:nameXmlTransform>
                <jxb:typeName suffix="us"/>
            </jxb:nameXmlTransform>
        </jxb:schemaBindings>
    </jxb:bindings>
</jxb:bindings>

当我运行构建时,我看到这样的输出行块:

[INFO] --- maven-jaxb2-plugin:0.13.3:generate (unifiedServices) @ UnifiedAccountMs ---
[INFO] Sources are not up-to-date, XJC will be executed.
[INFO] Episode file [C:\...\target\generated-sources\jaxb\us\META-INF\sun-jaxb.episode] was augmented with if-exists="true" attributes.

看起来不错,但它并没有告诉我任何事情。当它最终编译时,我得到这样的错误:

[ERROR] /C:/.../target/generated-sources/jaxb/us/com/cingular/csi/csi/namespaces/unifiedservices/infrastructurecommon/types/_public/messageheader/ObjectFactory.java:[32,8] duplicate class: com.cingular.csi.csi.namespaces.unifiedservices.infrastructurecommon.types._public.messageheader.ObjectFactory

当我搜索那个 fqcn 时,我确实发现它多次出现(省略的部分是相同的):

./target/generated-sources/jaxb/ausn/com/.../namespaces/unifiedservices/infrastructurecommon/types/_public/messageheader/ObjectFactory.java
./target/generated-sources/jaxb/us/com/.../namespaces/unifiedservices/infrastructurecommon/types/_public/messageheader/ObjectFactory.java

我可能误解了“typeName”转换应该做什么,但它似乎并没有改变任何东西。无论如何,我觉得在类名后面附加一个后缀并不是我想要的。我认为更改包名更合适,但我什至无法让类型名转换做任何事情。

【问题讨论】:

    标签: java eclipse maven jaxb maven-jaxb2-plugin


    【解决方案1】:

    一种解决方案是为每次执行添加一个单独的绑定文件 (*.xjb),以生成特定的类(并避免名称冲突)。

    <configuration>
      <bindingDirectory>src/main/bindings</bindingDirectory>
      <bindingIncludes>
        <include>unifiedServices.xjb</include>
      </bindingIncludes>
    

    参见XJC documentation,但例如可以为所有类名添加后缀:

    <schemaBindings>
      <nameXmlTransform>
        <typeName suffix="_SuffixA"/>
      </nameXmlTransform>
    </schemaBindings>
    

    这样做,如果命名空间“company.com”的相同“Foo”类型是由多个 wsdl 导入的相同公共架构的一部分,那么您最终可能会得到不同的类:

    • com.company.Foo_SuffixA(在“unifiedServices”中生成)
    • com.company.Foo_SuffixB(在“iuclp”中生成)

    【讨论】:

    • 我明白了基本的想法,但是这里的各个点需要填写什么并不明显。我会用我迄今为止尝试过的内容更新帖子。
    • 您的架构位置 'jxb:bindings schemaLocation="http...' (在 xjb 文件中)是错误的,它必须是 相对 路径(基于绑定填充位置)。例如:schemaLocation="../../schemas/my-schema.xsd'。完整示例:gist.github.com/nazartm/5014497
    • 好的。我改变了它,但现在它说“XPath 评估“/xs:schema”导致空目标节点”。我会更新我所做的。
    • xs 的命名空间在您的 xjb 中与 xsd 中的不同: xmlns:xs="w3.org/2001/XMLSchema" vs xmlns:xs="w3.org/2000/10/XMLSchema-instance" => 使用其中之一xjb 文件中的 xsd !
    • 谢谢,我确实注意到了这一点。我将它们更改为在上次更新中匹配。这个过程现在基本上可以工作了,虽然我发现 ObjectFactory 类没有被映射覆盖。我正在使用 antrun 插件来删除重复的插件,这是我从关于同一主题的另一篇帖子中获得的。我还注意到映射处理的所谓重复类中存在一些奇怪的差异。 CODE 确实是相同的,但我注意到生成的 cmets 中存在一些奇怪的差异,这些差异显示了它们源自的架构。我必须在那里做更多的分析。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多