2 Stimmen

Applet lädt Jars aus verschiedenen Domänen; hat Probleme beim Laden von Ressourcen (z.B. Bilder) aus Jars

Ich habe ein Applet in einer Sandbox, aber das sollte keinen Unterschied machen.

Das Applet besteht aus 2 Gläsern. Wenn ich beide Dateien auf der gleichen Domain1 hoste, ist alles in Ordnung. Aufgrund bestimmter besonderer Umstände muss ich jar2 auf einer anderen Domäne2 hosten.

Im Applet-Tag liste ich beide Dateien archive="jar1.jar, http://domain2.com/jar2.jar ".

Zunächst scheint es gut zu funktionieren. Beide Jars sind geladen und alles funktioniert einwandfrei. Sobald ich jedoch versuche, auf eine Ressource (z. B. ein Bild) von INNERHALB einer der Jars zuzugreifen, gibt es ein Problem.

Wie erhalte ich Ressourcen aus meinen Gläsern? Ich erhalte Ressourcen, indem ich zunächst eine URL für den Ort der Ressource erhalte:

public static URL getURL(String name) {return ResUtils.class.getResource(path);}

Wenn ich beide Jars auf Domain1 hoste, gibt diese Methode eine URL zurück. Wenn sie auf zwei Domänen gehostet werden, gibt getURL(...) NULL zurück, was dann zu einer Ausnahme beim Abrufen der Ressource führt:

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

Ich schätze, ResUtils.class.getResource verwendet seinen Classloader, um eine URL zurückzugeben. Aus irgendeinem Grund, wenn beide Jars auf zwei Domains gehostet werden, geben zusätzliche Aufrufe von getRessource() NULL zurück.

Meine Frage ist also:

  • Warum gibt getURL NULL zurück?

Ist das Java-Plugin so konzipiert, dass es das Hosten dieser Jars auf verschiedenen Domänen nicht zulässt? Wie muss ich meine Ressourcen laden, wenn ich die Jars auf verschiedenen Domains hoste?

2voto

Gary Punkte 5949

Versuchen Sie so etwas:

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

Die Verwendung des Kontext-Classloaders ist im Allgemeinen der beste Weg, um Bilder aus Jar-Dateien zu laden.

Bearbeiten1: Übrigens bin ich überrascht, dass der erste Vorschlag nicht funktioniert hat. Wenn ich mich recht erinnere, hätte der Vorschlag Thread.currentThread().getContextClassLoader() einen Verweis auf einen Classloader liefern sollen, der Ressourcen aus einer der beiden Jar-Dateien hätte finden können.

Edit2: Keine der oben genannten Maßnahmen funktioniert in diesem Fall. Die Neugierde hat mich übermannt, also musste ich es ausprobieren. Der Plugin-Classloader scheint einfach zu verwirrt zu sein, um Ressourcen aus jar-Dateien zu laden, die auf einem anderen Server gehostet werden, obwohl er keine Probleme mit dem Laden von Klassen hat. Was ich herausgefunden habe, ist, dass eine manuelle Methode tut arbeiten, um Ressourcen wie diese zu laden:

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

Für mich sieht das nach einem Fehler im Classloader des Plugins aus. Wir sollten in der Lage sein, die Methoden getResource() oder getResourceAsStream() des Classloaders zu verwenden, um eine gültige Ressource zu finden. Nicht so in diesem Fall. Die ImageIO-Klasse kann unsere manuelle URL lesen, aber der Classloader kann uns keine geben.

0voto

Andy Schmidt Punkte 251

Thread.currentThread().getContextClassLoader(); ist keine Lösung für mein Problem.

Alle meine Ressourcen befinden sich im gleichen "res"-Ordner/Paket - genau wie die Klasse, die sie abrufen soll: ResUtils (siehe Quelle unten).

Wenn eine Klasse in jar1 aus domain1 ResUtils.getImageIcon("trash.gif"); getURL(...) aufruft, wird eine URL zurückgegeben: url -> jar: http://domain1/bun.jar!/res/trash.gif

Wenn eine Klasse in jar2 aus domain2 ResUtils.getImageIcon("trash.gif"); getURL(...) aufruft, wird ein NULL zurückgegeben: 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);
           }
       }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X