Maven Weed
學習、使用Maven的過程中,親身遇到或看到的一些問題的解決方法。Maven有不少Bug,大家使用時一定要小心。(2007.02.10最后更新)向本地倉庫安裝文件
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)
打包時,不在META-INF中生成maven目錄
使用Maven打包(mvn package)時,默認地會在META-INF中生成一個目錄maven,里面是一個pom和一個屬性文件。如果不想生成這個目錄,需要在POM中進行如下配置:
以對于一般應用程序打包,即制作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)時,報如下錯誤:<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版本),需要升級到最新的2.1版本。運行命令mvn -U package,會先下載最新版本,再執行打包操作。Cause: Cannot find setter nor field in org.apache.maven.archiver.MavenArchiveConfiguration for 'addMavenDescriptor'
類似的,對于制作war,ear包,只需要將artifactId換成對應的plugin( maven-war-plugin , maven-ear-plugin )就可以了。
Javadoc中文亂碼
中文操作系統中,JDK1.5.0的Javadoc自動默認支持中文,而且頁面中的條目名也都默認為中文顯示(在之前的JDK中,這些條目名都默認為英文)。 如是在這種情況下使用命令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表示了某個依賴關系的適用范圍(作用域),共有5個scope。
compile: 默認的適用范圍,表示該依賴關系要應用于所有的classpath。
provided: 該適用范圍非常像compile適用范圍。但它表示該依賴關系已經由JDK或某個容量提供,如javax.servlet。
runtime:表示該依賴關系不用于編譯階段,而只使用于運行時階段,如apache jakarta commons。
test:表示該依賴關系并不用于實際的應用程序本身,而是該應用的測試程序的編譯與運行,如junit。
system:該依賴關系類似于provided,但必須顯示地表示是哪一個容器提供了這個artifact。無法在倉庫中找到該artifact。
注意:
[1]具有compile或runtime適用范圍的依賴關系中的jar文件,制作war文件時將會被放入WEB-INF/lib目錄中。
[2]不推薦使用system適用范圍。
將mvn.bat配置為Eclipse外部工具
為了能夠在Eclipse環境中運行mvn.bat,需要將它配置為一個外部工具(external tool)。在我的Eclipse Weed(配置外部工具)一文中已經提到了如何配置Eclipse External Tools(可先參見該文)。本主題將具體講述如何將mvn.bat的package Build周期短語配置為外部工具。
[1]主菜單Run-->External Tools-->External Tools...
[2]先選中Program項,再點擊左上角的New launch configuration按鈕
[3]Name文本框中輸入該外部工具的名稱“MvnPackage”
[4]通過Browser File System...按鈕,向Location文本框中輸入mvn.bat文件的絕對路徑
[5]通過Variables...按鈕,選擇project_loc,將向Working Directory文本框中輸入${project_loc}
[6]在Augments文本域中輸入package
這樣當你選中一個pom.xml文件后,再運行該外部工具,就相當于對該POM文件文件執行mvn package命令。
制作war文件時,過濾文件
使用maven-war-plugin制作war文件時,它會先將所有可能用于制作war的內容放入target/artifactId-version目錄(標準目錄結構)下,然后再將這些文件進行打包。這樣就有兩種方法進行文件過濾:[1]使期望被過濾的文件一開始就不被放入 target/artifactId-version目錄,即使它成為不可能的文件;[2]在制作war文件時,不將期望被過濾的文件加入包中。
[1]實現第一種方法,要對dependency進行配置。將不希望加入包的artifact放入exclusion參數中,如下腳本所示:
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
[2]實現第二種方法,要對maven-war-plugin進行配置,將
不希望加入包的資源文件(不再稱之為artifact)放入warSourceExcludes參數中,如下腳本所示:<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文件,它還會過濾掉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>
當加載插件時拋NullPointerException
如果倉庫中有某個插件的jar文件有問題,則會拋出這樣的異常。遇到這樣的問題時,必須將這個有問題的插件清除。
可以在執行參數中加上-X(如mvn -X compile)來獲得加載插件的過程,從中可能會發現問題插件。如果還不行,則使用一個新的倉庫,再次執行工程。
Install或Deploy源代碼



















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