使用JAXB和maven插件从Products.xsd生成Java类时,我收到以下警告和错误
org.xml.sax.SAXParseException; systemId: https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/amzn-base.xsd; lineNumber: 956; columnNumber: 45; Simple type "ProcessorTypeValues" was not mapped to Enum due to EnumMemberSizeCap limit. Facets count: 744, current limit: 256. You can use customization attribute "typesafeEnumMaxMembers" to extend the limit.
at com.sun.tools.xjc.reader.xmlschema.ErrorReporter.warning(ErrorReporter.java:88)
...
Error while generating code.Location [ https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/SWVG.xsd{300,40}].
org.xml.sax.SAXParseException; systemId: https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/SWVG.xsd; lineNumber: 300; columnNumber: 40; A class/interface with the same name "generated.BBFCRatingType" is already in use. Use a class customization to resolve this conflict.
在我能够解决这个问题之后,我得到了如下错误:
.../target/generated-sources/xjc/generated/Home.java:[2737,45] cannot find symbol
symbol: class Home
location: class generated.Home.ProductType
.../target/generated-sources/xjc/generated/Home.java:[2929,23] class generated.Home is already defined in package generated
我在google搜索时看到了很多关于这方面的问题,但是没有人提出适当的解决方案。
经过一天的分析问题并逐步解决问题后,我开始工作了。
我认为XSD不是很一致,它们包含多个元素声明,可以在一个普通的XSD中进行总结,一些元素的层次结构包含同名的元素。
在使用JAXB默认设置时,XSD无效,但在某些方面不符合Java约定。
一种解决方案是,将XSD保持在本地并仅注释掉冲突的部分,然后生成类。但我想使用提供的URL生成类,所以这对我不起作用。
所以我会在这里发布我的解决方案,也许它可以帮助某人:
生成是通过pom.xml中的maven-jaxb2-plugin
完成的,所以这部分读取(我的目标包被定义为com.amazon.product
,你可以把它改成你喜欢的):
<plugins>
...
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemas>
<schema>
<url>https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Product.xsd</url>
</schema>
</schemas>
</configuration>
<id>jaxb-generate-amazon</id>
</execution>
</executions>
<configuration>
<catalogResolver>org.jvnet.jaxb2.maven2.resolver.tools.ClasspathCatalogResolver</catalogResolver>
<generatePackage>com.amazon.product</generatePackage>
<generateDirectory>${project.build.directory}/generated-sources/xjc</generateDirectory>
<verbose>true</verbose>
<removeOldOutput>false</removeOldOutput>
<clearOutputDir>false</clearOutputDir>
<forceRegenerate>true</forceRegenerate>
</configuration>
</plugin>
...
<plugins>
我在资源文件夹中的bindig.xjb读取:
<bindings
xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="2.1">
<globalBindings underscoreBinding="asCharInWord" typesafeEnumMaxMembers="9000" typesafeEnumMemberName="generateName"/>
<bindings schemaLocation="https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/FoodServiceAndJanSan.xsd" node="//xsd:element[@name='ProductType']/xsd:complexType/xsd:choice/xsd:element[@name='FoodServiceAndJanSan']/xsd:complexType">
<class name="FoodServiceAndJanSanSub"/>
</bindings>
<bindings schemaLocation="https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Home.xsd" node="//xsd:element[@name='ProductType']/xsd:complexType/xsd:choice/xsd:element[@name='Home']/xsd:complexType">
<class name="HomeSub"/>
</bindings>
<bindings schemaLocation="https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/GiftCards.xsd" node="//xsd:element[@name='ProductType']/xsd:complexType/xsd:choice/xsd:element[@name='GiftCard']/xsd:complexType">
<class name="GiftCardSub"/>
</bindings>
<bindings schemaLocation="https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/MechanicalFasteners.xsd" node="//xsd:element[@name='ProductType']/xsd:complexType/xsd:choice/xsd:element[@name='MechanicalFasteners']/xsd:complexType">
<class name="MechanicalFastenersSub"/>
</bindings>
</bindings>
长枚举类型会导致警告
这只是一个警告,但它让我恼火。诸如'ProcessorTypeValues`之类的枚举具有比默认有效数256更多的条目。您可以在globalBindings中配置它:
<globalBindings ... typesafeEnumMaxMembers="1000" .../>
具有相同名称“generated.BBFCRatingType”的类/接口已在使用中。
例如,亚马逊定义了BBFCRatingType
和BBFC_Rating_Type
等元素类型。不幸的是,默认配置将为名为BBFCRatingType
的Java类生成。但是Java包中的两个类不能具有相同的名称。解决方案是告诉JAXB包含下划线:
<globalBindings ... underscoreBinding="asCharInWord" .../>
class generated.Home已经在包生成中定义
例如,Home.xsd将一个名为Home
的元素定义为ProductType
的子元素,Home
本身位于另一个元素中,也称为<bindings schemaLocation="https://images-na.ssl-images-amazon.com/images/G/01/rainier/help/xsd/release_1_9/Home.xsd" node="//xsd:element[@name='ProductType']/xsd:complexType/xsd:choice/xsd:element[@name='Home']/xsd:complexType">
<class name="HomeSub"/>
</bindings>
。问题与之前的错误相同:在一个包中具有相同名称的两个类。
我们必须给第二个类别一个不同的名字:
<bindings schemaLocation="xsd/ProductClothing.xsd">
<bindings node="//xsd:element[@name='VariationData']/xsd:complexType/xsd:sequence">
<bindings node="./xsd:element[@name='Parentage']/xsd:simpleType">
<typesafeEnumClass name="Parentage" />
</bindings>
<bindings node="./xsd:element[@name='VariationTheme']/xsd:simpleType">
<typesafeEnumClass name="VariationTheme" />
</bindings>
</bindings>
<bindings node="//xsd:element[@name='ClassificationData']/xsd:complexType/xsd:sequence">
<bindings node="./xsd:element[@name='ClothingType']/xsd:simpleType">
<typesafeEnumClass name="ClothingType" />
</bindings>
<bindings node="./xsd:element[@name='PerformanceRating']/xsd:simpleType">
<typesafeEnumClass name="PerformanceRating" />
</bindings>
<bindings node="./xsd:element[@name='CupSize']/xsd:simpleType">
<typesafeEnumClass name="CupSize" />
</bindings>
<bindings node="./xsd:element[@name='TargetGender']/xsd:simpleType">
<typesafeEnumClass name="TargetGender" />
</bindings>
<bindings node="./xsd:element[@name='WaterResistanceLevel']/xsd:simpleType">
<typesafeEnumClass name="WaterResistanceLevel" />
</bindings>
</bindings>
</bindings>
额外的想法/改进
如果你想要一些不能自动生成的枚举,要成为真正的Java枚举,你必须为每个枚举手动强制它。例如,对于ProductClothing:
repository on GitHub
我创建了一个包含所有必要绑定的qazxswpoi,以使XSD与Java一起工作。