使用Maven對JAVA程序打包-帶主類、帶依賴【轉】


很多時候,我們需要對編寫的程序進行打包,這個時候,我們可以借助一些項目構建工具,如maven, sbt, ant等,這里我使用的是maven。

打包成可執行有主類的jar包(jar包中無依賴)

以下是配置打包成可執行,帶主類的jar包:

<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> ... <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>fully.qualified.MainClass</mainClass> <!-- 你的主類名 --> </manifest> </archive> </configuration> ... </plugin> </plugins> </build>

 

But, 雖然現在把程序打包成了jar文件,也可以運行,但是,這個jar包是沒有包含依賴的,因此,如果這個程序有其他依賴,那么在運行這個程序的時候,需要指定類目錄,並且要把所有的依賴都放到類目錄下去,手動添加依賴到類目錄下,簡直就是惡夢。。。

我曾經就這么干過,它少一個依賴,我就手動加一個到類目錄,少一個,加一個,少一個,加一個,當我加了大概有10幾個之后,而且還看不到盡頭。。。簡直要瘋的節奏,然后想起之前用sbt打包,也是可以把依賴添加到jar包,心情頓時好轉,趕緊google,於是找到google到了maven的官網…。順便說一下,雖然我們google的時候,會搜索到很多結果,但很多時候,我們最好選擇合適的結果進行閱讀,我的一般順序是:官方優先,StackExchange。。。

打包成帶依賴的jar包

配置

不加main類而帶依賴的jar包

編輯pom.xml文件,內容如下:

<project> [...] <build> [...] <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- bind to the packaging phase --> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> [...] </project>

 

加main類也帶依賴的jar包

編輯pom.xml文件,內容如下:

<project> <build> <plugins> <!--(start) for package jar with dependencies --> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <configuration> <archive> <manifest> <mainClass>Main</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- bind to the packaging phase --> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <!--(end) for package jar with dependencies --> </plugins> </build> </project>

值得注意的是,不要像以下那樣修改pom.xml文件,那樣雖然不會報錯,但生成的jar包中的MANIFEST.MF中沒有主類,這樣的jar包無法直接運行。

<project> [...] <build> [...] <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> ... <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>fully.qualified.MainClass</mainClass> <!-- 你的主類名 --> </manifest> </archive> </configuration> ... </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- bind to the packaging phase --> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> [...] </project>

 

打包

使用以下命令打包:

mvn package

 

就像官方網站說的,” this is pretty simple! “

 



然而,當在運行操作hdfs的jar包時,我出現了以下問題:

 

Exception in thread "main" java.io.IOException: No FileSystem for scheme: hdfs at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2660) at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2667) at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:94) at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2703) at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2685) at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:373) at sentry.magic.fs.Dfs.<init>(Dfs.java:20) at sentry.magic.fs.CheckFlumeIsCompleted.<init>(CheckFlumeIsCompleted.java:26) at Main.main(Main.java:26)

 

好在有位仁兄[2]也遇到了這個問題,從而使得問題解決。解決方法如下:

    FileSystem dfs = null; Configuration conf = new Configuration(); public Dfs(URI uri) throws IOException { // 必須有下面這一句 conf.set("fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem"); // 必須有上面那一句 dfs = FileSystem.get(uri,conf); }

 

除了他之種方法之外,我也自己摸索出了一種方法,經過實踐,也是可行的,我的方法如下: 
找到打包好的jar包,然后使用歸檔管理器打開這個jar包,即“open with archive manager”,找到META-INFO/services目錄,再找到這個目錄下的org.apache.Hadoop.fs.FileSystem文件,編輯這個文件,在文件末尾加上一行:

org.apache.hadoop.hdfs.DistributedFileSystem

 

但是,這么修改jar的方法,不太合適,因為每生成一次,需要修改一次,所以,建議暫時使用前面那種解決方法。

參考文獻:

[1] https://maven.apache.org/plugins/maven-assembly-plugin/usage.html 
[2] http://www.cnblogs.com/justinzhang/p/4983673.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM