手動編譯並運行Java項目的過程


  現在Java開發基本上就是IDE調試,如果跨平台打個jar包過去運行一般就可以了,但是有些情況比如需要引入外部依賴的時候,這個時候是不能直接運行的,還需要引入一些外部的參數,並不是簡單的javac和java的關系了,下面來詳細說一下

  一般情況下,在本地都是使用eclipse開發工具進行開發,很多東西基本上就不用我們考慮了,如果我們要將項目放到Linux下運行的話,那么就需要進行轉移的操作,當然有Maven、Ant這樣的自動化部署工具,簡直是太方便了,為了做到更進一步認識的話,我們純手動的去打包一個java的項目

  首先,項目名稱為JarTest,在eclipse結構如下圖所示:

  

  包名和類名都看的非常清楚了,App是主類,包含有main方法;TestBean是一個JavaBean實體;TestService是一個利用TestBean進行簡單計算的類,那么各個類的代碼如下:

App.java

 1 package net.javatest.package1;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import net.javatest.package2.TestBean;
 7 import net.javatest.package3.TestService;
 8 
 9 public class App {
10 
11     public static void main(String[] args) {
12         List<TestBean> tb = new ArrayList<TestBean>();
13         String[] names = {"hacker","nginx","github","hadoop","storm","solr","kafka","spark"};
14         for(int i = 0;i < names.length;i++) {
15             tb.add(new TestBean(String.valueOf(i),names[i]));
16         }
17         List<String> namelist = TestService.nameList(tb);
18         for(int i = 0;i < namelist.size();i++) {
19             System.out.println(namelist.get(i));
20         }
21     }
22 
23 }

TestBean.java

 1 package net.javatest.package2;
 2 
 3 public class TestBean {
 4     private String id;
 5     private String name;
 6     
 7     public TestBean() {
 8         
 9     }
10     
11     public TestBean(String id, String name) {
12         this.id = id;
13         this.name = name;
14     }
15     
16     public String getId() {
17         return id;
18     }
19     public void setId(String id) {
20         this.id = id;
21     }
22     public String getName() {
23         return name;
24     }
25     public void setName(String name) {
26         this.name = name;
27     }
28 }

TestService.java

 1 package net.javatest.package3;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import net.javatest.package2.TestBean;
 7 
 8 public class TestService {
 9     
10     public static List<String> nameList(List<TestBean> tbs) {
11         List<String> names = new ArrayList<String>();
12         for(TestBean tb : tbs) {
13             names.add(tb.getName());
14         }
15         return names;
16     }
17     
18 }

  文件就是這樣,源程序都不依賴於外部包,其實在eclipse中自動已經進行編譯成class了,我們可以直接使用class文件,在這里我們直接使用源文件進行編譯,首先打包上傳項目,壓縮成JarTest.zip上傳到服務器,

  

  接下來解壓釋放目錄:

unzip JarTest.zip
cd JarTest/src

  因為我們打包項目的時候打包的項目外層目錄,所以解壓出來需要進入JarTest這個目錄,我們的源代碼文件在src中,現在開始編譯:

javac net/javatest/package1/App.java net/javatest/package2/TestBean.java net/javatest/package3/TestService.java 

  這樣回車之后,沒任何提示就編譯好了,現在每個包下都有一個和源文件對應的class文件,如果感覺上面太長太麻煩,可以使用通配符全部搞定編譯:

javac net/javatest/package*/*.java

  這樣就全部編譯完了,現在我們可以執行一下看一下運行結果,

java net.javatest.package1.App

  這樣就可以直接App的main方法了,接下來可以進行打包,打成一個jar包,用起來更方便,我們可以用eclipse打成jar包看一下目錄結構,我們會發現jar包如果解壓出來之后,會看到META-INF的一個目錄,這個目錄中有一個MANIFEST.MF文件,這個文件就是定義如何導入外部jar包以及主類的存在位置,接下來我們自己編寫MANIFEST.MF這個文件,我們使用命令: vim MANIFEST.MF 創建一個文件,直接在當前也就是src目錄下創建即可,然后我們編輯以下內容:

1 Manifest-Version: 1.0
2 Main-Class: net.javatest.package1.App
3  
4  

  第一行是固定格式,定義版本號,第二行就是指明主類的位置可以用空格分開多個聲明,注意冒號之后要有一個空格;然后注意的就是后面需要空出2行,輸入兩次換號即可,然后我們保存退出,執行下面命令打包:

jar -cvfm jartest.jar MANIFEST.MF net/

  其中jartest.jar就是要打的包,net就是我們的包目錄,現在我們就可以看到一個jartest.jar這樣一個文件,

  

  然后我們執行下面命令就可以運行該jar文件了

java -jar jartest.jar

  如果jar包中具有多個包含main方法的類時,需要指定Main-Class定義的其中之一,命令如下:

java -jar jartest.jar net.javatest.package1.App

  以上是沒有任何外部依賴的Java項目的運行,如果有其他依賴的話,具體運行情況如下,我們將剛才打好的jar包下載,然后新建另外一個項目去調用jar包里面類中的方法,項目如下:

  

  只有一個主類,代碼很簡單,就是調用了jartest.jar的方法,JarTest2.java代碼如下:

 1 package net.javatest;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import net.javatest.package2.TestBean;
 7 import net.javatest.package3.TestService;
 8 
 9 public class JarTest2 {
10 
11     public static void main(String[] args) {
12         List<TestBean> tb = new ArrayList<TestBean>();
13         String[] names = {"test2","nginx","hbase","hadoop","storm","solr","kafka","spark"};
14         for(int i = 0;i < names.length;i++) {
15             tb.add(new TestBean(String.valueOf(i),names[i]));
16         }
17         List<String> namelist = TestService.nameList(tb);
18         for(int i = 0;i < namelist.size();i++) {
19             System.out.println(namelist.get(i));
20         }
21     }
22 
23 }

  這時候將jartest.jar導入項目的path里面,編譯的時候就不會出錯了,我們繼續上傳該項目,進行編譯,編譯命令如下:

javac -classpath ../lib/jartest.jar: net/javatest/JarTest2.java 

  導入多個外部jar包時需要用:分割,並且最后一個后面必須有冒號,-classpath參數用於指定外部jar包和類文件都可以,運行的時候也需要進行包含,運行命令如下:

java -classpath ../lib/jartest.jar: net.javatest.JarTest2

  接下來將項目打包,打包之前同樣執行 vim MANIFEST.MF 編輯文件如下:

1 Manifest-Version: 1.0
2 Main-Class: net.javatest.JarTest2
3 Class-Path: lib/jartest.jar
4  
5  

  這里第三行導入外部jar包文件,多個文件依賴用空格分隔,目錄無所謂這里是相對於打包后jar文件的目錄,就是說lib目錄和打包后的jar文件在一個目錄即可正常運行,接下來打包:

jar -cvfm jartest2.jar MANIFEST.MF net/

  打包后直接使用 java -jar jattest.jar 是不能執行的,需要將剛才的lib復制過來才可以,執行下面命令:

cd ..
cp -r lib/ src/

  復制剛才的lib目錄過來即可,現在執行 java -jar jartest2.jar 即可正常運行了

  綜合來說,對於一個復雜的項目,編譯以及運行時除了系統類庫的支持,還需要引入外部jar包或者類文件才能保證整個項目的正常運行,具體的執行流程需要不斷地去熟悉

 


免責聲明!

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



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