﻿# 如何使用 javac 批次編譯整個資料夾(含子資料夾)下的所有 .java 檔案

前陣子幫同事處理一個不知道怎樣自動化編譯的 Java 專案，因為該專案沒有**建置工具**(Build Tools)輔助，完全依賴 Eclipse 內建的建置工具，所以工程師就不知道怎樣進行 CI 自動建置了。其實在網路上可以找到許多 Shell 環境下的解決方案，但很少有 Windows 環境下的解決方案，為了這個問題，我寫了一段自動化的腳本來解決這個問題，這個腳本幾乎可以適用任何簡易類型的 Java 專案。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/395a76346033d274f155-196042691-3faec680-6978-424e-b5f0-d7d32a3751a4.png)

### 使用批次檔腳本自動建置專案下所有 Java 檔

假設我們的專案有個 `src/` 資料夾，用來儲存所有 Java 的原始碼 (`*.java`)，但是散落在各個不同 packages 的資料夾下，此時你可以用以下命令將所有 `**/*.java` 編譯到 `bin/` 目錄下：

```batch
@ECHO OFF

REM 準備一個暫存檔
SET filelist=%temp%\filelist-%random%.txt

REM 利用 dir /s /b 取得 src 目錄下(含子目錄)的 *.java 檔案清單
dir /s /b src\*.java > %filelist%

REM 直接透過 javac @filename 用法，將所有 Java 原始檔進行編譯，並透過 -d 指定輸出路徑(*.class)
javac @%filelist% -sourcepath src -cp ".;lib" -d bin\

REM 刪除暫存檔
del %filelist%
```

> 這裡我假設你還有其他 `*.jar` 檔放在 `lib/` 目錄下，若有其他的 class path 需要參考，可以自行新增。

### 使用 PowerShell 自動建置專案下所有 Java 檔

假設我們的專案有個 `src/` 資料夾，用來儲存所有 Java 的原始碼 (`*.java`)，但是散落在各個不同 packages 的資料夾下，此時你可以用以下 PowerShell 命令將所有 `**/*.java` 編譯到 `bin/` 目錄下：

```powershell
# 準備一個暫存檔
$filelist = New-TemporaryFile

# 利用 dir /s /b 取得 src 目錄下(含子目錄)的 *.java 檔案清單
Get-ChildItem -Recurse *.java | foreach { $_.FullName } | Out-File -Encoding utf8 $filelist

# 直接透過 javac @filename 用法，將所有 Java 原始檔進行編譯，並透過 -d 指定輸出路徑(*.class)
javac "@$($filelist.FullName)" -sourcepath src -cp ".;lib" -d bin\

# 刪除暫存檔
Remove-Item $filelist
```

> 這裡我假設你還有其他 `*.jar` 檔放在 `lib/` 目錄下，若有其他的 class path 需要參考，可以自行新增。

### 相關連結

-   [Java: How can I compile an entire directory structure of code ? - Stack Overflow](https://stackoverflow.com/a/73252094/910074)
-   [How to create a Java / Maven project that works in Visual Studio Code?](https://stackoverflow.com/a/46727175/910074)
