經過DOS、SHELL批處理命令加載Lib並編譯和打包Java項目(或者運行項目)

有些時候,須要經過DOS批處理來編譯整個項目的JAVA文件;而且編譯後還要對Class文件進行打包成jar文件。。。
這還不是最煩的,最煩的是,編譯和打包的時候須要依賴其餘多個jar文件,困難就這麼來了。。。。java

項目結構
App
|-dest
| |-libs(copy過來的依賴庫)
| |-bin(生成的class文件)
|
|-libs(依賴庫)
|-src(須要編譯的JAVA源文件)windows

若是須要對項目編譯,首先,須要清理dest文件夾bash

REM 刪除dest包
IF EXIST dest RMDIR /s /q destapp

REM 建立 dest/libs和dest/bin文件夾
mkdir "dest/libs"
mkdir "dest/bin"編碼

REM copy依賴庫
copy libs\*.jar dest\libs\ /yspa

而後,從JAVA的編譯命令用法入手:
javac <選項> <源文件>
其參數中,"-d <目錄>",指定存放生成的類文件的位置
"-cp <路徑>",指定查找用戶類文件和註釋處理程序的位置(我的理解就是所須要依賴的jar包)
"-encoding <編碼>", 指定源文件使用的字符編碼(咱們使用UTF-8)
例如: javac -d dest\bin -cp libs\commons-logging-1.1.1.jar;freemarker-2.3.19.jar; -encoding UTF-8 src/a.java src/com.mycls/b.java src/com.mycls/c.java
上面Demo是加載其依賴庫並使用UTF-8編碼編譯指定java文件code

繼續,對編譯好的class文件進行打成jar包orm

REM 須要在class的根目錄打包
cd dest/binblog

REM 將當前目錄下全部文件打包到上級目錄的myjar.jar文件中
jar -cvf ../myjar.jar *
固然了,還能夠經過對MANIFEST.MF的定製來指定默認運行的類utf-8

上面的內容,對於一個JAVA開發來講都不是事兒,接下來問題來了。。。。
在編譯的時候,javac加載依賴庫是指定的依賴庫,那若是有不少依賴庫,而且在開發過成功還會發生變更呢?難道要修改cmd(bat)批處理?
這個時候,就須要指定一個libs目錄,加載此目錄下的全部文件便可。但是怎麼拼接這個參數呢?
以下所示(若是沒有依賴的jar,可將cp相關部分去除):
SETLOCAL enableDelayedExpansion
FOR %%i IN ("libs\*.jar") DO SET CP=%%i;!CP!
SET OPT=-d %OUTPUT_PATH%\bin -cp %CP% -encoding utf-8
EndLocal

這樣,全部的參數就造成了,
SETLOCAL enableDelayedExpansion是擴展本地環境變量延遲,是獲取CP參數的一個出錯點,若是沒有這個,for裏面的賦值語句是無效的。

OUTPUT_PATH 變量是指定編譯後的class文件的位置,
CP 變量就是全部須要加載用的lib包

同理,循環src目錄下的全部文件和目錄並拼接全部的java文件(配置文件請自行處理),能夠獲取全部的java文件:
CD %SRC_PATH%
FOR /R %%b IN ( . ) DO (
IF EXIST %%b/*.java SET JFILES=!JFILES! %%b/*.java
)
CD ..
REM 正在編譯...
javac %OPT% %JFILES%
REM 編譯結束

而後就是打包了,
CD %OUTPUT_PATH%\bin
REM 將全部文件打包爲mylib.jar並存放到父目錄
jar -cvf ../mylib.jar *
REM 打包完畢


對於SHELL命令來講,這樣的批處理更爲簡單:
#獲取全部的依賴lib
export libs=`find libs -name "*.jar" |xargs|sed "s/ /:/g"`
#獲取全部須要編譯的java文件
export jfiles=`find src -name "*.java" |xargs|sed "s/ / /g"`
#準備編譯
opt="-d $OUTPUT_PATH/bin -cp ${libs} -encoding utf-8"

javac $opt ${jfiles}
#打包
cd ${OUTPUT_PATH}/bin

jar -cvf ${CUR}/dest/mylib.jar *

cd ${CUR}/src

jar -cvf ${CUR}/dest/mylib-source.jar *

如下圖目錄結構爲例:

 

裏面的compile.sh和compile.cmd文件的內容分別爲:

 

調用腳本的JAVA代碼:

 1 package test.compile;
 2 
 3 import java.io.File;
 4 import java.text.SimpleDateFormat;
 5 
 6 /**
 7  * <p>編譯abc目錄下全部java文件</p>
 8  * @author Ares
 9  * @version $Id: CompileTool.java, v 0.1 2015年02月26日 上午10:41:32 Exp $
10  */
11 public class CompileTool {
12 
13     // DOS: 第一個參數是 src、cmd的父目錄,第二個參數爲最終壓縮包(mylib.jar,mylib-source.jar的目錄)所在目錄
14     
15     private static String os_name  = System.getProperty("os.name").toLowerCase();
16     
17     public static boolean compileAndJar(final String jarRootPath) throws Exception{
18         String app_path = jarRootPath; // app_path是指定abc的絕對路徑,由於java文件執行目錄可能跟編譯目錄不一致,因此若是須要請使用此參數(腳本中第一步須要進入此目錄) 19         if(app_path !=null && (!app_path.endsWith("/") && !app_path.endsWith(File.separator)))
20             app_path += File.separator;
21         String compile_datetime = new SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
22         // 無後綴的jar名稱(cmd 會拼寫爲 jarname.jar 和 jarname-source.jar)
23         String jar_name = "myjar_" + compile_datetime; // jar名稱格式,mylib_日期時間,以參數的形式傳入,下面的腳本中未使用,如若使用,請替代腳本中的mylib 24         String cmd = "";
25         java.io.File cmdFile = null;
26         if(os_name.indexOf("windows") > -1){
27             cmd = "cmd.exe /C start " + app_path + "compile.exe " + app_path + " " + jar_name;
28             cmdFile = new java.io.File(app_path + "compile.exe");
29         }else {
30             cmd = app_path + "compile.sh " + app_path + " " + jar_name;
31             cmdFile = new java.io.File(app_path + "compile.sh");
32         }
33         if(!cmd.equals("") && cmdFile != null && cmdFile.exists()){
34             if(!cmdFile.canExecute()) cmdFile.setExecutable(true);
35             return callCmd(cmd);
36         }else {
37             throw new Exception("can't find compile command. command:"+cmdFile.getAbsolutePath());
38         }
39     }
40 
41     private static boolean callCmd(String cmdStr) {
42         try {
43             Process child = Runtime.getRuntime().exec(cmdStr);
44             java.io.InputStream in = child.getInputStream();
45             while (in.read() != -1) {}
46             in.close();
47             try {
48                 child.waitFor();
49                 return true;
50             } catch (InterruptedException e) {
51                 e.printStackTrace();
52             }
53             return false;
54         } catch (java.io.IOException e) {
55             e.printStackTrace();
56         }
57         return false;
58     }
59 }

 

 

下面是compile.sh文件內容:

#!/bin/bash

CUR=$(pwd)

## reset dest folder
OUTPUT_PATH=${CUR}/dest
rm -rf $OUTPUT_PATH
mkdir -p ${OUTPUT_PATH}/bin
mkdir -p ${OUTPUT_PATH}/libs

## 獲取依賴庫和須要編譯的java文件
export libs=`find libs -name "*.jar" |xargs|sed "s/ /:/g"`
export jfiles=`find src -name "*.java" |xargs|sed "s/ / /g"`

## 編譯
opt="-d $OUTPUT_PATH/bin -cp ${libs} -encoding utf-8"
javac $opt ${jfiles}

## 打包
cd ${OUTPUT_PATH}/bin
jar -cvf ${CUR}/dest/mylib.jar *
cd ${CUR}/src
jar -cvf ${CUR}/dest/mylib-source.jar *

 

下面是compile.cmd文件內容:

 1 @ECHO OFF
 2 SETLOCAL enableDelayedExpansion
 3 
 4 REM Save Current Path(保存當前路徑)
 5 SET CUR=%CD%
 6 
 7 REM Dir Structure(設置目錄結構)
 8 SET OUTPUT_PATH=dest
 9 SET SRC_PATH=%CUR%\src
10 SET LIBS_PATH=%CUR%\libs
11 
12 REM Reset Output Dir(重置清空輸出目錄)
13 IF EXIST %OUTPUT_PATH% RMDIR /s /q %OUTPUT_PATH%
14 IF NOT EXIST %OUTPUT_PATH% MKDIR %OUTPUT_PATH%
15 CD %OUTPUT_PATH%
16 IF NOT EXIST bin MKDIR bin
17 IF NOT EXIST libs MKDIR libs
18 
19 REM Copy Files(複製jar文件)
20 CD %CUR%
21 SET CP=%OUTPUT_PATH%/libs
22 copy %LIBS_PATH%\*.jar %OUTPUT_PATH%\libs\ /y
23 
24 CD %CUR%
25 FOR %%i IN ("libs\*.jar") DO SET CP=%%i;!CP!
26 SET OPT=-d %OUTPUT_PATH%\bin -cp %CP% -encoding utf-8
27 
28 CD %SRC_PATH%
29 REM 獲取全部須要編譯的java源文件,並用空格連接
30 REM 此處須要開啓變量延遲(SETLOCAL enableDelayedExpansion不可缺乏)
31 
32 FOR /R %%b IN ( . ) DO (
33 IF EXIST %%b/*.java  SET JFILES=!JFILES! %%b/*.java
34 )
35 
36 CD %CUR%
37 REM 正在編譯...
38 javac %OPT% %JFILES%
39 
40 IF "%errorlevel%" EQU "0" (
41 ECHO 編譯成功,正在拷貝資源文件...
42 copy %CUR%/src/*.* %OUTPUT_PATH%\src\ /y
43 )
44 
45 REM 準備打包編譯文件和JAVA源文件
46 CD %OUTPUT_PATH%/bin
47 jar -cvf ../mylib.jar *
48 cd %SRC_PATH%
49 jar -cvf %CUR%/dest/mylib-source.jar *
50 
51 EndLocal
52 exit
相關文章
相關標籤/搜索