我在 maven 中有一个使用 JAXB 生成的源的多模块项目:
parent
module A
module B (depends on module A)
如果没有 JAXB,一切都可以正常编译。当我将 JAXB 插件添加到模块 B 时,maven 抱怨:
Failed to execute goal on project moduleB: Could not resolve dependencies for
project groupId:A:jar:1.7.0: Could not find artifact groupId:A:jar:1.7.0:
in thirdparty (http://10.0.0.2:8081/nexus/content/repositories/thirdparty)
据我所知,这是因为 jaxb maven 插件要求在编译模块 A 之前的 generate-sources 阶段解决所有依赖项。我们没有在本地存储库中安装模块 A 的机制——我们从来不需要它,因为两个模块都在同一个 git 存储库中。
我发现的丑陋解决方案是这样的:
parent
module A
module B (depends on module A & C)
module C (contains only JAXB generate-sources)
JAXB 不需要模块 A,因此一切都可以编译。这个解决方案确实有效,但它很难看。通常模块包含有用的代码,但为了将有用的代码放在模块 C 中,我必须使其依赖于导致相同错误的模块 A。(切换到不同的 JAXB 插件不起作用,因为它还在生成源阶段解决了依赖关系。)
问题:有没有办法在不创建另一个模块的情况下避免这种依赖?
(可能的解决方案可能涉及为模块 B 添加阶段或范围,更改模块 B 需要模块 A 的依赖项的范围,因此在生成源之后才需要它,或者创建排除项以便 JAXB 不查找此特别依赖。)
接下来是 pom.xml 文件的极简版本。它来自工作 pom,但我不能 100% 确定它会以现在的形式编译。
父/pom.xml:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>artFacts</artifactId>
<groupId>com.group</groupId>
<version>1.7.0</verison>
<repositories>
<repository>
<id>thirdparty</id>
<url>http://10.0.0.2:8081/nexus/content/repositories/thirdparty</url>
</repository>
</repositories>
<modules>
<module>modA</module>
<module>modB</module>
</modules>
</project>
父/a/pom.xml:
<project>
<parent>
<artifactId>artFacts</artifactId>
<groupId>com.group</groupId>
<version>1.7.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>modA</artifactId>
<packaging>jar</packaging>
</project>
父/b/pom.xml:
<project>
<parent>
<artifactId>artFacts</artifactId>
<groupId>com.group</groupId>
<version>1.7.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>modB</artifactId>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>xjc_raw</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<packageName>com.group.jaxb</packageName>
<schemaDirectory>${basedir}/xsd/</schemaDirectory>
<outputDirectory>${project.build.directory}/generated-sources/jaxb</outputDirectory>
<staleFile>${project.build.directory}/generated-sources/jaxb/.staleFlag</staleFile>
<target>2.1</target>
</configuration>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
<!-- Tell Eclipse where to find the generated sources. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/jaxb</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- This is the dependency which fails because it can't be resolved
during the generate-sources phase. -->
<dependency>
<groupId>com.group</groupId>
<artifactId>modA</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
<type>jar</type>
<optional>false</optional>
</dependency>
<dependencies>
</project>
在这种形式下,项目应该会失败并显示上面的错误消息。将其更改为丑陋的解决方案可以通过创建 modC 并将有关 JAXB 的所有内容放在那里来完成。在此之后,只需让 modB 依赖于 modA 和 modC,再加上将 modC 添加到父级即可。