如何使用 class 自定义来解决文件生成冲突
How to use a class customization to resolve file generating conflicts
我正在尝试使用 Maven 生成供 Spring 框架使用的 JAXB 文件,但 Maven 显示以下错误:
我知道它无法生成带有名称的文件,但我不确定如何解决这个问题。到目前为止,我访问了以下链接。 , 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>
<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>
我将以下 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;
您遇到的错误消息基本上表明您使用了两次 wsdl types
部分中的某些名称。在您的情况下,所有 <element>
标签与其相应类型具有相同的名称(定义为<complexType>
)。
示例:
<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>
这种情况很少见。
基本上有两个选项可以解决这些问题:
使用自动名称解析
<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>
该插件将通过为每个冲突的名称附加数字来解决所有命名冲突。在上面提到的 SearchFlights 的情况下,这将导致生成 SearchFlights 和 SearchFlights2。
更好的方法 是使用绑定文件提前解决所有名称冲突。绑定文件主要包含 XPATH
表达式和转换规则。
附加到 every 声明名称的绑定文件如下:
<?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>
jaxb:nameXmlTransform
还有其他选项,例如后缀和其他类型 xml 元素(如类型)的前缀。
遗憾的是我无法使用 org.jvnet.jaxb2.maven2:maven-jaxb2-plugin
(但我确信有一个工作配置)
来处理这个绑定文件
它仍然适用于 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>
如果 autoNameResolution 修复
<args>
<arg>-XautoNameResolution</arg>
</args>
不起作用,请尝试:
<args>
<arg>-B-XautoNameResolution</arg>
</args>
删除 <generatePackage></generatePackage>
标签即可解决问题。
但是,此删除的结果是您的包将从 xml 命名空间创建。例如,命名空间 example.com/xyz
将生成包 com.example.xyz
像 hamid-mohayeji 提到的那样删除 generatePackage 修复了很多情况(至少在你的 xsd 是理智的情况下)。该设置试图将所有实体放入同一个命名空间,这在非简单情况下肯定会出错。但是,省略包会使您留下从命名空间创建的包。例如 http://www.co.com/srvc/api/common 将成为包 com.co.srvc.api.common。
这可以通过添加一个简单的绑定文件来解决。在pom中配置<bindingDirectory>src/main/resources/bindings</bindingDirectory>
,在绑定目录下添加一个绑定文件something.xjb。这里需要参考个人相对于这个文件。
此文件分别为每个 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>
当您使用
jaxws-maven-plugin
maven 插件从 WSDL 生成 类 使用下面的参数来解决这个问题。
<execution>
<configuration>
<xjcArgs>
<xjcArg>-XautoNameResolution</xjcArg>
</xjcArgs>
</configuration>
</execution>
对于 xsd 到 jaxb 和使用来自 org.codehaus.mojo 的 jaxb2-maven-plugin,我遇到了同样的问题。配置下有一个 packageName 在同一个包下创建所有生成的文件导致了问题
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>target/generated-sources/jaxb</outputDirectory>
<schemaDirectory>src/main/xsd</schemaDirectory>
<schemaFiles>test.xsd</schemaFiles>
<!-- <packageName>com.example.myschema</packageName> -->
</configuration>
</plugin>
以上所有答案均无效...
但是这个:
<configuration>
<defaultOptions>
<autoNameResolution>true</autoNameResolution>
</defaultOptions>
</configuration>
<defaultOptions>
<autoNameResolution>true</autoNameResolution>
</defaultOptions>
这对我适用于 Apache CXF 插件。
我正在尝试使用 Maven 生成供 Spring 框架使用的 JAXB 文件,但 Maven 显示以下错误:
我知道它无法生成带有名称的文件,但我不确定如何解决这个问题。到目前为止,我访问了以下链接。
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>
<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>
我将以下 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;
您遇到的错误消息基本上表明您使用了两次 wsdl types
部分中的某些名称。在您的情况下,所有 <element>
标签与其相应类型具有相同的名称(定义为<complexType>
)。
示例:
<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>
这种情况很少见。
基本上有两个选项可以解决这些问题:
使用自动名称解析
<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>
该插件将通过为每个冲突的名称附加数字来解决所有命名冲突。在上面提到的 SearchFlights 的情况下,这将导致生成 SearchFlights 和 SearchFlights2。
更好的方法 是使用绑定文件提前解决所有名称冲突。绑定文件主要包含 XPATH
表达式和转换规则。
附加到 every 声明名称的绑定文件如下:
<?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>
jaxb:nameXmlTransform
还有其他选项,例如后缀和其他类型 xml 元素(如类型)的前缀。
遗憾的是我无法使用 org.jvnet.jaxb2.maven2:maven-jaxb2-plugin
(但我确信有一个工作配置)
它仍然适用于 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>
如果 autoNameResolution 修复
<args>
<arg>-XautoNameResolution</arg>
</args>
不起作用,请尝试:
<args>
<arg>-B-XautoNameResolution</arg>
</args>
删除 <generatePackage></generatePackage>
标签即可解决问题。
但是,此删除的结果是您的包将从 xml 命名空间创建。例如,命名空间 example.com/xyz
将生成包 com.example.xyz
像 hamid-mohayeji 提到的那样删除 generatePackage 修复了很多情况(至少在你的 xsd 是理智的情况下)。该设置试图将所有实体放入同一个命名空间,这在非简单情况下肯定会出错。但是,省略包会使您留下从命名空间创建的包。例如 http://www.co.com/srvc/api/common 将成为包 com.co.srvc.api.common。
这可以通过添加一个简单的绑定文件来解决。在pom中配置<bindingDirectory>src/main/resources/bindings</bindingDirectory>
,在绑定目录下添加一个绑定文件something.xjb。这里需要参考个人相对于这个文件。
此文件分别为每个 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>
当您使用
jaxws-maven-plugin
maven 插件从 WSDL 生成 类 使用下面的参数来解决这个问题。
<execution>
<configuration>
<xjcArgs>
<xjcArg>-XautoNameResolution</xjcArg>
</xjcArgs>
</configuration>
</execution>
对于 xsd 到 jaxb 和使用来自 org.codehaus.mojo 的 jaxb2-maven-plugin,我遇到了同样的问题。配置下有一个 packageName 在同一个包下创建所有生成的文件导致了问题
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>target/generated-sources/jaxb</outputDirectory>
<schemaDirectory>src/main/xsd</schemaDirectory>
<schemaFiles>test.xsd</schemaFiles>
<!-- <packageName>com.example.myschema</packageName> -->
</configuration>
</plugin>
以上所有答案均无效...
但是这个:
<configuration>
<defaultOptions>
<autoNameResolution>true</autoNameResolution>
</defaultOptions>
</configuration>
<defaultOptions>
<autoNameResolution>true</autoNameResolution>
</defaultOptions>
这对我适用于 Apache CXF 插件。