Maven Jaxb Generate在编译依赖于多个模块的模块时失败

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

我有一个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\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工件解析在某些情况下无法正常工作的原因

在0.10.0版本中,我为JAXB-1044和JAXB-1045实现了变通方法。我将尝试通过pull请求将我的补丁程序发送到XJC,但您知道,我不确定Oracle人员何时/是否会接受我的PRs

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
    。(在
    w3c模式
    jar中有一个
    /w3c/1999/xlink.xsd
    资源)
  • 然后,通过Maven目录解析器(通过
    Maven-jaxb2-plugin
    )将该systemId解析为“真实”URL,该URL将是一些
    jar:…
    URL,指向本地存储库中
    w3c模式
    工件jar中的资源
  • 因此,模式不是从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>