將圖片、聲音等資源打包進 JAR,HTML 以 ARCHIVE="test.jar" 載入 Applet。直覺寫法 new ImageIcon("/img/logo.gif") 拋出 AccessControlException: FilePermission denied。
FilePermission)new ImageIcon(String path) 嘗試以檔案路徑載入,觸發安全檢查Class.getResource()public URL getResource(String name)
// 規則:
// 1. 以 '/' 開頭:從 classpath 根目錄查找(不含套件前綴)
// 2. 不以 '/' 開頭:相對於當前類別套件路徑(將 '.' 換成 '/')
// 3. 找不到回傳 null
// 錯誤寫法
// private ImageIcon icon = new ImageIcon("/img/logo.gif");
// 正確寫法
private ImageIcon icon = new ImageIcon(getClass().getResource("/img/logo.gif"));
// 更完整的防禦寫法
URL imgUrl = getClass().getResource("/img/logo.gif");
if (imgUrl == null) {
throw new IllegalStateException("資源不存在: /img/logo.gif");
}
ImageIcon icon = new ImageIcon(imgUrl);
import javax.swing.*;
import java.awt.*;
public class ImageButtonApplet extends JApplet {
public void init() {
try {
// 關鍵:使用 getClass().getResource() 取得 JAR 內資源 URL
URL imgUrl = getClass().getResource("/img/logo.gif");
if (imgUrl == null) throw new Exception("找不到資源");
ImageIcon icon = new ImageIcon(imgUrl);
JButton btn = new JButton(icon);
getContentPane().add(btn);
} catch (Exception e) {
e.printStackTrace();
getContentPane().add(new JLabel("載入失敗: " + e.getMessage()));
}
}
}
src/ImageButtonApplet.javasrc/img/logo.gif
javac -d bin src/ImageButtonApplet.javajar cvf test.jar -C bin .(包含 img/logo.gif)<applet code="ImageButtonApplet.class" archive="test.jar" width="200" height="200"></applet>
try (InputStream is = getClass().getResourceAsStream("/config.properties")) {
Properties props = new Properties();
props.load(is);
}
JAR 無目錄概念,需掃描 ClassPath 或使用 ClassLoader.getResources()。常見做法:預先定義資源清單檔(MANIFEST.MF 或自訂 resources.lst)。
getClass().getResource() 在以下環境同樣適用:
java -jar app.jar)WEB-INF/classes、WEB-INF/lib/*.jar)ClassPathResource 底層實作src/test/resources)| 錯誤現象 | 原因 | 解決 |
|---|---|---|
| getResource 回傳 null | 路徑錯誤、大小寫不符、未打入 JAR | 檢查 JAR 內結構:jar tf test.jar | grep logo |
| ImageIcon 圖片不顯示 | URL 正確但圖片格式不支援、損壞 | 用 ImageIO.read(url) 驗證 |
| 開發環境正常、部署失效 | IDE 自動複製 resources 到輸出目錄,但打包腳本遺漏 | 檢查 Maven/Gradle resources 設定 |
Applet 已淘汰,現代 Web 應用資源載入:
<img src="/assets/logo.gif">、Webpack import logo from './logo.gif'、Vite new URL('./logo.gif', import.meta.url)ResourceLoader、ClassPathResource、ServletContext.getResource()getClass().getResource()、Swing 同樣適用鐵律:JAR 內資源永遠使用 Class.getResource() 或 ClassLoader.getResource() 取得 URL/Stream,絕不使用檔案路徑字串。 此原理貫穿 Java 所有類載入場景,掌握它能解決 90% 的資源載入問題。