2

我有一个沙盒小程序,但这不应该有所作为。

Applet 由 2 个罐子组成。如果我将两个文件都托管在同一个 domain1 上,一切都很好。由于某些特殊情况,我需要将 jar2 托管在不同的 domain2 上。

在小程序标签中,我列出了两个文件 archive="jar1.jar, http://domain2.com/jar2.jar "。

首先,它似乎工作得很好。两个罐子都已加载,一切正常。尽管如此,只要我尝试从其中一个 jar 中访问资源(如图像),就会出现问题。

如何从我的 jar 中获取资源?我首先通过获取资源位置的 URL 来获取资源:

公共静态 URL getURL(String name) {return ResUtils.class.getResource(path);}

如果我在 domain1 上托管两个 jar,则此方法返回一个 URL。当托管在两个域上时,getURL(...) 返回 NULL,然后在获取资源时导致异常:

Caused by: java.lang.IllegalArgumentException: input == null!
    at javax.imageio.ImageIO.read(Unknown Source)

我猜 ResUtils.class.getResource 使用它的 Classloader 返回一个 URL。出于某种原因,在两个域上托管两个 jar 时,添加对 getRessource() 的调用返回 NULL。

所以我的问题是:

  • 为什么 getURL 返回 NULL?

Java 插件是否旨在禁止在不同域中托管这些 jar?当我将 jars 托管在不同的域上时,如何加载我的资源?

4

2 回答 2

2

尝试这样的事情:

      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      URL url = cl.getResource("imagename.gif");
      System.out.println("URL is: " + url);
      ImageIcon icon = new ImageIcon(url);

使用上下文类加载器通常是从 jar 文件加载图像的最佳方式。

Edit1:顺便说一句,我很惊讶第一个建议没有奏效。如果我没记错的话,Thread.currentThread().getContextClassLoader() 建议应该给你一个类加载器的引用,这个类加载器可以从任一 jar 文件中找到资源。

Edit2:在这种情况下,上述方法均无效。好奇心战胜了我,所以我不得不尝试一下。插件类加载器似乎太混乱了,无法从托管在另一台服务器上的 jar 文件加载资源,即使加载类没有问题。我发现手动方法确实可以加载如下资源:

  String manualString = "jar:http://spider.grunt.webhop.net/clubjar.jar!/club.gif";
  URL manualURL = new URL(manualString);
  BufferedImage buf = ImageIO.read(manualURL);
  System.out.println("manual buf: " +buf);

对我来说,这看起来像是插件类加载器的错误。我们应该能够使用类加载器 getResource() 或 getResourceAsStream() 方法来定位有效资源。在这种情况下并非如此。ImageIO 类可以读取我们的手动 URL,但类加载器不能给我们一个。

于 2009-04-25T16:43:26.350 回答
0

Thread.currentThread().getContextClassLoader(); 不能解决我的问题。

我所有的资源都在同一个“res”文件夹/包中——与获取它们的类相同:ResUtils(参见下面的源代码)。

如果来自 domain1 的 jar1 中的类调用 ResUtils.getImageIcon("trash.gif"); getURL(...) 返回一个 URL: url -> jar: http://domain1/bun.jar!/res/trash.gif

如果来自 domain2 的 jar2 中的类调用 ResUtils.getImageIcon("trash.gif"); getURL(...) 返回一个 NULL: url -> null

package res;

public class ResUtils {
       private static final String PATH =  "/" + (ResUtils.class.getPackage().getName().replace(".", "/")) + "/";
         public static URL getURL(String name)  {return ResUtils.class.getResource(PATH + name);}
          public static ImageIcon getImageIcon(String name) {
           return new ImageIcon(getBufferedImage(name));
       }

       public static BufferedImage getBufferedImage(String name) {
           try {
               URL url = getURL(name);
               return ImageIO.read(url);
           } catch (Exception e) {
               e.printStackTrace();
               return new BufferedImage(10,10, BufferedImage.TYPE_INT_RGB);
           }
       }
}
于 2009-04-25T18:22:41.183 回答