说实话,这是一个相当大的构建,我使用了一些最佳实践来保持所有这些东西井井有条。
首先,我将您的代码划分为几个模块,并将其布局如下:
pom.xml
/src
/app
/app-name
pom.xml
/src ...
/app-name-sdk
pom.xml
/src ...
/deployment
pom.xml
/src
/assembly
image.xml
/main
/app-folder
/bin
startup-script.sh
startup-script.bat
/etc
config.conf
...
/plugins
/plugin-A
pom.xml
/src ...
/plugin-B
pom.xml
/src ...
此时,您已在逻辑上分离出所有不同的组件部分,清楚地知道所有内容的位置,并打包成逻辑组。 (现在当我再次检查它时,它看起来不像是文件夹呕吐物,因为我现在可以将 /doc 和 /bin 目录保留在顶层,并且知道 /src 下的子目录描述了每个相关子模块中的内容。)
此时,顶层 pom.xml 应大致如下所示:
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>app-name-parent</artifactId>
<groupId>com.mycompany.my-app</groupId>
<version>1.3.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>[Parent] My App</name>
<modules>
<!-- App -->
<module>src/app/app-name</module>
<module>src/app/my-app-sdk</module>
<!-- Plugins -->
<module>src/plugins/plugin-A</module>
<module>src/plugins/plugin-B</module>
<!-- Packaging -->
<module>src/app/distribution</module>
</modules>
<properties>
<!-- Useful properties to define here -->
<scm.revision>USER</scm.revision>
<compiler.debug>true</compiler.debug>
<compiler.optimize>false</compiler.optimize>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- If you're not going to version your plugins with the parent,
then you should pick out the specific version info here
for each plugin. That way, you could just update individual plugins.
If this is to be packaged up and shipped together, it's probably not necessary.
-->
<plugin-A.version>1.1</plugin-A.version>
<plugin-B.version>1.3</plugin-B.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<debug>${compiler.debug}</debug>
<optimize>${compiler.optimize}</optimize>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencyManagement>
<dependencies>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>release</id>
<properties>
<compiler.debug>false</compiler.debug>
<compiler.optimize>true</compiler.optimize>
</properties>
</profile>
<profile>
<id>ci-server</id>
<activation>
<property>
<name>env.SVN_REVISION</name>
</property>
</activation>
<properties>
<scm.revision>${env.SVN_REVISION}</scm.revision>
</properties>
</profile>
</profiles>
</project>
然后,您的所有子模块都需要定义到父模块的链接,如下所示:
<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>
<parent>
<artifactId>app-name-parent</artifactId>
<groupId>com.mycompany.my-app</groupId>
<version>1.3.2-SNAPSHOT</version>
<relativePath>../../..</relativePath>
</parent>
<groupId>com.mycompany.my-app</groupId>
<artifactId>app-name</artifactId>
<name>[App] My App</name>
<description>
TODO
</description>
<dependencies>
<!-- System dependencies -->
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>app-name-sdk</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
为了这个世界上所有神圣和正确的事物的爱,不要尝试将所有内容打包到与 jar 输出相关的模块之一中。这是错误的,所有这样做的人都是分流。
我在开玩笑。
但说真的:将打包过程分解为自己的单独模块,这里是 src/app/deployment 模块,用于打包构建的其他工件。然后,它实际上只依赖于系统中的其他组件,并且可能看起来像:
<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>
<parent>
<artifactId>app-name-parent</artifactId>
<groupId>com.mycompany.my-app</groupId>
<version>1.3.2-SNAPSHOT</version>
<relativePath>../../..</relativePath>
</parent>
<groupId>com.mycompany.my-app</groupId>
<artifactId>deployment</artifactId>
<packaging>pom</packaging>
<name>[App] Deployment Image</name>
<description>
TODO
</description>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>image</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<tarLongFileMode>gnu</tarLongFileMode>
<descriptors>
<descriptor>src/assembly/image.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>my-app</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<!-- Notice the separate group namespace element 'plugins', for clarity -->
<groupId>${project.parent.groupId}.plugins</groupId>
<artifactId>plugin-A</artifactId><!-- Or project.version, depending... -->
<version>${plugin-A.version}</version>
</dependency>
<dependency>
<groupId>${project.parent.groupId}.plugins</groupId>
<artifactId>plugin-B</artifactId>
<version>${plugin-B.version}</version><!-- Or project.version, depending... -->
</dependency>
</dependencies>
</project>
然后您可以使用程序集描述符文件(此处为 image.xml)将所有内容打包成一个连贯的整体,如下所示:
<assembly>
<id>image</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<!-- Everything -->
<dependencySet>
<outputDirectory>/app-folder/jars</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<fileMode>0644</fileMode>
<directoryMode>0644</directoryMode>
<!-- This includes all transitive, <scope>compile</scope> dependencies -->
<includes>
<include>${project.parent.groupId}:*</include>
</includes>
</dependencySet>
</dependencySets>
<!-- Packaged scripts, config files, etc. -->
<fileSets>
<fileSet>
<outputDirectory>/app-folder/bin</outputDirectory>
<lineEnding>unix</lineEnding>
<fileMode>0755</fileMode>
<directoryMode>0744</directoryMode>
<filtered>false</filtered>
<directory>src/main/app-folder/bin</directory>
<includes>
<include>**/*</include>
</includes>
<!-- Some weird files are added here, for some reason -->
<excludes>
<exclude>*.*.formatted</exclude>
</excludes>
</fileSet>
<fileSet>
<outputDirectory>/app-folder/etc</outputDirectory>
<lineEnding>unix</lineEnding>
<fileMode>0640</fileMode>
<directoryMode>0744</directoryMode>
<filtered>true</filtered>
<directory>src/main/app-folder/etc</directory>
<includes>
<include>**/*</include>
</includes>
<!-- Some weird files are added here, for some reason -->
<excludes>
<exclude>*.*.formatted</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
您可以通过包装获得更精美的包装,但这是让您完成 90% 的基本原理。
很抱歉这篇文章的长度,但我这样做很多,遵循这种做法确实让一切变得更清晰,更容易弄清楚,特别是如果我必须在几个月后回来.