如何編譯一個無包結構的單個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 放置在根據package劃分的目錄中。
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
java原代碼所在目錄下執行javac命令編譯源代碼時候,-d ./表示以源代碼所在目錄爲class文件的根目錄。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