利用原始的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 放置在根據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

利用原始的javac編譯整個Java項目

Java| 命令編譯Java程序以及運行class文件(javac)

java命令行構建(一)

Java基礎14:離開IDE,使用java和javac構建

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章