Applet加载来自不同域的jar;从坛子加载资源(例如图像)有问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Applet加载来自不同域的jar;从坛子加载资源(例如图像)有问题相关的知识,希望对你有一定的参考价值。

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

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

在applet标签中,我列出了两个文件archive =“jar1.jar,http://domain2.com/jar2.jar”。

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

我如何从罐子里获取资源?我通过首先获取资源位置的URL来获取资源:

public static 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?当我在不同的域上托管jar时,如何加载我的资源?

答案

尝试这样的事情:

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

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

编辑1:顺便说一句,我很惊讶第一个建议不起作用。如果内存对我有用,那么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,但类加载器不能给我们一个。

另一答案

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);
           }
       }
}

以上是关于Applet加载来自不同域的jar;从坛子加载资源(例如图像)有问题的主要内容,如果未能解决你的问题,请参考以下文章

从 JAR 加载资源而不访问 ClassLoader?

如何在 HTML 页面加载时使用 JFrames 打开 Applet

Chrome 扩展:阻止来自外部域的内容被加载到特定域的页面中

从 Java 中的类路径加载资源的 URL

SpringBoot:加载和读取jar包外面的资源文件

从 s3 将外部 jars 加载到 Zeppelin