我使用Jibx CodeGen maven插件从xsd文件生成Java源和绑定。我想在同一应用程序中维护xsd的多个版本,因此我计划根据XSD的版本生成不同的目标包。
JBix似乎基于xsd文件的名称空间生成Java包。
即。对于命名空间,http://www.example.jibx.org/generated/v30/types它生成包org.jibx.example.generated.v30.types
http://www.example.jibx.org/generated/v30/types
org.jibx.example.generated.v30.types
在maven构建代码生成期间,似乎可以正常工作,并且生成了绑定文件,但是在绑定阶段,它表示Verification失败:
Maven日志样本
Generating code for mapping org.jibx.example.generated.v30.bar.Bar Generating code for mapping org.jibx.example.generated.v30.bar.SpecificBar Generating code for mapping org.jibx.example.generated.v30.foo.Foo Generating code for mapping org.jibx.example.generated.v30.foo.SpecificFoo Generating code for mapping org.jibx.example.generated.v30.generic.Generic Generating code for mapping org.jibx.example.generated.v31.bar.Bar Generating code for mapping org.jibx.example.generated.v31.bar.SpecificBar Generating code for mapping org.jibx.example.generated.v31.foo.Foo Generating code for mapping org.jibx.example.generated.v31.foo.SpecificFoo Generating code for mapping org.jibx.example.generated.v31.generic.Generic Wrote 16 files org.jibx.example.generated.v30.bar.Bar output file size is 4365 bytes Verification failure on class org.jibx.example.generated.v30.bar.Bar: VERIFIED_REJECTED Repository.lookup() failed. FILE NOT FOUND? Found 10 methods: void marshal void JiBX_binding_v30_marshal_1_0 org.jibx.example.generated.v30.bar.Bar JiBX_binding_v30_newinstance_1_0 org.jibx.example.generated.v30.bar.Bar JiBX_binding_v30_unmarshal_1_0 java.lang.String JiBX_getName void setSpecific org.jibx.example.generated.v30.bar.SpecificBar getSpecific void setGeneric org.jibx.example.generated.v30.generic.Generic getGeneric void unmarshal org.jibx.example.generated.v30.bar.SpecificBar output file size is 2056 bytes Verification failure on class org.jibx.example.generated.v30.bar.SpecificBar: VERIFIED_REJECTED Repository.lookup() failed. FILE NOT FOUND? Found 6 methods: java.lang.String getLabel void JiBX_binding_v30_marshal_1_0 boolean JiBX_binding_v30_test_1_0 org.jibx.example.generated.v30.bar.SpecificBar JiBX_binding_v30_newinstance_1_0 org.jibx.example.generated.v30.bar.SpecificBar JiBX_binding_v30_unmarshal_1_0 void setLabel org.jibx.example.generated.v30.foo.Foo output file size is 4365 bytes Verification failure on class org.jibx.example.generated.v30.foo.Foo: VERIFIED_REJECTED Repository.lookup() failed. FILE NOT FOUND?
pom.xml
<properties> <junit.version>4.11</junit.version> <jibx.version>1.2.4.3</jibx.version> <jibx.codegen.version>1.2.4.3</jibx.codegen.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <build-helper-maven-plugin.version>1.9.1</build-helper-maven-plugin.version> </properties> <repositories> <repository> <id>sonatype</id> <name>Sonatype Groups</name> <url>https://oss.sonatype.org/content/groups/public/</url> </repository> </repositories> <build> <pluginManagement> <plugins> <!-- ### Target JDK 1.6 ### --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <!-- #### Cleaning up generated sources #### --> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.6.1</version> <configuration> <filesets> <fileset> <directory>src-generated/src</directory> <includes> <include>**/*</include> </includes> <followSymlinks>false</followSymlinks> </fileset> </filesets> </configuration> </plugin> <plugin> <groupId>org.jibx</groupId> <artifactId>maven-jibx-plugin</artifactId> <version>${jibx.codegen.version}</version> <configuration> <schemaLocation>src/main/config</schemaLocation> <schemaBindingDirectory>src-generated/src</schemaBindingDirectory> <baseBindingDirectory>src-generated/src</baseBindingDirectory> <targetDirectory>src-generated/src</targetDirectory> </configuration> <executions> <execution> <!-- ### Generation of binding for versions 3.0 of XSD ### --> <id>generate-java-code-from-schema-3.0</id> <phase>generate-sources</phase> <goals> <goal>schema-codegen</goal> </goals> <configuration> <schemaLocation>src/main/config</schemaLocation> <schemaBindingDirectory>src-generated/src</schemaBindingDirectory> <baseBindingDirectory>src-generated/src</baseBindingDirectory> <targetDirectory>src-generated/src</targetDirectory> <includeSchemas> <includeSchema>types-3.0.xsd</includeSchema> <includeSchema>generic-3.0.xsd</includeSchema> <includeSchema>foo-3.0.xsd</includeSchema> <includeSchema>bar-3.0.xsd</includeSchema> </includeSchemas> <options> <binding-file-name>binding-v30.xml</binding-file-name> </options> </configuration> </execution> <execution> <id>generate-java-code-from-schema-3.1</id> <phase>generate-sources</phase> <goals> <goal>schema-codegen</goal> </goals> <configuration> <schemaLocation>src/main/config</schemaLocation> <schemaBindingDirectory>src-generated/src</schemaBindingDirectory> <baseBindingDirectory>src-generated/src</baseBindingDirectory> <targetDirectory>src-generated/src</targetDirectory> <includeSchemas> <includeSchema>types-3.1.xsd</includeSchema> <includeSchema>generic-3.1.xsd</includeSchema> <includeSchema>foo-3.1.xsd</includeSchema> <includeSchema>bar-3.1.xsd</includeSchema> </includeSchemas> <options> <binding-file-name>binding-v31.xml</binding-file-name> </options> </configuration> </execution> <execution> <id>compile-binding</id> <phase>process-classes</phase> <goals> <goal>bind</goal> </goals> <configuration> <includes> <include>binding-v30.xml</include> <include>binding-v31.xml</include> </includes> <load>true</load> <validate>true</validate> <verbose>true</verbose> <verify>true</verify> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>${build-helper-maven-plugin.version}</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>src-generated/src</source> </sources> </configuration> </execution> </executions> </plugin> </plugins> </build>
foo-3.0.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.jibx.org/generated/v30/foo" xmlns="http://www.example.jibx.org/generated/v30/foo" xmlns:dgr="http://www.example.jibx.org/generated/v30/generic" xmlns:tdr="http://www.example.jibx.org/generated/v30/types" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <xs:import namespace="http://www.example.jibx.org/generated/v30/generic" schemaLocation="generic-3.0.xsd" /> <xs:import namespace="http://www.example.jibx.org/generated/v30/types" schemaLocation="types-3.0.xsd" /> <xs:element name="foo"> <xs:complexType> <xs:annotation> <xs:documentation><![CDATA[ Documentation with french accentuation : éàç]]></xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="generic" type="dgr:generic" /> <xs:element name="specific" type="specificFoo" /> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="specificFoo"> <xs:sequence> <xs:element name="label" type="label"> <xs:annotation> <xs:documentation>Label for Foo</xs:documentation> </xs:annotation> </xs:element> <xs:element name="dateFoo" type="tdr:dateDDMMYYYY" minOccurs="0"> <xs:annotation> <xs:documentation>Date of Foo</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> <xs:simpleType name="label"> <xs:restriction base="xs:string"> <xs:minLength value="2" /> <xs:maxLength value="255" /> </xs:restriction> </xs:simpleType> </xs:schema>
通用3.0.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://www.example.jibx.org/generated/v30/generic" xmlns="http://www.example.jibx.org/generated/v30/generic" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tdr="http://www.example.jibx.org/generated/v30/types" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <xs:import namespace="http://www.example.jibx.org/generated/v30/types" schemaLocation="types-3.0.xsd" /> <xs:complexType name="generic"> <xs:annotation> <xs:documentation>Generic data</xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="type" type="tdr:typeCode"> <xs:annotation> <xs:documentation>Type for code</xs:documentation> </xs:annotation> </xs:element> <xs:element name="isValid" type="xs:boolean"> <xs:annotation> <xs:documentation>Flag that tells generic data is valid</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> </xs:schema>
类型3.0.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tdr="http://www.example.jibx.org/generated/v30/types" targetNamespace="http://www.example.jibx.org/generated/v30/types" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <xs:simpleType name="text"> <xs:annotation> <xs:documentation>Text</xs:documentation> </xs:annotation> <xs:restriction base="xs:string" /> </xs:simpleType> <xs:simpleType name="typeCode"> <xs:annotation> <xs:documentation>Text</xs:documentation> </xs:annotation> <xs:restriction base="xs:string" /> </xs:simpleType> <xs:simpleType name="dateDDMMYYYY"> <xs:annotation> <xs:documentation>Date au with format : DD/MM/YYYY</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:length value="10" /> <xs:pattern value="[0-3][0-9]/[0-1][0-9]/(19|20)[0-9]{2}" /> </xs:restriction> </xs:simpleType> </xs:schema>
这是生成的绑定(binding-v30.xml)
<binding xmlns:ns1="http://www.example.jibx.org/generated/v30/bar" xmlns:ns2="http://www.example.jibx.org/generated/v30/foo" xmlns:dgr="http://www.example.jibx.org/generated/v30/generic" name="binding_v30" package="org.jibx.example.generated.v30" trim-whitespace="true"> <namespace uri="http://www.example.jibx.org/generated/v30/bar" prefix="ns1"/> <namespace uri="http://www.example.jibx.org/generated/v30/foo" prefix="ns2"/> <mapping class="org.jibx.example.generated.v30.bar.Bar" name="bar" ns="http://www.example.jibx.org/generated/v30/bar"> <structure map-as="dgr:generic" get-method="getGeneric" set-method="setGeneric" name="generic"/> <structure map-as="ns1:specificBar" get-method="getSpecific" set-method="setSpecific" name="specific"/> </mapping> <mapping abstract="true" type-name="ns1:specificBar" class="org.jibx.example.generated.v30.bar.SpecificBar"> <value style="element" name="label" get-method="getLabel" set-method="setLabel"/> </mapping> <mapping class="org.jibx.example.generated.v30.foo.Foo" name="foo" ns="http://www.example.jibx.org/generated/v30/foo"> <structure map-as="dgr:generic" get-method="getGeneric" set-method="setGeneric" name="generic"/> <structure map-as="ns2:specificFoo" get-method="getSpecific" set-method="setSpecific" name="specific"/> </mapping> <mapping abstract="true" type-name="ns2:specificFoo" class="org.jibx.example.generated.v30.foo.SpecificFoo"> <value style="element" name="label" get-method="getLabel" set-method="setLabel"/> <value style="element" name="dateFoo" get-method="getDateFoo" set-method="setDateFoo" usage="optional"/> </mapping> <mapping abstract="true" type-name="dgr:generic" class="org.jibx.example.generated.v30.generic.Generic"> <value style="element" name="type" get-method="getType" set-method="setType"/> <value style="element" name="isValid" get-method="isIsValid" set-method="setIsValid"/> </mapping> </binding>
我编写了一个Junit测试,以确保jibx可以实例化绑定对象的工厂,并针对它解组xml文件。
Junit单元测试:FooTest.java
@Test public void testFoo1() { IBindingFactory foo30Factory = null; try { foo30Factory = BindingDirectory.getFactory("binding_v30", Foo.class); } catch (JiBXException e) { String l_msg = "Cannot create factory "; LOGGER.error(l_msg, e); Assert.fail(l_msg + e.getMessage()); } IUnmarshallingContext unmarshmallingContext = null; try { unmarshmallingContext = foo30Factory.createUnmarshallingContext(); } catch (JiBXException e) { String l_msg = "Cannot create unmarshmalling context "; LOGGER.error(l_msg, e); Assert.fail(l_msg + e.getMessage()); } String l_xmlFileToTest = "/xml/foo1.xml"; LOGGER.info("Loading file : " + l_xmlFileToTest); InputStream in = this.getClass().getResourceAsStream(l_xmlFileToTest); BufferedReader buffer = new BufferedReader(new InputStreamReader(in)); Foo l_fooObtained = null; try { l_fooObtained = (Foo) unmarshmallingContext.unmarshalDocument(buffer); } catch (JiBXException e) { String l_msg = "Cannot instanciate object for class " + Foo.class; LOGGER.error(l_msg, e); Assert.fail(l_msg + e.getMessage()); } Assert.assertNotNull("l_coeaObtenu ne doit pas etre null", l_fooObtained); }
foo1.xml
<?xml version="1.0" encoding="UTF-8" ?> <foo> <generic> <type>12345</type> <isValid>1</isValid> </generic> <specific> <label>Label example</label> <dateFoo>01/01/2015</dateFoo> </specific> </foo>
我在运行它时得到了这个堆栈跟踪:元素“通用”没有解组器
ERROR FooTest - Cannot instanciate object for class class org.jibx.example.generated.v30.foo.Foo org.jibx.runtime.JiBXException: No unmarshaller for element "generic" (line 5, col 14) at org.jibx.runtime.impl.UnmarshallingContext.unmarshalElement(UnmarshallingContext.java:2754) at org.jibx.runtime.impl.UnmarshallingContext.unmarshalDocument(UnmarshallingContext.java:2914) at org.jibx.example.generated.v30.bar.FooTest.testFoo1(FooTest.java:59) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165) at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
我终于找到了答案。我想使用的xml中缺少namepace声明。它可以与以下形状正确的形状一起使用:
<?xml version="1.0" encoding="UTF-8" ?> <foo:foo xmlns:foo="http://www.example.jibx.org/generated/v30/foo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.jibx.org/generated/v30/foo foo-3.0.xsd"> <generic> <type>12345</type> <isValid>1</isValid> </generic> <specific> <label>Label example</label> <dateFoo>01/01/2015</dateFoo> </specific> </foo:foo>