以 Maven 方式针对不同平台进行构建
我有一个带有子模块 a:jar
的项目,它需要一组不同的依赖项,具体取决于它编译的平台。所有平台的代码都是相同的。例如,在 Android 上,httpcomponents 库已经与操作系统捆绑在一起,而我必须将其包含在 J2SE 环境的构建中。我还有另一个子模块,它将几个子模块及其依赖项组装到一个存档中。如何可靠地配置程序集子模块,以获取为相应平台编译的所有子模块及其适合该平台的依赖项?
我尝试使用配置文件创建 a:jar:android
和 a:jar:j2se
。但是,声明对其中之一的依赖关系会导致程序集中出现奇怪的依赖关系。即,程序集项目的 dependency:tree
有时会包含对 a:jar:j2se
的依赖项(无论我是否声明使用 a程序集中的 :jar:android
或 a:jar:j2se
),有时还有其他。在我更新本地存储库中的 a
的 jar 后,它(经常)发生了变化。装配项目中的切换也使用配置文件。
我可以通过将相同的依赖项应用于程序集来解决这个问题项目的配置文件,根据各个子模块配置文件的需要。但由于我必须在 POM 中重复一遍,可能有一种更专业的方法来实现这一目标。由于我对 Maven 很陌生,我想知道它是什么?我不想重复代码(因为代码保持不变,这甚至会更加重复),并且我不喜欢重复 POM 的某些部分,因为由于版本升级而更改它们可能会变得复杂。
一些具体材料: 来自 a:jar
的 POM 的依赖项:
<dependencies>
.....
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.0.1</version>
<scope>compile</scope>
<!-- Exclusion in the common part, they are provided in the profiles from different sources -->
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
....
</exclusions>
</dependency>
</dependencies>
<profiles>
<profile>
<id>android</id>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>1.6_r2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>java</id>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
程序集项目(使用 Maven 程序集插件)配置文件:
<profiles>
<profile>
<id>android</id>
<dependencies>
<dependency>
<groupId>a</groupId>
<artifactId>a</artifactId>
<version>${project.version}</version>
<classifier>android</classifier>
<type>jar</type>
</dependency>
<!-- Duplicate -->
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>1.6_r2</version>
<scope>provided</scope>
</dependency>
<!-- Duplicate -->
</dependencies>
</profile>
<profile>
<id>java</id>
<dependencies>
<!-- Duplicate -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
<scope>compile</scope>
</dependency>
<!-- /Duplicate -->
<dependency>
<groupId>a</groupId>
<artifactId>a</artifactId>
<version>${project.version}</version>
<classifier>java</classifier>
<type>jar</type>
</dependency>
</dependencies>
</profile>
</profiles>
我想摆脱标记的依赖项声明。
I have a project with a submodule a:jar
which needs a different set of dependencies, depending for which platform it is compiled. The code is the same for all platforms. E.g. on Android the httpcomponents library is already bundled with the OS, whereas I have to include it for builds for J2SE environments. I also have another submodule, which assembles several submodules and their dependencies into an archive. How can I reliably configure the assembly submodule, to take all the submodules compiled for the respective platform, and their dependencies appropriate for that platform?
I tried using profiles to create a:jar:android
and a:jar:j2se
. However, declaring a dependency on one of these would result in strange dependencies in the assembly. I.e., the dependency:tree
of the assembly project would sometimes include the dependencies on a:jar:j2se
(doesn't matter whether I declared to use the a:jar:android
or a:jar:j2se
in the assembly), and sometimes the other. It changed (often) after I updated the jars of a
in the local repository. Switching in the assembly project uses also profiles.
I could solve that by applying the same dependencies to the assembly project's profiles as are needed by the individual submodules profile. But as I have to repeat myself in the POMs, there is probably a more maven-y way to achieve that. As I am quite new to maven, I wonder what it is? I don't want to duplicate the code (that would even be more repeating as the code stays the same) and I don't like to duplicate parts of the POM as changing them due to version upgrades can get complicated.
Some concrete material: Dependencies from a:jar
's POM:
<dependencies>
.....
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.0.1</version>
<scope>compile</scope>
<!-- Exclusion in the common part, they are provided in the profiles from different sources -->
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
....
</exclusions>
</dependency>
</dependencies>
<profiles>
<profile>
<id>android</id>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>1.6_r2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>java</id>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
The assembly project (which uses the Maven Assembly Plugin) profiles:
<profiles>
<profile>
<id>android</id>
<dependencies>
<dependency>
<groupId>a</groupId>
<artifactId>a</artifactId>
<version>${project.version}</version>
<classifier>android</classifier>
<type>jar</type>
</dependency>
<!-- Duplicate -->
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>1.6_r2</version>
<scope>provided</scope>
</dependency>
<!-- Duplicate -->
</dependencies>
</profile>
<profile>
<id>java</id>
<dependencies>
<!-- Duplicate -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
<scope>compile</scope>
</dependency>
<!-- /Duplicate -->
<dependency>
<groupId>a</groupId>
<artifactId>a</artifactId>
<version>${project.version}</version>
<classifier>java</classifier>
<type>jar</type>
</dependency>
</dependencies>
</profile>
</profiles>
I'd like to get rid of the marked dependency declarations.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有几种解决方案:
这些子模块的依赖项可以声明为“已提供”,在这种情况下,在项目中,您可以包含对子模块的依赖项以及平台没有的显式依赖项。
使用
获取不必要的依赖项。使用上面的 (1) 或 (2) 创建另一个“结构”子模块 a-android:pom a-j2se:pom ,它仅描述依赖项,并在您的项目中使用这些模块。
There are several solutions:
These submodule's dependencies could be declared "provided", in this case in a project you include the dependency to the submodule along with explicit dependencies which a platform doesn't have.
Use
<exclusions>
for unnecessary dependencies.Using (1) or (2) above create yet another "structural" submodules a-android:pom a-j2se:pom which just describe dependencies, and use these modules from your projects.
您可以将 Maven 配置文件添加到 pom 并根据操作系统激活每个配置文件。配置文件激活确实支持此类选项。然后,在每个特定于操作系统的配置文件中,您可以列出可选的依赖项。这是一篇关于配置文件的文章 -> http://maven.apache.org/guides/introduction/introduction-to -profiles.html
在你的情况下,它会是这样的:
You can add a maven profile to pom and activate each profile based on the OS. Profile activation does support such an options. Then in each OS-specific profile you can list optional dependencies. Here is an article on profiles -> http://maven.apache.org/guides/introduction/introduction-to-profiles.html
In your case it would be something like this: