Maven Jaxb Generate在编译依赖于多个模块的模块时失败
我有一个EclipseMaven项目,它由多个模块组成,其中一些模块包含我想要为其生成类的Xml模式(使用Jaxb)。我的项目布局如下:Maven Jaxb Generate在编译依赖于多个模块的模块时失败,maven,jaxb,build-error,xmlcatalog,jaxb-episode,Maven,Jaxb,Build Error,Xmlcatalog,Jaxb Episode,我有一个EclipseMaven项目,它由多个模块组成,其中一些模块包含我想要为其生成类的Xml模式(使用Jaxb)。我的项目布局如下: schemas\core (pom) schemas\core\types (jar) schemas\vehicle (pom) schemas\vehicle\automobile (jar) schemas\vehicle\civic (jar) 包含架构的项目包括: schemas\core\types (xsd\types.xsd) schemas
schemas\core (pom)
schemas\core\types (jar)
schemas\vehicle (pom)
schemas\vehicle\automobile (jar)
schemas\vehicle\civic (jar)
包含架构的项目包括:
schemas\core\types (xsd\types.xsd)
schemas\vehicle\automobile (xsd\automobile.xsd)
schemas\vehicle\civic (xsd\civic.xsd)
某些模块包含从其他模块导入架构的架构:
automobile.xsd imports types.xsd
civic.xsd imports types.xsd, automobile.xsd
由于模式位于不同的项目中,我使用类路径目录解析器和目录文件来解析模式的位置
汽车项目依赖于类型项目中的模式。以下是其目录文件(catalog.xml)中的条目:
由于某些原因,在尝试从automobile项目解析jar文件时,它找不到types.xsd
有人知道为什么会这样吗
多谢各位
注意-我在尝试用搭扣来让事情顺利进行,我确实找到了一种方法。如果我从pom.xml文件中删除片段,我就不会再得到错误,但是,项目civic最终会得到依赖模块中的所有类型(这是我通过使用片段来避免的)
如果要查看每个项目的完整catalog.xml和pom.xml文件,请查看以下链接:
类型:
汽车:
思域:我也有同样的问题。模式C导入B和A,B导入A。为A、works、B生成源也很好,而为C生成源时会弹出MalformedUrlException 我仍在调查错误,但解决方法是使用systemIdSuffix(Oasis spec 1.1)匹配systemId并重写它。您需要执行以下操作:
<systemSuffix systemIdSuffix="types.xsd" uri="maven:schemas.core:types!/types.xsd"/>
<systemSuffix systemIdSuffix="types.xsd" uri="maven:schemas.core:types!/types.xsd"/>
<systemSuffix systemIdSuffix="automobile.xsd" uri="maven:schemas.vehicle:automobile!/automobile.xsd"/>
从poms中的插件配置中删除“catalogResolver”元素
将“automobile”项目的目录文件的内容替换为以下内容:
<systemSuffix systemIdSuffix="types.xsd" uri="maven:schemas.core:types!/types.xsd"/>
<systemSuffix systemIdSuffix="types.xsd" uri="maven:schemas.core:types!/types.xsd"/>
<systemSuffix systemIdSuffix="automobile.xsd" uri="maven:schemas.vehicle:automobile!/automobile.xsd"/>
将“civic”项目的目录文件内容替换为以下内容:
<systemSuffix systemIdSuffix="types.xsd" uri="maven:schemas.core:types!/types.xsd"/>
<systemSuffix systemIdSuffix="types.xsd" uri="maven:schemas.core:types!/types.xsd"/>
<systemSuffix systemIdSuffix="automobile.xsd" uri="maven:schemas.vehicle:automobile!/automobile.xsd"/>
让我知道这是否对您有效。我也遇到过类似的问题。我使用了找到的示例项目 我以两种方式修改了这些项目: 1) 拥有一个包含2个名称空间和一个本地目录文件的项目。根据这一点,使用B中a的插曲制作一个项目B 2) 有一个A项目,一个B项目和一个C项目。B依赖于A,C依赖于B 在这两种情况下,我都得到了和你一样的例外。但我开始意识到在情境2中发生了什么 这是一个例外: com.sun.istack.SAXParseException2;处理“jar:file:/Users/sjaak/.m2/repository/org/tst/b-working/1.0/b-working-1.0.jar!”时引发IOException。异常:java.net.MalformedURLException:否!/符合规格 因此,在构建项目C时,它尝试解决与项目B相关的命名空间问题。我将问题追溯到com.sun.tools.xjc.reader.internalizeRableStractReferenceFinderImpl方法startElement 我使用的解决方案是修改org.jvnet.jaxb2.maven2:maven-jaxb2-plugin。我使用了他们的MavenCatalogResolver(如上所述的默认版本),并做了一个小改动,只是没有提供整个systemId:jar:file:/Users/sjaak/.m2/repository/org/tst/b-working/1.0/b-working-1.0.jar!,但是,不要使用仅提供感叹号后面的部分用于解析的模式 代码如下:
package org.jvnet.jaxb2.maven2.resolver.tools;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.MessageFormat;
import org.jvnet.jaxb2.maven2.DependencyResource;
import org.jvnet.jaxb2.maven2.DependencyResourceResolver;
import com.sun.org.apache.xml.internal.resolver.CatalogManager;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MavenCatalogResolver extends
com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver {
private final static Pattern PTRN = Pattern.compile("^jar:file:(.*).jar!(.*)$");
public static final String URI_SCHEME_MAVEN = "maven";
private final DependencyResourceResolver dependencyResourceResolver;
private final CatalogManager catalogManager;
public MavenCatalogResolver(CatalogManager catalogManager,
DependencyResourceResolver dependencyResourceResolver) {
super(catalogManager);
this.catalogManager = catalogManager;
if (dependencyResourceResolver == null) {
throw new IllegalArgumentException(
"Dependency resource resolver must not be null.");
}
this.dependencyResourceResolver = dependencyResourceResolver;
}
@Override
public String getResolvedEntity(String publicId, String systemId)
{
String result;
Matcher matcher = PTRN.matcher(systemId);
if (matcher.matches())
{
result = super.getResolvedEntity(publicId, matcher.group(2));
}
else
{
result = super.getResolvedEntity(publicId, systemId);
}
if (result == null) {
return null;
}
try {
final URI uri = new URI(result);
if (URI_SCHEME_MAVEN.equals(uri.getScheme())) {
final String schemeSpecificPart = uri.getSchemeSpecificPart();
try {
final DependencyResource dependencyResource = DependencyResource
.valueOf(schemeSpecificPart);
try {
final URL url = dependencyResourceResolver
.resolveDependencyResource(dependencyResource);
String resolved = url.toString();
return resolved;
} catch (Exception ex) {
catalogManager.debug.message(1, MessageFormat.format(
"Error resolving dependency resource [{0}].",
dependencyResource));
}
} catch (IllegalArgumentException iaex) {
catalogManager.debug.message(1, MessageFormat.format(
"Error parsing dependency descriptor [{0}].",
schemeSpecificPart));
}
return null;
} else {
return result;
}
} catch (URISyntaxException urisex) {
return result;
}
}
}
这实际上解决了我的问题。我会再调查一下。我觉得可能有一些XJC参数可以使用,或者目录XML格式提供了更多的可能性
希望有帮助。这里是
maven-jaxb2-plugin
的作者
我只有0.10.0
版本的maven-jaxb2-plugin
。此版本修复了与报告的问题相关的问题
这实际上不是maven-jaxb2-plugin
中的一个bug,而是XJC本身的一个问题(或者更好地说是几个问题):
maven-jaxb2-plugin
中,我现在已经实现了相当可靠的解决方法。请参见此处的测试项目:
这正是您想要的:通过catalog和Maven解析器将模式解析为来自另一个工件的资源。基本上,这种改写:
REWRITE_SYSTEM "http://www.ab.org" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!"
现在可以了
如果出现问题,请执行mvn-X
并检查输出,您还会在日志中看到目录解析器的语句。这可能会给你提示,什么是不起作用的
下面是另一个项目,它使用来自一个中心工件的模式、绑定和目录本身:
POM中的代码片段:
<schemas>
<schema>
<url>http://www.w3.org/1999/xlink.xsd</url>
</schema>
</schemas>
<schemaIncludes/>
<bindings>
<binding>
<dependencyResource>
<groupId>${project.groupId}</groupId>
<artifactId>w3c-schemas</artifactId>
<resource>globalBindings.xjb</resource>
<version>${project.version}</version>
</dependencyResource>
</binding>
</bindings>
<catalogs>
<catalog>
<dependencyResource>
<groupId>${project.groupId}</groupId>
<artifactId>w3c-schemas</artifactId>
<resource>catalog.cat</resource>
<version>${project.version}</version>
</dependencyResource>
</catalog>
</catalogs>
绑定:
<jaxb:bindings schemaLocation="http://www.w3.org/1999/xlink.xsd" node="/xs:schema">
<jaxb:schemaBindings>
<jaxb:package name="org.hisrc.w3c.xlink.v_1_0"/>
</jaxb:schemaBindings>
</jaxb:bindings>
那么,这一切是如何运作的:
- 模式以及目录和全局绑定存储在中心工件
中w3cschemas
- 项目希望编译URL
http://www.w3.org/1999/xlink.xsd
- 目录将此URL重写为systemId
。(在maven:org.hisrc.w3c:w3c schemas:jar:/w3c/1999/xlink.xsd
jar中有一个w3c模式
资源)/w3c/1999/xlink.xsd
- 然后,通过Maven目录解析器(通过
)将该systemId解析为“真实”URL,该URL将是一些Maven-jaxb2-plugin
URL,指向本地存储库中jar:…
工件jar中的资源w3c模式
- 因此,模式不是从Internet下载的,而是从本地资源获取的
- 该解决方案保留了“原始”SystemID,因此您可以自定义schem
REWRITE_SYSTEM "http://www.w3.org" "maven:org.hisrc.w3c:w3c-schemas:jar::!/w3c"
<jaxb:bindings schemaLocation="http://www.w3.org/1999/xlink.xsd" node="/xs:schema"> <jaxb:schemaBindings> <jaxb:package name="org.hisrc.w3c.xlink.v_1_0"/> </jaxb:schemaBindings> </jaxb:bindings>