利用原始的javac手寫編譯指令碼編譯整個Java專案
如何編譯一個無包結構的單個java檔案,無依賴jar包,除了JDK;以及執行該檔案?
在任何目錄(/home/vc/javacDemo/one
)下新建NoPackageClass.java檔案
public class NoPackageClass {
public static void main(String[] args) {
System.out.println("This is no package class!");
System.out.println("java.io.tmpdir property: "+System.getProperty("java.io.tmpdir" ));
}
}
進入改目錄下執行
javac -encoding UTF-8 ./NoPackageClass.java
編譯原始檔,只指定了原始檔原始碼格式為UTF-8
執行:java NoPackageClass
,這裡執行class檔案並不需要加class檔案字尾,只要java 命令後跟具有main函式的class檔名即可。
輸出:
This is no package class!
java.io.tmpdir property: /tmp
如何編譯一個有包結構的java檔案, 無依賴jar包,除了JDK; 以及如何執行該檔案
在目錄/home/vc/javacDemo/two
package org.vincent;
public class PackageClass {
public static void main(String[] args) {
System.out.println("This is package class!");
}
}
這個時候因為原始檔已經有package 進行管理了,那麼需要新增一個引數-d, 用於指定編譯後的class 檔案存放的基目錄,然後javac會根據包結構再生成相應的資料夾 。
當我們在 /home/vc/javacDemo/two
javac -encoding UTF-8 -d ./ PackageClass.java
最後編譯的class 檔案所在目錄為:/home/vc/javacDemo/two/org/vincent
class檔案根目錄 + org/vincent
(這個也是包結構)
執行 只能在class 檔案根目錄下執行,就是我們maven專案熟知的target目錄
同時需要執行main方法類所在的全路徑名稱:java org.vincent.PackageClass
輸出:This is package class!
批量編譯大量java檔案
新增 PackageClassTwo.java 檔案
package org.vincent;
public class PackageClassTwo{
public static void main(String[] args) {
System.out.println("This is package class!");
}
}
相當於現在在/home/vc/javacDemo/two
目錄下有兩個原始檔 PackageClassTwo.java , PackageClass.java ,在當前源目錄下執行javac命令編譯檔案,然後在當前目錄下的org/vincent子目錄有兩個編譯好的class檔案
javac -d ./ -encoding UTF-8 ./*.java
執行:java org.vincent.PackageClass
, java org.vincent.PackageClassTwo
檔案兩個命令都可以進行執行輸出:This is package class!
。
修改 PackageClass.java檔案引用PackageClassTwo類
package org.vincent;
public class PackageClass {
public static void main(String[] args) {
System.out.println("This is package class!");
PackageClassTwo two=new PackageClassTwo();
System.out.println(two.toString());
}
}
使用 下面javac命令編譯
javac -d ./ -encoding UTF-8 ./*.java
java命令執行執行:java org.vincent.PackageClass
, java org.vincent.PackageClassTwo
檔案兩個命令都可以進行執行輸出:
java org.vincent.PackageClass
命令輸出:
This is package class!
org.vincent.PackageClassTwo@15db9742
java org.vincent.PackageClassTwo
命令輸出:
This is package class!
說明PackageClass 類可以引用到 PackageClassTwo類。
這個才是比較正常的專案,通過手動編寫指令碼使用javac編譯一個完整的java專案
不用maven這些構建工具,直接把原始碼上傳到Linux伺服器手寫指令碼手動編譯成一個可執行jar程式。
這是一個有package 管理,有依賴的簡單的java程式。專案根目錄下有這些東西
- 專案根目錄
- src 原始碼根目錄,package目錄隨便
- lib 依賴包跟目錄,lib 目錄下一般是直接放jar檔案沒有在有目錄,這個目錄和MANIFEST.MF中Class-Path引數有關係
- MANIFEST.MF 檔案: 定義了入口main方法所在類,以及依賴包的位置
# 重點是編譯指令碼
#! /bin/bash
# 此處應該是專案資料夾所在目錄
cur_dir=$(pwd)
echo $cur_dir
function compile(){
# 記錄專案的根目錄所在路徑
project_name=javacDemo
project_dir=$cur_dir/$project_name
project_src=$project_dir/src # 原始碼所在根目錄
project_lib=$project_dir/lib #依賴jar所在目錄
project_class=$project_dir/target # 編譯後class檔案存放根目錄
echo "begin compile"
echo $project_dir
echo $project_src
echo $project_lib
echo $project_class
# src目錄下的所有java檔案的名稱存入到 專案根目錄/src/sources.list檔案中 先檢查是否存在,如存在先刪除
rm -rf $project_src/sources.list
# $project_src -name '*.java'表示在 $project_src目錄下以及子目錄下尋找以.java目錄結尾的 檔案 並存放到source.list臨時檔案
find $project_src -name '*.java' > $project_src/sources.list
echo "java source file >>>"
cat $project_src/sources.list
# 構建存放編譯好的class檔案的基目錄,先刪除目錄
rm -rf $project_class
mkdir $project_class
# 組裝cp引數
# 將所有的jar檔案絕對路徑記錄下來到lib.list檔案中
rm -rf $project_lib/lib.list
find $project_lib -name '*.jar' > $project_lib/lib.list
# 將當前目錄.新增進去
cpvar=.:
# 一行一行讀取lib.list檔案並去每行檔案路徑最終的檔名 ${line##*/}
while read line
do
echo $line
cpvar=${cpvar}${project_lib}"/"${line##*/}":"
echo $cpvar
done < $project_lib/lib.list
echo "print cpvar "
echo $cpvar
# 刪除這個中間檔案
rm -rf $project_lib/lib.list
# 擷取cpvar最後一個字元:
# 獲取cpvar字串長度
length=${#cpvar}-1
# 取 0 - length 長度的字串
cpvar=${cpvar:0:length}
echo $cpvar
# 批量編譯java檔案
# 編碼:-encoding utf-8
# 依賴庫以冒號:隔開
# -sourcepath 引數指定原始碼目錄跟目錄, @$project_src/sources.list 指定原始碼檔名
javac -d $project_class -encoding UTF-8 -cp $cpvar -g -sourcepath $project_src @$project_src/sources.list
# 刪除 sources.list零時檔案
rm -rf $project_src/sources.list
#刪除存在的jar 若編譯過的話
# rm $qddemo/qddemo.jar
cd $project_class
jar -cvfm $project_class/${project_name}.jar $project_dir/MANIFEST.MF *
chmod a+x $project_class/${project_name}.jar
echo "將依賴包從"${project_lib}"複製到"${project_class}/lib"目錄下. "
# 將依賴jar包從$project_lib 目錄 複製到 $project_target/lib目錄下
cp -r $project_lib $project_class/lib
}
compile
exit 0
note:指令碼和專案在同一目錄下,也即專案資料夾和編譯指令碼在同級目錄下 如
- 專案資料夾
- 指令碼檔案
注意:執行編譯指令碼必須在指令碼所在目錄執行編譯指令碼,因為指令碼基於當前目錄查詢工程目錄,進行編譯。
MANIFEST.MF檔案,放置在 專案根目錄下
指定了依賴的jar包檔案尋找的路徑在編譯後生成的jar檔案所在目錄下lib目錄下。
Manifest-Version: 1.0
Main-Class: org.vincent.App
Class-Path: lib/commons-collections-3.2.2.jar lib/commons-lang-2.6.jar
進入target目錄下執行生成的jar檔案:
java -jar javacDemo.jar
輸出:
start begin
true
true
start stop
Myname