同一份代码打成多种包(JAR/WAR/EAR)时,如果不用classifier会产生什么有趣效果?
Posted on 2013-01-18 10:54 Bruce Zhang 阅读(842) 评论(0) 编辑 收藏 举报首先截取一段《Maven: The Complete Reference》关于Maven四维为坐标的解释:
Coordinates define a unique location for a project. Projects are related to one another using Maven Coordinates.project-a
doesn’t just depend on project-b
; a project with a groupId
, artifactId
, and version
depends on another project with a groupId
, artifactId
, and version
. To review, a Maven Coordinate is made up of three components:
groupId ...
artifactId ...
version ...
There is a fourth, less-used qualifier:
- classifier
- You would use a classifier if you were releasing the same code but needed to produce two separate artifacts for technical reasons. For example, if you wanted to build two separate artifacts of a JAR, one compiled with the Java 1.4 compiler and another compiled with the Java 6 compiler, you might use the classifier to produce two separate JAR artifacts under the same groupId:artifactId:version combination. If your project uses native extensions, you might use the classifier to produce an artifact for each target platform. Classifiers are commonly used to package up an artifact’s sources, JavaDocs or binary assemblies.
- 对于本话题,最有指导性就是上面被我标红的那句话。
- 意思是说:只要你想要用同一份代码打成多个包(ear/war/jar),就必须用classifer,来凑足四维坐标。否则,Maven绝对是不会认的,package阶段还好,但是在install/deploy时Maven就会做一些奇怪的事情(可以算一个bug),这里先卖个关子,后面再说具体现象。
- 下面是一个例子:
- 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>
<groupId>com.my.backend</groupId>
<artifactId>backend-cs</artifactId>
<version>1.1</version>
<packaging>jar</packaging><dependencies>
.......
</dependencies>
<plugins>
......
<plugin>
<groupId>com.google.code.maven-svn-revision-number-plugin</groupId>
<artifactId>svn-revision-number-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<entries>
<entry>
<prefix>SVN</prefix>
</entry>
</entries>
</configuration>
</plugin><plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>backend-cs-extra-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
</execution>
</executions>
</plugin><plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>backend-cs-extra-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<jarName>${project.artifactId}-${project.version}-${SVN.committedRevision}</jarName>
</configuration>
</execution>
</executions>
</plugin></plugins>
</project>
从上述pom.xml的配置可以看出:
(1)项目是JAR包项目
(2)希望额外再打一个JAR包和一个WAR包
运行mvn clean install后,得到如下执行日志:
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ backend-cs ---
[INFO] Deleting D:\workspace\backend-cs\backend-cs\target......
[INFO] --- maven-svn-revision-number-plugin:1.7:revision (default) @ backend-cs ---
[INFO] inspecting D:\workspace\backend-cs\backend-cs......
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ backend-cs ---
[INFO] Compiling 594 source files to D:\workspace\backend-cs\backend-cs\target\classes
......[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ backend-cs ---
[INFO] Building jar: D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1.jar......
[INFO] --- maven-war-plugin:2.1-alpha-1:war (backend-cs-extra-war) @ backend-cs ---
[INFO] Packaging webapp
[INFO] Assembling webapp[backend-cs] in [D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1]
[INFO] Processing war project
[INFO] Webapp assembled in[25152 msecs]
[INFO] Building war: D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1-442474.war[INFO] --- maven-jar-plugin:2.3.1:jar (backend-cs-extra-jar) @ backend-cs ---
[INFO] Building jar: D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1-442474.jar[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ backend-cs ---
[INFO] Installing D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1-442474.jar to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1.jar
[INFO] Installing D:\workspace\backend-cs\backend-cs\pom.xml to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1.pom精彩的地方就是这里了,mavn-install-plugin开始发疯了:
backend-cs-1.1-442474.jar ——> backend-cs-1.1.jar ???
把额外打的jar包当成正式的jar包安装到本地仓库去了。
可能目前看起来还不是很清晰,我们把maven-jar-plugin打额外JAR包的maven-jar-plugin申明加上classifier,看看会有什么变化??
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>backend-cs-extra-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<jarName>${project.artifactId}-${project.version}-${SVN.committedRevision}</jarName>
<classifier>extra-jar</classifier>
</configuration>
</execution>
</executions>
</plugin>再执行mvn clean install,mvn-install-plugin执行日志如下:
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ backend-cs ---
[INFO] Installing D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1-442474.war to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1.jar
[INFO] Installing D:\workspace\backend-cs\backend-cs\pom.xml to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1.pom
[INFO] Installing D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1-442474-extra-jar.jar to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1-extra-jar.jar看到了吧!Maven的确是疯了:backend-cs-1.1-442474.war ——> backend-cs-1.1.jar ???
尽然把“backend-cs-1.1-442474.war”重命名成“backend-cs-1.1.jar”安装到本地maven仓库了。
那么,如果给maven-war-plugin也加上classifier,又会有什么惊喜呢?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>backend-cs-extra-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
<configuration>
<classifier>extra-war</classifier>
</configuration>
</execution>
</executions>
</plugin>再运行mvn clean install,mvn-install-plugin执行日志如下:
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ backend-cs ---
[INFO] Installing D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1.jar to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1.jar
[INFO] Installing D:\workspace\backend-cs\backend-cs\pom.xml to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1.pom
[INFO] Installing D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1-442474-extra-war.war to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1-extra-war.war
[INFO] Installing D:\workspace\backend-cs\backend-cs\target\backend-cs-1.1-442474-extra-jar.jar to C:\MavenRepo\com\my\backend\backend-cs\1.1\backend-cs-1.1-extra-jar.jar到这里,Maven终于正常了:
backend-cs-1.1.jar ——> backend-cs-1.1.jar
pom.xml ——> backend-cs-1.1.pom
backend-cs-1.1-442474-extra-war.war ——> backend-cs-1.1-extra-war.war
backend-cs-1.1-442474-extra-jar.jar ——> backend-cs-1.1-extra-jar.jar
总结如下:
(1)如果要将一份源码打成多种/多个包,就必须都使用classifier来确定第四维度。
(2)如果不申明classifier,maven-install-plugin就会发疯把最后一个生成的包重命名成项目包,并安装到本地仓库,且发布到远程仓库。如第一次是“backend-cs-1.1-442474.jar ——> backend-cs-1.1.jar”,第二次是“backend-cs-1.1-442474.war ——> backend-cs-1.1.jar”。