首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Applet 中正確引用 JAR 封存內資源檔案的關鍵技巧

     編輯:Java 程式設計入門

問題情境

將圖片、聲音等資源打包進 JAR,並在 <APPLET ARCHIVE="test.jar"> 中載入。直覺寫法 new ImageIcon("/img/Logo.gif") 會拋出 AccessControlException: java.io.FilePermission,因為 Applet 沙箱禁止直接存取檔案系統路徑。

錯誤與正確做法對比

做法程式碼結果
❌ 絕對/相對路徑new ImageIcon("/img/Logo.gif")嘗試從檔案系統讀取,被沙箱阻擋
❌ getResourceAsStream 但路徑錯誤getClass().getResourceAsStream("img/Logo.gif")相對路徑從類別套件目錄查找,找不到資源
✅ Class.getResource (絕對路徑)getClass().getResource("/img/Logo.gif")從 JAR 根目錄查找,**正確**
✅ ClassLoader.getResourcegetClass().getClassLoader().getResource("img/Logo.gif")從 Classpath 根目錄查找,同樣正確

核心 API:Class.getResource()

public URL getResource(String name) {
    // name 以 '/' 開頭:從 classpath 根目錄查找 (JAR 內部根目錄)
    // name 不以 '/' 開頭:從當前類別的 package 目錄查找
}

完整修正範例

public class ImageButtonApplet extends JApplet {
    private String resourcePath = "/img/Logo.gif";  // 絕對路徑,從 JAR 根目錄
    
    public void init() {
        try {
            // 關鍵:使用 getClass().getResource() 取得 JAR 內資源 URL
            URL imgUrl = getClass().getResource(resourcePath);
            if (imgUrl == null) throw new Exception("資源不存在: " + resourcePath);
            
            ImageIcon icon = new ImageIcon(imgUrl);
            JButton btn = new JButton(icon);
            getContentPane().add(btn);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

HTML 嵌入設定

<APPLET CODE="ImageButtonApplet.class" 
         CODEBASE="." 
         ARCHIVE="test.jar" 
         WIDTH="200" HEIGHT="200">
</APPLET>
  • CODEBASE=".":類別檔與 JAR 同目錄
  • ARCHIVE="test.jar":瀏覽器下載並快取 JAR
  • 經 HTMLConverter 轉換後可支援 Java Plug-in

JAR 封裝結構驗證

test.jar
├── ImageButtonApplet.class
└── img/
    └── Logo.gif

使用 jar tf test.jar 確認結構,資源路徑必須與程式碼 getResource("/img/Logo.gif") 完全一致(區分大小寫)。

進階:統一資源載入工具類

public class ResourceUtil {
    public static URL getResource(Class clazz, String path) {
        // 支援絕對/相對路徑,自動處理前綴
        String normalized = path.startsWith("/") ? path : "/" + path;
        URL url = clazz.getResource(normalized);
        if (url == null) {
            // 嘗試 ClassLoader (適合模組化環境)
            url = clazz.getClassLoader().getResource(normalized.substring(1));
        }
        return url;
    }
    
    public static ImageIcon loadImageIcon(Class clazz, String path) {
        URL url = getResource(clazz, path);
        return (url != null) ? new ImageIcon(url) : null;
    }
}

適用場景擴充

  • ImageIO.read(url):載入 BufferedImage 進行像素處理
  • AudioClip clip = Applet.newAudioClip(url):載入音效
  • getResourceAsStream():讀取文字設定檔、屬性檔、JSON 等
  • Font.createFont(Font.TRUETYPE_FONT, url.openStream()):載入自訂字型

常見錯誤排查清單

  1. JAR 內路徑大小寫是否與程式碼完全一致 (Linux 區分大小寫)
  2. 資源是否確實打包進 JAR (jar tf 驗證)
  3. 路徑前綴:/ 代表 JAR 根目錄,無 / 代表類別套件目錄
  4. 簽署 Applet 才能存取本地檔案系統,無簽署僅能讀取 JAR 內資源
  5. Java 模組系統 (JPMS) 環境下需在 module-info.java 宣告 opens package
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved