Java 使用XJC或xmlBeans生成代理类失败
我正在尝试使用XJC2.2.4-2和插曲文件生成代理类。最初使用amazon.xsd生成的插曲效果良好,但是后续使用该插曲的请求失败 我还尝试了xmlbeansJava 使用XJC或xmlBeans生成代理类失败,java,jaxb,xjc,amazon-mws,Java,Jaxb,Xjc,Amazon Mws,我正在尝试使用XJC2.2.4-2和插曲文件生成代理类。最初使用amazon.xsd生成的插曲效果良好,但是后续使用该插曲的请求失败 我还尝试了xmlbeansscomp命令,但也失败了 我正在运行的命令是: xjc.exe-extension-b amazon.com.base.xsd 及 scomp-src amazonggeneratedclasses-out feedsApi.jar newnew是一个包含所有xsd文件的目录 哪些产出: [XJC] 第60行: <jaxb:bi
scomp
命令,但也失败了
我正在运行的命令是:
xjc.exe-extension-b amazon.com.base.xsd
及
scomp-src amazonggeneratedclasses-out feedsApi.jar new
new是一个包含所有xsd文件的目录
哪些产出:
[XJC]
第60行:
<jaxb:bindings scd="Amazon-Vendor-Only">
<jaxb:class ref="amazon.AmazonVendorOnly"/>
</jaxb:bindings>
不幸的是,XSD文件都被标记为机密文件,因此我无法在这里共享它们的内容。也就是说,如果有人有任何预感、建议甚至是方向,请分享 这可能是答案,也可能不是答案,因为我不知道您的设置的确切细节,但这个问题强烈地提醒了我这一点,所以我想它可能会有所帮助。请注意,这仅适用于使用XJC的JAXB。然而,这个问题的基础实际上可能是ApacheXerces和/或其JRE等价物中的一个bug,因此您选择的绑定框架可能不会有什么不同。我对JRE Xerces fork和最新的Xerces版本都有问题,因此切换XML API实现对我也没有任何帮助 我有一个Maven项目,它非常简单地包含一个主模式、一些主模式包含的其他模式(相同的名称空间)和一个绑定文件。然后,我有许多其他的Maven项目,每个项目都有自己的模式来导入主项目(不同的名称空间)。由于主模式及其包含的JAXB实体已经由第一个Maven项目生成,因此我也希望使用一个插曲文件来确保其他项目只是扩展它,而不是重新生成代码。这将允许我分发单独的罐子 以下是第一个主要项目的Maven pom(Maven 3):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>acme.xml</groupId>
<artifactId>acme-xml-main</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>Acme XML main models</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<outputDirectory>${basedir}/target/classes-${compilerTarget}</outputDirectory>
<testOutputDirectory>${basedir}/target/test-classes-${compilerTarget}</testOutputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<excludes>
<!-- Filtering out any svn folders -->
<exclude>**/.svn</exclude>
<!-- Filtering out JAXB binding files -->
<exclude>**/*.xjb</exclude>
<!-- Filtering out XML catalogs -->
<exclude>**/*.cat</exclude>
</excludes>
</resource>
</resources>
<!-- First we need to generate Java source files based on the schemas -->
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb21-plugin</artifactId>
<version>0.8.0</version>
<executions>
<execution>
<id>xjc-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>${basedir}/src/main/resources/acme/schemas</schemaDirectory>
<schemaLanguage>XMLSCHEMA</schemaLanguage>
<addCompileSourceRoot>true</addCompileSourceRoot>
<episode>true</episode>
<removeOldOutput>true</removeOldOutput>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
<configuration>
<target>1.6</target>
<encoding>${project.build.sourceEncoding}</encoding>
<optimize>true</optimize>
<source>1.6</source>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
</plugin>
</plugins>
</build>
</project>
您可以看到上面第二个Maven pom中引用的catalog.cat。
我尝试了一整套不同的系统ID方法,但不管我做了什么,在类路径上解析模式似乎都不起作用。因此,我转而创建一个自定义目录解析器来为我处理这个问题。这是一个Java类,我与主模式/JAXB模型jar文件一起打包。我在第一个Maven pom中添加了这个依赖项
<dependency>
<groupId>com.sun.org.apache.xml.internal</groupId>
<artifactId>resolver</artifactId>
<version>20050927</version>
<scope>provided</scope>
</dependency>
com.sun.org.apache.xml.internal
分解器
20050927
假如
。。。并创建了一个自定义目录解析器,它总是将某些系统ID和主命名空间URI链接到我的主架构
然后,我将第二个Maven pom的XJC生成配置调整为:
<!-- First we need to generate Java source files based on the schemas -->
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb21-plugin</artifactId>
<version>0.8.2</version>
<!-- Need this dependency for the custom catalog resolver -->
<dependencies>
<dependency>
<groupId>acme.xml</groupId>
<artifactId>acme-xml-main</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<executions>
<execution>
<id>xjc-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- The extension flag needs to be on in order to use the episode file -->
<args>
<arg>-extension</arg>
</args>
<schemaDirectory>${basedir}/src/main/resources/acme/sub/schemas</schemaDirectory>
<schemaLanguage>XMLSCHEMA</schemaLanguage>
<addCompileSourceRoot>true</addCompileSourceRoot>
<!-- No need to generate an episode for this compilation... -->
<episode>false</episode>
<!-- The catalog makes sure we can resolve the main schema -->
<catalog>${basedir}/src/main/resources/acme/sub/schemas/catalog.cat</catalog>
<catalogResolver>acme.xml.tools.AcmeCatalogResolver</catalogResolver>
<!-- Using the episode file from the general model bundle -->
<episodes>
<episode>
<groupId>acme.xml</groupId>
<artifactId>acme-xml-main</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</episode>
</episodes>
<removeOldOutput>true</removeOldOutput>
</configuration>
</execution>
</executions>
</plugin>
org.jvnet.jaxb2.maven2
maven-jaxb21-plugin
0.8.2
acme.xml
AcmeXMLMain
1.0.0
编译
xjc生成
生成
-延伸
${basedir}/src/main/resources/acme/sub/schemas
XMLSCHEMA
真的
假的
${basedir}/src/main/resources/acme/sub/schemas/catalog.cat
acme.xml.tools.AcmeCatalogResolver
acme.xml
AcmeXMLMain
1.0.0
编译
真的
有了这一点,以及目录解析器的一些控制台输出来了解发生了什么,最终可以从类路径解析主模式。但事情还没有完全准备好
每当我在主模式中使用include时,为了确保它可以在不同的文件和组定义中被分解,我会发现XML处理器抱怨重复的定义。似乎各种文件将通过不同的路径(一些系统ID、其他名称空间、一些完整路径、其他相对路径…)进行解析,这似乎会导致问题。尽管这些不同的路径指向本质上相同的文件,但从中加载的任何内容都将被XML处理器视为单独的定义。XML验证API似乎并不擅长创建一个连贯的模式对象,只是不断地查找内容,没有意识到它正在通过不同的路径查看同一个文件
因此,我向自定义目录解析器添加了更多内容,以确保始终以相同的方式处理包含的文件。下面是生成的类:
package acme.xml.tools;
import com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.InputSource;
public class AcmeCatalogResolver extends CatalogResolver {
private final static String namespace = "http://www.acme.com";
private final static Set<String> systemIDs;
static {
final Set<String> temp = new HashSet<String>();
temp.add("main.xsd");
temp.add("Main.xsd");
temp.add("MAIN.xsd");
systemIDs = Collections.unmodifiableSet(temp);
}
@Override
public InputSource resolveEntity(String publicId, String systemId) {
//If the public ID is the main namespace, get the input source
//based on the system ID
if(publicId != null && publicId.trim().equals(namespace)) {
final InputSource source = getInputSource(systemId);
source.setPublicId(publicId);
return source;
}
//Otherwise, check if the system ID is one of the allowed references
//to the main schema and return that
if(systemId != null && systemIDs.contains(systemId.trim())) {
final InputSource source = getMainSchemaInputSource();
source.setPublicId(publicId);
return source;
}
//Still nothing: check for file or jar URIs to the main schema
if(systemId != null && (systemId.startsWith("file:") ||
systemId.startsWith("jar:"))) {
boolean match = false;
for(final String id : systemIDs) {
match = systemId.endsWith(id);
if(match)
break;
}
if(match) {
final InputSource source = getMainSchemaInputSource();
source.setPublicId(publicId);
return source;
}
}
//Final option: use only the system ID to find the source
if(systemId != null && !systemId.isEmpty()) {
final InputSource source = getInputSource(systemId);
source.setPublicId(publicId);
return source;
}
//This should not be necessary, but just in case...
return super.resolveEntity(publicId, systemId);
}
@Override
public Source resolve(String href, String base) throws TransformerException {
if(href != null && href.trim().equals(namespace)) {
final StreamSource source = getMainSchemaSource();
source.setPublicId(href);
return getMainSchemaSource();
}
return super.resolve(href, base);
}
@Override
public String getResolvedEntity(String string, String string1) {
return super.getResolvedEntity(string, string1);
}
private InputSource getInputSource(String systemId) {
final int lastSlash = systemId.lastIndexOf('/');
if(lastSlash >= 0)
systemId = systemId.substring(lastSlash + 1);
final int lastBackSlash = systemId.lastIndexOf('\\');
if(lastBackSlash >= 0)
systemId = systemId.substring(lastBackSlash + 1);
final URL url =
this.getClass().getResource("/acme/schemas/" + systemId);
final InputStream stream =
this.getClass().getResourceAsStream("/acme/schemas/" + systemId);
final InputSource source = new InputSource(stream);
source.setSystemId(url.toString());
return source;
}
private InputSource getMainSchemaInputSource() {
final URL url =
this.getClass().getResource("/acme/schemas/main.xsd");
final InputStream stream =
this.getClass().getResourceAsStream("/acme/schemas/main.xsd");
final InputSource source = new InputSource(stream);
source.setSystemId(url.toString());
return source;
}
private StreamSource getGeneralSchemaSource() {
final URL url =
this.getClass().getResource("/acme/schemas/main.xsd");
final InputStream stream =
this.getClass().getResourceAsStream("/acme/schemas/main.xsd");
final StreamSource source = new StreamSource(stream);
source.setSystemId(url.toString());
return source;
}
}
package acme.xml.tools;
导入com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver;
导入java.io.InputStream;
导入java.net.URL;
导入java.util.Collections;
导入java.util.HashSet;
导入java.util.Set;
导入javax.xml.transform.Source;
导入javax.xml.transform.TransformerException;
导入javax.xml.transform.stream.StreamSource;
导入org.xml.sax.InputSource;
公共类AcmeCatalogResolver扩展了CatalogResolver{
私有最终静态字符串命名空间=”http://www.acme.com";
私有最终静态集SystemID;
静止的{
最终设置温度=新的HashSet();
临时添加(“main.xsd”);
临时添加(“Main.xsd”);
临时添加(“MAIN.xsd”);
SystemId=集合。不可修改集(临时);
}
@凌驾
public InputSource resolveEntity(字符串publicId、字符串systemId){
//如果public ID是主名称空间,则获取输入源
//基于系统ID
if(publicId!=null&&publicId.trim().equals(命名空间)){
最终输入源=getInputSource(系统ID);
source.setPublicId(publicId);
返回源;
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>acme.xml</groupId>
<artifactId>acme-xml-sub</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>Acme XML sub models</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>acme.xml</groupId>
<artifactId>acme-xml-main</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<outputDirectory>${basedir}/target/classes-${compilerTarget}</outputDirectory>
<testOutputDirectory>${basedir}/target/test-classes-${compilerTarget}</testOutputDirectory>
<!-- Resources to include into the packaged build -->
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<excludes>
<!-- Filtering out any svn folders -->
<exclude>**/.svn</exclude>
<!-- Filtering out JAXB binding files -->
<exclude>**/*.xjb</exclude>
<!-- Filtering out XML catalogs -->
<exclude>**/*.cat</exclude>
</excludes>
</resource>
</resources>
<plugins>
<!-- First we need to generate Java source files based on the schemas -->
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb21-plugin</artifactId>
<version>0.8.2</version>
<executions>
<execution>
<id>xjc-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- The extension flag needs to be on in order to use the episode file -->
<args>
<arg>-extension</arg>
</args>
<schemaDirectory>${basedir}/src/main/resources/acme/sub/schemas</schemaDirectory>
<schemaLanguage>XMLSCHEMA</schemaLanguage>
<addCompileSourceRoot>true</addCompileSourceRoot>
<!-- No need to generate an episode for this compilation... -->
<episode>false</episode>
<!-- The catalog makes sure we can resolve the main schema -->
<catalog>${basedir}/src/main/resources/acme/sub/schemas/catalog.cat</catalog>
<!-- Using the episode file from the main model jar -->
<episodes>
<episode>
<groupId>acme.xml</groupId>
<artifactId>acme-xml-main</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</episode>
</episodes>
<removeOldOutput>true</removeOldOutput>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
<configuration>
<target>1.6</target>
<encoding>${project.build.sourceEncoding}</encoding>
<optimize>true</optimize>
<excludes>
<!-- This exclude avoids compiling the ObjectFactory class that -->
<!-- XJC insists on generating for the default package name of the main -->
<!-- namespace. Please leave this in to avoid any trouble. -->
<exclude>**/acme/main/ObjectFactory.java</exclude>
</excludes>
<source>1.6</source>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
</plugin>
</plugins>
</build>
</project>
--
Resolving the main XML Schema system ID.
--
SYSTEM "main.xsd" "classpath:/acme/schemas/main.xsd"
--
Resolving the main namespace to the corresponding schema file.
--
PUBLIC "http://www.acme.com" "classpath:/acme/schemas/main.xsd"
<dependency>
<groupId>com.sun.org.apache.xml.internal</groupId>
<artifactId>resolver</artifactId>
<version>20050927</version>
<scope>provided</scope>
</dependency>
<!-- First we need to generate Java source files based on the schemas -->
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb21-plugin</artifactId>
<version>0.8.2</version>
<!-- Need this dependency for the custom catalog resolver -->
<dependencies>
<dependency>
<groupId>acme.xml</groupId>
<artifactId>acme-xml-main</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<executions>
<execution>
<id>xjc-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- The extension flag needs to be on in order to use the episode file -->
<args>
<arg>-extension</arg>
</args>
<schemaDirectory>${basedir}/src/main/resources/acme/sub/schemas</schemaDirectory>
<schemaLanguage>XMLSCHEMA</schemaLanguage>
<addCompileSourceRoot>true</addCompileSourceRoot>
<!-- No need to generate an episode for this compilation... -->
<episode>false</episode>
<!-- The catalog makes sure we can resolve the main schema -->
<catalog>${basedir}/src/main/resources/acme/sub/schemas/catalog.cat</catalog>
<catalogResolver>acme.xml.tools.AcmeCatalogResolver</catalogResolver>
<!-- Using the episode file from the general model bundle -->
<episodes>
<episode>
<groupId>acme.xml</groupId>
<artifactId>acme-xml-main</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</episode>
</episodes>
<removeOldOutput>true</removeOldOutput>
</configuration>
</execution>
</executions>
</plugin>
package acme.xml.tools;
import com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.InputSource;
public class AcmeCatalogResolver extends CatalogResolver {
private final static String namespace = "http://www.acme.com";
private final static Set<String> systemIDs;
static {
final Set<String> temp = new HashSet<String>();
temp.add("main.xsd");
temp.add("Main.xsd");
temp.add("MAIN.xsd");
systemIDs = Collections.unmodifiableSet(temp);
}
@Override
public InputSource resolveEntity(String publicId, String systemId) {
//If the public ID is the main namespace, get the input source
//based on the system ID
if(publicId != null && publicId.trim().equals(namespace)) {
final InputSource source = getInputSource(systemId);
source.setPublicId(publicId);
return source;
}
//Otherwise, check if the system ID is one of the allowed references
//to the main schema and return that
if(systemId != null && systemIDs.contains(systemId.trim())) {
final InputSource source = getMainSchemaInputSource();
source.setPublicId(publicId);
return source;
}
//Still nothing: check for file or jar URIs to the main schema
if(systemId != null && (systemId.startsWith("file:") ||
systemId.startsWith("jar:"))) {
boolean match = false;
for(final String id : systemIDs) {
match = systemId.endsWith(id);
if(match)
break;
}
if(match) {
final InputSource source = getMainSchemaInputSource();
source.setPublicId(publicId);
return source;
}
}
//Final option: use only the system ID to find the source
if(systemId != null && !systemId.isEmpty()) {
final InputSource source = getInputSource(systemId);
source.setPublicId(publicId);
return source;
}
//This should not be necessary, but just in case...
return super.resolveEntity(publicId, systemId);
}
@Override
public Source resolve(String href, String base) throws TransformerException {
if(href != null && href.trim().equals(namespace)) {
final StreamSource source = getMainSchemaSource();
source.setPublicId(href);
return getMainSchemaSource();
}
return super.resolve(href, base);
}
@Override
public String getResolvedEntity(String string, String string1) {
return super.getResolvedEntity(string, string1);
}
private InputSource getInputSource(String systemId) {
final int lastSlash = systemId.lastIndexOf('/');
if(lastSlash >= 0)
systemId = systemId.substring(lastSlash + 1);
final int lastBackSlash = systemId.lastIndexOf('\\');
if(lastBackSlash >= 0)
systemId = systemId.substring(lastBackSlash + 1);
final URL url =
this.getClass().getResource("/acme/schemas/" + systemId);
final InputStream stream =
this.getClass().getResourceAsStream("/acme/schemas/" + systemId);
final InputSource source = new InputSource(stream);
source.setSystemId(url.toString());
return source;
}
private InputSource getMainSchemaInputSource() {
final URL url =
this.getClass().getResource("/acme/schemas/main.xsd");
final InputStream stream =
this.getClass().getResourceAsStream("/acme/schemas/main.xsd");
final InputSource source = new InputSource(stream);
source.setSystemId(url.toString());
return source;
}
private StreamSource getGeneralSchemaSource() {
final URL url =
this.getClass().getResource("/acme/schemas/main.xsd");
final InputStream stream =
this.getClass().getResourceAsStream("/acme/schemas/main.xsd");
final StreamSource source = new StreamSource(stream);
source.setSystemId(url.toString());
return source;
}
}