问题描述
|
信封:Maven 2.2.1
我在svn下有两个java项目(projectA,projectB)。我的行家结构如下。
For projectA
pom.xml (contains ProjectA parent pom deFinitions)
module moduleA
module moduleB
For projectB
pom.xml (contains ProjectB parent pom deFinitions)
module moduleC
module moduleD
projectA / pom.xml和projectB / pom.xml包含两个项目都通用的通用定义,例如junit,selenium,编译器,eclipse插件。 (例如下面给出的)
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency
我应该如何创建/组织包含特定定义的组织特定项目pom,这样单个项目就不必重新创建/维护一个项目。有人可以提供一些之前已经完成的代码片段或项目吗?
编辑1:
公司/pom.xml
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>company</artifactId>
<packaging>pom</packaging>
<name>parent</name>
<version>1.0.0</version>
<build>
<defaultGoal>install</defaultGoal>
</build>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
projectA / pom.xml
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany</groupId>
<artifactId>company</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.mycompany</groupId>
<artifactId>projectA</artifactId>
<packaging>pom</packaging>
<name>projectA</name>
<version>1.0.0</version>
<modules>
<module>moduleA</module>
<build>
<defaultGoal>install</defaultGoal>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
projectA / moduleA / pom.xml
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany</groupId>
<artifactId>projectA</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.mycompany</groupId>
<artifactId>moduleA</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>moduleA</name>
<build>
<finalName>moduleA</finalName>
<defaultGoal>install</defaultGoal>
</build>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
</dependencies>
引发以下错误:
Project ID: com.mycompany:moduleA
POM Location: c:\\temp\\maven\\projectA\\moduleA\\pom.xml
Validation Messages:
[0] \'dependencies.dependency.version\' is missing for commons-lang:comm
ons-lang:jar
[1] \'dependencies.dependency.version\' is missing for javax.servlet:ser
vlet-api:jar
解决方法
如果仅是需要重用的依赖项,请创建另一个带有packaging7的项目并在其中指定依赖项。让我们将其称为
OrgDependencies
,然后将其作为依赖项包含在projectA
和projectB
中。它将从transit8ѭ项目中传递所有依赖项。
在您的示例中,在projectA中,而不是
<parent>
<groupId>com.mycompany</groupId>
<artifactId>company</artifactId>
<version>1.0.0</version>
</parent>
试穿
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>company</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
并从模块中删除对commons-lang等的依赖。
更新。
虽然我以前的带有传递依赖项的解决方案应该可以工作,但实际上您需要什么
是您公司范围内pom.xml中的“ 14”部分
这就是您定义版本的地方。
注意:dependencyManagement
节中的任何内容实际上都不是依赖项,而只是一个描述符,用于在正常的ѭ16transit节中指定该依赖项的情况下指定版本并排除可传递的依赖项(如有必要)。因此,您可以根据需要在dependencyManagement
中放置任意数量的项,这不会使所有后代都依赖它们。
我测试了它,它的工作原理是:
<?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/xsd/maven-4.0.0.xsd\">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>company</artifactId>
<packaging>pom</packaging>
<name>parent</name>
<version>1.0.0</version>
<build>
<defaultGoal>install</defaultGoal>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
, 我会认真考虑重新将依赖项添加到“超级” POM中,这不必要地耦合了项目(但可能暗示如果项目不是完全不同的,则无论如何都应合并它们)。
我认为@lexicore的最后评论也很刺耳,就OOP类推而言,它也感觉像是“抽象的混合层次”。
Alex Gitelman提供了正确的答案,您需要使用dependencyManagement,如下所示。Dependency Scope
Maven3应该支持POM片段,请参阅如何使用Maven 3 mixins?我一直在等待。
我们有一个组织ÜberPOM,但这仅包含:
<organization>
<name>...</name>
<url>...</url>
</organization>
<developers>
<developer>
<id>...<id>
<name>...</name>
<email>...</email>
<roles>
<role>...</role>
</roles>
</developer>
<distributionManagement>
...
</distributionManagement>
<repositories>
<!-- your proxy repo here -->
</repositories>
这些都是很少更改的事情(如果我们更改存储库/分发管理,则所有项目都必须更改,如果开发人员离开或加入,我们可以在任何方便的时候更新项目POM)。
依赖关系专门属于所考虑的模块,因为两个独立项目碰巧现在共享依赖关系并不意味着它们总是会共享。我完全理解为每个项目(编译器插件,报告插件,junit等)复制XML粘贴粘贴的烦恼,但是每个项目中活动级别的不同肯定会导致它们在某个时候有所不同。
WRT级联内置在持续集成中,如果项目A要求更改超级依赖项POM,则将强制您重建所有其他项目-如果您只有2个项目,也许还好,但即使如此,您之前还是结帐并构建了这两个项目提交更改?
,在OS项目中,我通常使用3个以上级别的POM:
\“公司范围内的POM \”包含开发人员范围内的定义,例如分发管理,单个插件版本等。非常稳定,通常具有一个数字版本。示例:Sonatype OSS父级。
\“ Project POM \”包含项目范围内的定义:Java编译器版本,依赖项管理等。父级是公司范围内的POM。示例:JAXB2基础项目。每个发行版都会更新版本。
在不同级别上的“模块POM”。列出各个依赖项(依赖项的版本从项目POM继承),添加“特殊”构建步骤。示例:JAXB基础。
我也看到了其他OS项目(例如Apache \)的类似模式。
还有一些评论:
根据公司规模和产品组织,您也可能具有“部门POM”或“产品POM”。
POM继承与OOP继承差不多。您将把什么放入哪个抽象类中,以使类层次结构稳定但动态?例如,在公司范围内的POM中定义依赖项的版本是没有意义的,因为版本更改太频繁了。相反,在每个项目中定义分发管理将损害DRY原则。