Maven Weed
學(xué)習(xí)、使用Maven的過程中,親身遇到或看到的一些問題的解決方法。Maven有不少Bug,大家使用時(shí)一定要小心。(2007.02.10最后更新)向本地倉(cāng)庫(kù)安裝文件
mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging> -DgeneratePom=true -DcreateChecksum=true(需要使用maven-install-plugin 2.2-SNAPSHOT)
打包時(shí),不在META-INF中生成maven目錄
使用Maven打包(mvn package)時(shí),默認(rèn)地會(huì)在META-INF中生成一個(gè)目錄maven,里面是一個(gè)pom和一個(gè)屬性文件。如果不想生成這個(gè)目錄,需要在POM中進(jìn)行如下配置:
以對(duì)于一般應(yīng)用程序打包,即制作jar包為例
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</plugin>
</plugins>
</build>
如果你在打jar包(mvn package)時(shí),報(bào)如下錯(cuò)誤:<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</plugin>
</plugins>
</build>
[INFO] Failed to configure plugin parameters for: org.apache.maven.plugins:maven-jar-plugin:2.0
Cause: Cannot find setter nor field in org.apache.maven.archiver.MavenArchiveConfiguration for 'addMavenDescriptor'
這是由于maven-jar-plugin的版本不夠高(很可能是2.0版本),需要升級(jí)到最新的2.1版本。運(yùn)行命令mvn -U package,會(huì)先下載最新版本,再執(zhí)行打包操作。Cause: Cannot find setter nor field in org.apache.maven.archiver.MavenArchiveConfiguration for 'addMavenDescriptor'
類似的,對(duì)于制作war,ear包,只需要將artifactId換成對(duì)應(yīng)的plugin( maven-war-plugin , maven-ear-plugin )就可以了。
Javadoc中文亂碼
中文操作系統(tǒng)中,JDK1.5.0的Javadoc自動(dòng)默認(rèn)支持中文,而且頁(yè)面中的條目名也都默認(rèn)為中文顯示(在之前的JDK中,這些條目名都默認(rèn)為英文)。 如是在這種情況下使用命令mvn javadoc:javadoc生成Javadoc,則這些條目名將成為亂碼。
解決方法:讓javadoc插件使用UTF16或Unicode字符集。具體配置的形式如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<charset>UTF16</charset>
</configuration>
</plugin>
</plugins>
</build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<charset>UTF16</charset>
</configuration>
</plugin>
</plugins>
</build>
Scope
Scope表示了某個(gè)依賴關(guān)系的適用范圍(作用域),共有5個(gè)scope。
compile: 默認(rèn)的適用范圍,表示該依賴關(guān)系要應(yīng)用于所有的classpath。
provided: 該適用范圍非常像compile適用范圍。但它表示該依賴關(guān)系已經(jīng)由JDK或某個(gè)容量提供,如javax.servlet。
runtime:表示該依賴關(guān)系不用于編譯階段,而只使用于運(yùn)行時(shí)階段,如apache jakarta commons。
test:表示該依賴關(guān)系并不用于實(shí)際的應(yīng)用程序本身,而是該應(yīng)用的測(cè)試程序的編譯與運(yùn)行,如junit。
system:該依賴關(guān)系類似于provided,但必須顯示地表示是哪一個(gè)容器提供了這個(gè)artifact。無法在倉(cāng)庫(kù)中找到該artifact。
注意:
[1]具有compile或runtime適用范圍的依賴關(guān)系中的jar文件,制作war文件時(shí)將會(huì)被放入WEB-INF/lib目錄中。
[2]不推薦使用system適用范圍。
將mvn.bat配置為Eclipse外部工具
為了能夠在Eclipse環(huán)境中運(yùn)行mvn.bat,需要將它配置為一個(gè)外部工具(external tool)。在我的Eclipse Weed(配置外部工具)一文中已經(jīng)提到了如何配置Eclipse External Tools(可先參見該文)。本主題將具體講述如何將mvn.bat的package Build周期短語配置為外部工具。
[1]主菜單Run-->External Tools-->External Tools...
[2]先選中Program項(xiàng),再點(diǎn)擊左上角的New launch configuration按鈕
[3]Name文本框中輸入該外部工具的名稱“MvnPackage”
[4]通過Browser File System...按鈕,向Location文本框中輸入mvn.bat文件的絕對(duì)路徑
[5]通過Variables...按鈕,選擇project_loc,將向Working Directory文本框中輸入${project_loc}
[6]在Augments文本域中輸入package
這樣當(dāng)你選中一個(gè)pom.xml文件后,再運(yùn)行該外部工具,就相當(dāng)于對(duì)該P(yáng)OM文件文件執(zhí)行mvn package命令。
制作war文件時(shí),過濾文件
使用maven-war-plugin制作war文件時(shí),它會(huì)先將所有可能用于制作war的內(nèi)容放入target/artifactId-version目錄(標(biāo)準(zhǔn)目錄結(jié)構(gòu))下,然后再將這些文件進(jìn)行打包。這樣就有兩種方法進(jìn)行文件過濾:[1]使期望被過濾的文件一開始就不被放入 target/artifactId-version目錄,即使它成為不可能的文件;[2]在制作war文件時(shí),不將期望被過濾的文件加入包中。
[1]實(shí)現(xiàn)第一種方法,要對(duì)dependency進(jìn)行配置。將不希望加入包的artifact放入exclusion參數(shù)中,如下腳本所示:
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
[2]實(shí)現(xiàn)第二種方法,要對(duì)maven-war-plugin進(jìn)行配置,將
不希望加入包的資源文件(不再稱之為artifact)放入warSourceExcludes參數(shù)中,如下腳本所示:<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.1</version>
<configuration>
<warSourceExcludes>WEB-INF/lib/dom4j-1.4.jar</warSourceExcludes>
</configuration>
</plugin>
</plugins>
</build>
注意:上述方法都不僅僅是過濾掉dom4j的jar文件,它還會(huì)過濾掉dom4j所依賴的其它文件(artifact)。<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.1</version>
<configuration>
<warSourceExcludes>WEB-INF/lib/dom4j-1.4.jar</warSourceExcludes>
</configuration>
</plugin>
</plugins>
</build>
當(dāng)加載插件時(shí)拋NullPointerException
如果倉(cāng)庫(kù)中有某個(gè)插件的jar文件有問題,則會(huì)拋出這樣的異常。遇到這樣的問題時(shí),必須將這個(gè)有問題的插件清除。
可以在執(zhí)行參數(shù)中加上-X(如mvn -X compile)來獲得加載插件的過程,從中可能會(huì)發(fā)現(xiàn)問題插件。如果還不行,則使用一個(gè)新的倉(cāng)庫(kù),再次執(zhí)行工程。
Install或Deploy源代碼



















在命令行中設(shè)置本地倉(cāng)庫(kù)
在使用Maven2命令(mvn)時(shí),可以設(shè)置本地倉(cāng)庫(kù)的路徑,該路徑將會(huì)替代settings.xml中設(shè)置的本地倉(cāng)庫(kù)路徑。
如命令,mvn -Dmaven.repo.local=Another_Local_Repo package
注:在Maven1中還可以通過-Dmaven.repo.remote設(shè)置遠(yuǎn)程倉(cāng)庫(kù),但目前在Maven2中還不行。
在Maven發(fā)行包中找到Super POM文件
所有的POM都默認(rèn)繼承Super POM,該P(yáng)OM定義了Maven標(biāo)準(zhǔn)目錄結(jié)構(gòu)。但在Maven的發(fā)行包中,這個(gè)Super POM是存放在了哪里呢?
這個(gè)POM就存放在maven-project的jar文件中。在筆者的機(jī)器中,該Super POM的位置是:
Maven_Home/lib/maven-project-2.0.4.jar/org/apache/maven/project/pom-4.0.0.xml
構(gòu)建Maven遠(yuǎn)程倉(cāng)庫(kù)
構(gòu)建Maven遠(yuǎn)程倉(cāng)庫(kù)的方法很多,也很簡(jiǎn)單。常用的Web服務(wù)器(Apache,JBoss,Tomcat,...)都可以用于構(gòu)建Maven遠(yuǎn)程倉(cāng)庫(kù);而發(fā)布artifact時(shí),也可以使用多種協(xié)議(FTP,SFTP,SSH,...)。
此處使用RedHat AS 4.0 + Apache2.0.59,并應(yīng)用SSH協(xié)議向遠(yuǎn)程倉(cāng)庫(kù)發(fā)布artifact。
[1]在Apache的DocumnetRoot中新建目錄maven2/repo,此處該目錄的絕對(duì)路徑為
/usr/local/apache2/htdocs/maven2/repo
[2]在本地Maven的settings.xml文件中設(shè)置Server,語句的形式如下:
<servers>
<server>
<id>myrepo</id>
<username>myuser</username>
<password>mypasswd</password>
</server>
</servers>
myuser/mypasswd是登錄遠(yuǎn)程Linux系統(tǒng)時(shí)使用的用戶名/密碼。
[3]在本地工程的pom.xml中進(jìn)行如下形式的設(shè)置:
<distributionManagement>
<repository>
<id>myrepo</id>
<url>scp://Host/usr/local/apache2/htdocs/maven2/repo</url>
</repository>
</distributionManagement>
此處id必須與前面設(shè)置的server中的id一致;scp是使用SSH協(xié)議的文件傳輸命令;Host是遠(yuǎn)程Linux服務(wù)器的IP地址或域名;/usr/local/apache2/htdocs/maven2/repo就是Maven倉(cāng)庫(kù)在遠(yuǎn)程服務(wù)器中的絕對(duì)路徑。
[4]在本地中使用命令mvn deploy發(fā)布artifact到遠(yuǎn)程倉(cāng)庫(kù)中。
[5] 啟動(dòng)Apache服務(wù)器, 通過地址http://Host/maven2/repo,就可以看到剛剛發(fā)布artifact了。
updating...