使用javac編譯Java項目

在缺乏eclipse和idea等IDE的工具的情況下,使用jdk自帶的javac命令編譯Java項目

當項目只有一個Java文件的時候,可以直接使用

javac 文件名.java

但是如果有多個源文件的時候, 例如項目結構如下:

 

com.rogueq.MainClass


package com.rogueq;

import com.rogueq.service.HelloService;
import com.rogueq.service.impl.HelloServiceImpl;

public class MainClass {
    public static void main(String[] args) {
        HelloService helloService = new HelloServiceImpl();
        helloService.sayHello();
    }
}
 


com.rogueq.service.HelloService


package com.rogueq.service;

public interface HelloService {
    void sayHello();
}
 


com.rogueq.service.impl


package com.rogueq.service.impl;

import com.rogueq.service.HelloService;

public class HelloServiceImpl implements HelloService {

    @Override
    public void sayHello() {
        System.out.println("Hello world Manual Packaging !!!!!");
    }
}
 


此時我們可以使用命令

javac -d out com/rogueq/*.java com/rogueq/service/*.java com/rogueq/service/impl/*.java

-d 參數指定class文件的輸出目錄 

以上路徑皆爲相對路徑(相對當前目錄), 也可以使用絕對路徑

 

上面的項目因爲文件夾少,所以我們可以手動將所有還有java文件的文件路徑寫全,但是如果一個項目很大, 手動寫則會比較耗時且容易出錯。

所以需要我們自己寫一個工具類 ManualCompile.java


import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

public class ManualCompile {
    private static final String USER_DIR = System.getProperty("user.dir");
    private static final String FILE_SEPARATOR = System.getProperty("file.separator");
    private static final String OS_NAME = System.getProperty("os.name");

    public static void main(String[] args) throws IOException {
        String sourcePath = USER_DIR;
        if (args.length > 0) {
            sourcePath = getPath(args[0]);
        }

        Set<String> dirs = getSourceDirs(new File(sourcePath));

        String input = dirs.toString()
                .replace(",", "")
                .replace("[", "")
                .replace("]", "");
                
        System.out.println(input);        

        String output;
        if (args.length >= 2) {
            output = createDestDirectory(args[1]);
        } else {
            output = createDestDirectory("out");
        }
        
        // 打印將要執行的javac 命令
        System.out.println("javac -d " + output + " " + input);

        try {
            // 執行javac編譯操作
            Runtime.getRuntime().exec("javac -d " + output + " " + input);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Failure");
        }

        System.out.println("SUCCESS, The dest path is [" + output + "]");

    }

    // 創建class文件的存放目錄 默認路徑爲當前工作路徑下的out文件夾
    private static String createDestDirectory(String args) {
        String destPath = getPath(args);
        File file = new File(destPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    // 獲取要編譯的java源文件的目錄, 並在目錄的末尾添加上了 *.java
    private static Set<String> getSourceDirs(File file) {
        Set<String> resultDirs = new HashSet<>();
        if (file.isFile() && file.getName().endsWith(".java")) {
            resultDirs.add(file.getAbsolutePath().replace(file.getName(), "*.java"));
            return resultDirs;
        } else if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                resultDirs.addAll(getSourceDirs(f));
            }
        }
        return resultDirs;
    }


    // 根據傳入的參數獲取當前項目工作路徑
    private static String getPath(String sourcePath) {
        String path;
        if (sourcePath == null) {
            return USER_DIR;
        }
        path = sourcePath.trim();

        if (!path.contains(":") && OS_NAME.toLowerCase().contains("windows")) {

            if (path.startsWith("\\") || path.startsWith("/")) {
                path = USER_DIR + path;
            } else {
                path = USER_DIR + FILE_SEPARATOR + path;
            }

            if (!(path.endsWith("\\") || path.endsWith("/"))) {
                path += FILE_SEPARATOR;
            }
        }

        if (OS_NAME.toLowerCase().contains("linux") && !path.startsWith("/")) {
            path = USER_DIR + FILE_SEPARATOR + path;
        }

        return path.replace("\\", FILE_SEPARATOR).replace("/", FILE_SEPARATOR);
    }
}


工具類功能說明如下:

        當不傳入參數的時候, 將編譯當前目錄下的文件

        命令:  (java ManualClass)
        例如: 當前目錄爲 D:/project/hello  則會編譯D:/project/hello 目錄下的所有java文件 編譯完成後的文件放置在 D:/project/hello/out文件夾中
        
        當只傳入一個參數的時候, 將編譯該參數指定的目錄下的文件

        命令:(java ManualClass D:/project/hello)
        例如: 當前目錄爲 D:/project/hello  參數爲 D:/project/haha 則會編譯D:/project/haha下的所有java文件  編譯完成後的文件放置在 D:/project/hello/out文件夾中

        當傳入兩參數的時候, 將編譯第一個參數指定的目錄下的文件 並把編譯完成的class文件放入第二個目錄指定的文件夾

        命令:(java ManualClass D:/project/hello D:/project/hello/dest)
        
        參數支持絕對路徑和相對路徑
            例如: D:/project/haha 或 /heihei 但不支持 ../
            
        總結: 
               第一個參數爲要編譯的java的文件夾或java文件 默認是當前目錄 
               第二參數爲編譯完成的class文件的放置文件夾  默認是當前目錄下的out文件夾(沒有會自動創建)
               路徑格式支持絕對路徑和相對路徑, 但是不支持../    

 

 

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