Java 如何使用类自定义来解决文件生成冲突

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35108965/
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-08-11 16:19:27  来源:igfitidea点击:

How to use a class customization to resolve file generating conflicts

javaspringmavenjaxbwsdl

提问by Daniel Newtown

I am trying to use Maven to generate JAXB files to be used by Spring framework, but Maven displays following errors:

我正在尝试使用 Maven 生成供 Spring 框架使用的 JAXB 文件,但 Maven 显示以下错误:

I understand that it is unable to generate files with the names, but I am not sure how to resolve the issue. So far, I visited following links. 1, 2, 3

我知道它无法生成带有名称的文件,但我不确定如何解决该问题。到目前为止,我访问了以下链接。1, 2, 3

org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 5; columnNumber: 39; A class/interface with the same name "hello.wsdl.SearchFlights" is already in use. Use a class customization to resolve this conflict.
....
org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 12; columnNumber: 43; (Relevant to above error) another "SearchFlights" is generated from here.
....
org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 371; columnNumber: 42; A class/interface with the same name "hello.wsdl.GetFlightDetails" is already in use. Use a class customization to resolve this conflict.
....

Maven plugin

Maven插件

    <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.4</version>
        <configuration>
            <warSourceDirectory>WebContent</warSourceDirectory>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>
        <version>0.12.3</version>
        <executions>
            <execution>
                <goals>
                    <goal>generate</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <schemaLanguage>WSDL</schemaLanguage>
            <generatePackage>hello.wsdl</generatePackage>
            <schemas>
                <schema>
                    <url>http://www5v80.elsyarres.net/service.asmx?wsdl</url>
                </schema>
            </schemas>
        </configuration>
    </plugin>

I added following package-info.javafile to the hello.wsdlpackage but it did not help.

我将以下package-info.java文件添加到hello.wsdl包中,但没有帮助。

@XmlSchema( 
    namespace = "ElsyArres.API",
    elementFormDefault = XmlNsForm.QUALIFIED) 
package hello.wsdl;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

采纳答案by jah

The error message you are facing basically states that some names in the the typessection of your wsdl are you used two times. In your case all<element>tags have the same name as their corresponding types (defined as <complexType>).

您面临的错误消息基本上表明typeswsdl 部分中的某些名称被您使用了两次。在您的情况下,所有<element>标签都具有与其对应类型相同的名称(定义为<complexType>)。

Example:

例子:

  <s:element name="SearchFlights">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="SoapMessage" type="tns:SearchFlights" />
      </s:sequence>
    </s:complexType>
  </s:element>

  <s:complexType name="SearchFlights">
    <s:complexContent mixed="false">
      <s:extension base="tns:SoapMessageBase">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Request" type="tns:SearchFlightsRequest" />
          <s:element minOccurs="0" maxOccurs="1" name="Response" type="tns:SearchFlightsResponse" />
        </s:sequence>
      </s:extension>
    </s:complexContent>
  </s:complexType>

This is quite uncommon.

这是相当罕见的。

There are basically two options to resolve these issues:

解决这些问题基本上有两种选择:

Use autoNameResolution

使用自动名称解析

 <plugin>
     <groupId>org.jvnet.jaxb2.maven2</groupId>
     <artifactId>maven-jaxb2-plugin</artifactId>
     <version>0.13.1</version>
     <executions>
         <execution>
             <goals>
                 <goal>generate</goal>
             </goals>
         </execution>
     </executions>
     <configuration>

         <args>
             <arg>-XautoNameResolution</arg>
         </args>

         <schemaLanguage>WSDL</schemaLanguage>
         <generatePackage>hello.wsdl</generatePackage>
         <schemas>
             <schema>
                 <url>http://www5v80.elsyarres.net/service.asmx?wsdl</url>
             </schema>
          </schemas>
      </configuration>
  </plugin>

The plugin will resolve all naming conflicts through appending numbers to every colliding name. In the above mentioned case of SearchFlightsthis will result in SearchFlightsand SearchFlights2being generated.

该插件将通过为每个冲突名称附加数字来解决所有命名冲突。在上面提到的SearchFlights 的情况下,这将导致 生成SearchFlightsSearchFlights2

A better waywould be to use a binding file to resolve all name conflicts in advance. Binding files mostly contain XPATHexpression and transformation rules. A binding file that appends to everydeclarations name is the following:

更好的方法是使用绑定文件提前解决所有名称冲突。绑定文件主要包含XPATH表达式和转换规则。附加到每个声明名称的绑定文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings wsdlLocation="http://www5v80.elsyarres.net/service.asmx?wsdl"
            xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1"
            xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='ElsyArres.API']">
        <jaxb:schemaBindings>
            <jaxb:nameXmlTransform>
                <jaxb:elementName suffix="Elem"/>
            </jaxb:nameXmlTransform>
        </jaxb:schemaBindings>
    </jaxws:bindings>
</jaxws:bindings>

There are other options for jaxb:nameXmlTransformlike suffixes and prepending to other kind of xml elements (like types).

对于jaxb:nameXmlTransform类似后缀和其他类型的 xml 元素(如类型),还有其他选项。

Sadly i could not get to work this binding file with the org.jvnet.jaxb2.maven2:maven-jaxb2-plugin( but i am sure there is a working configuration)

遗憾的是,我无法使用org.jvnet.jaxb2.maven2:maven-jaxb2-plugin(但我确定有一个有效的配置)

It nevertheless works with the org.codehaus.mojo:jaxws-maven-pluginand the following configuration.

尽管如此,它仍适用org.codehaus.mojo:jaxws-maven-plugin于以下配置。

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.4.1</version>
    <executions>
        <execution>
            <goals>
                <goal>wsimport</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <bindingFiles>
         <bindingFile>${basedir}/src/main/resources/bindings.xjb</bindingFile>
        </bindingFiles>
        <wsdlUrls>
            <wsdlUrl>http://www5v80.elsyarres.net/service.asmx?wsdl</wsdlUrl>
        </wsdlUrls>
        <vmArgs>
            <vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
        </vmArgs>
    </configuration>
</plugin>

回答by trunkc

If the autoNameResolution fix

如果 autoNameResolution 修复

 <args>
     <arg>-XautoNameResolution</arg>
 </args>

doesn't work, try:

不起作用,请尝试:

 <args>
     <arg>-B-XautoNameResolution</arg>
 </args>

回答by Hamid Mohayeji

Removing <generatePackage></generatePackage>tag solves the problem.

删除<generatePackage></generatePackage>标签解决了这个问题。

However, the consequence of this removal is that your packages will be created from the xml namespace. For example, the namespace example.com/xyzwill result to the package com.example.xyz

但是,此删除的结果是您的包将从 xml 命名空间创建。例如,命名空间example.com/xyz将导致包com.example.xyz

回答by thoredge

Removing generatePackage as hamid-mohayeji mentions fixes a lot of cases (at least cases where your xsds are sane). The setting tries to put all entities into the same namespace and that's bound to go wrong in non-simple cases. However omitting the package leaves you with packages created from the namespace. For example http://www.co.com/srvc/api/commonwould become package com.co.srvc.api.common.

删除 generatePackage 作为 hamid-mohayeji 提到修复了很多情况(至少在您的 xsds 正常的情况下)。该设置试图将所有实体放入同一个命名空间中,这在非简单情况下肯定会出错。但是,省略包会给您留下从命名空间创建的包。例如http://www.co.com/srvc/api/common将成为包com.co.srvc.api.common

This can be remedied by adding a simple binding file. Configure <bindingDirectory>src/main/resources/bindings</bindingDirectory>in the pom and add a binding file something.xjb to the binding directory. Here you need to refer to individual relatively to this file.

这可以通过添加一个简单的绑定文件来解决。<bindingDirectory>src/main/resources/bindings</bindingDirectory>在pom中配置,在绑定目录下添加一个绑定文件something.xjb。这里需要相对于这个文件来引用个人。

This file sets packages for each xsd-file individually:

此文件分别为每个 xsd 文件设置包:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0">

    <jaxb:bindings schemaLocation="../schemas/common.xsd">
        <jaxb:schemaBindings>
            <jaxb:package name="com.mycomp.myapp.co.common" />
        </jaxb:schemaBindings>
    </jaxb:bindings>

    ... more bindings

</jaxb:bindings>