Problem mit ClassLoader - Laden von Resourcen aus Jar's

Status
Nicht offen für weitere Antworten.

KSG9|sebastian

Top Contributor
Hoi..

ich hab n kleines Problem. Ich hab ne Anwendung, welche Plugins immer dynamisch lädt. D.h. Anwendung wird gestartet -> Bestimmtes Verzeichniss wird gescannt und die Jar Files werden als Plugins geladen.
In den Jar-Files ist ne XML-Datei drin welche die Art des Plugins beschreibt.

In meiner Hauptanwendung lade ich die Jar-Files über nen ClassLoader, das funktioniert. Wenn ich aber innerhalb eines Plugins mit "Test.class.getRessourceAsStream("blah")" auf eine Datei zugreifen will, welche im gleichen Package liegt wie Test.class, bekomme ich nen Fehler ("InputStream == null ..").

//Edit: Test.class wäre die Hauptklasse des Plugins

Habt ihr ne Idee wie ich das ganze lösen könnte ?

P.S.: Noch was anderes: Wie krieg ich nen ClassLoader hin, der nicht cached ?


Gruß Sebastian
 

KSG9|sebastian

Top Contributor
keiner ne idee ?

@Roar: Wie hast du es beim Dashboard gemacht ? Das läuft doch gleich, oder ? Die Plugins werden als JAR nachgeladen...hast du dort nicht solche Probleme ?
 

Mag1c

Top Contributor
Hi,

wie genau machst du das mit dem Nachladen ? Hast du einen eigenen ClassLoader ? Ich vermute, daß der ClassLoader, der beim getResourceAsStream(...) benutzt wird, von deinen nachgeladenen JARs nichts weiß.

Gruß
Mag1c
 

KSG9|sebastian

Top Contributor
Ich hab nen eigenen JarClassLoader.

Wenn ich das Plugin als Stand-Alone starte (java -jar TestPlugin.jar), dann funktioniert Test.class.getResourceAsStream(..) ganz normal und ich kann auf die Dateien zugreifen.

Wenn ich das TestPlugin.jar aber über mein Hauptprogramm lade (mit dem eigenen ClassLoader), dann funktioniert getRessourceAsStream(...) nicht, bzw. komm ich nicht an die Datei ran.


Der ClassLoader

Code:
public class JarLoader extends SecureClassLoader {
	private URL urlBase;

	public boolean printLoadMessages = true;

	Hashtable classArrays;

	public JarLoader(String base, ClassLoader parent) {
		super(parent);
		try {
			if (!(base.endsWith("/")))
				base = base + "/";
			urlBase = new URL(base);
			classArrays = new Hashtable();
		} catch (Exception e) {
			throw new IllegalArgumentException(base);
		}
	}

	private byte[] getClassBytes(InputStream is) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		BufferedInputStream bis = new BufferedInputStream(is);
		boolean eof = false;
		while (!eof) {
			try {
				int i = bis.read();
				if (i == -1)
					eof = true;
				else
					baos.write(i);
			} catch (IOException e) {
				return null;
			}
		}

		return baos.toByteArray();
	}

	protected Class findClass(String name) {
		String urlName = name.replace('.', '/');
		byte buf[];
		Class cl;

		SecurityManager sm = System.getSecurityManager();
		if (sm != null) {
			int i = name.lastIndexOf('.');
			if (i >= 0)
				sm.checkPackageDefinition(name.substring(0, i));
		}

		buf = (byte[]) classArrays.get(urlName);
		if (buf != null) {
			cl = defineClass(name, buf, 0, buf.length);
			return cl;
		}

		try {
			URL url = new URL(urlBase, urlName + ".class");
			if (printLoadMessages)
				System.out.println("Loading " + url);
			InputStream is = url.openConnection().getInputStream();
			buf = getClassBytes(is);
			cl = defineClass(name, buf, 0, buf.length);
			return cl;
		} catch (Exception e) {
			System.out.println("Can't load " + name + ": " + e);
			return null;
		}
	}

	public void readJarFile(String name) {
		URL jarUrl = null;
		JarInputStream jis;
		JarEntry je;

		try {
			jarUrl = new URL(urlBase, name);

		} catch (MalformedURLException mue) {
			System.out.println("Unknown jar file " + name);
			return;
		}
		if (printLoadMessages)
			System.out.println("Loading jar file " + jarUrl);

		try {
			jis = new JarInputStream(jarUrl.openConnection().getInputStream());
		} catch (IOException ioe) {
			System.out.println("Can't open jar file " + jarUrl);
			return;
		}

		try {
			while ((je = jis.getNextJarEntry()) != null) {
				String jarName = je.getName();
				if (jarName.endsWith(".class")) 
					loadClassBytes(jis, jarName);
				
				jis.closeEntry();
			}
		} catch (IOException ioe) {
			System.out.println("Badly formatted jar file");
		}
	}

	private void loadClassBytes(JarInputStream jis, String jarName) {
		if (printLoadMessages)
			System.out.println("\t" + jarName);
		BufferedInputStream jarBuf = new BufferedInputStream(jis);
		ByteArrayOutputStream jarOut = new ByteArrayOutputStream();
		int b;
		try {
			while ((b = jarBuf.read()) != -1)
				jarOut.write(b);
			classArrays.put(jarName.substring(0, jarName.length() - 6), jarOut
					.toByteArray());
		} catch (IOException ioe) {
			System.out.println("Error reading entry " + jarName);
		}

	}

	public void checkPackageAccess(String name) {
		SecurityManager sm = System.getSecurityManager();
		if (sm != null)
			sm.checkPackageAccess(name);
	}
}


Ich hab mir schon überlegt, die Methode getResourceAsStream(..) zu überschreiben, aber ich hab absolut keine Ahnung wie ich dann an die Datei drankommen soll. V.a. weil ich beim aufruf der Methode getResourceAsStream(..) nicht weiß in welcher Jar ich suchen müsste...
 

Bleiglanz

Gesperrter Benutzer
Finds a resource with a given name. The rules for searching resources associated with a given class are implemented by the defining class loader of the class. This method delegates to this object's class loader.
sollte also eigentlich der richtige sein, nämlich deiner?

aber: ein eigener Classloader hat auch eine Methode getResourceAsStream(String name), die du wahrscheinlich überschreiben musst

das cachen kann man glaub ich nicht verhindern (ist wohl in der JVM so eingebaut), du kannst ja einfach eine neue Instanz deines Classloaders erzeugen und nochmal laden...
 

KSG9|sebastian

Top Contributor
Bleiglanz hat gesagt.:
aber: ein eigener Classloader hat auch eine Methode getResourceAsStream(String name), die du wahrscheinlich überschreiben musst

Ja schon klar...aber wie soll ich in der überschriebenen Methode an die Resource drankommen ? Ich weiß nicht, welche Klasse die Anfrage stellt (von welcher Klasse der Aufruf "Test.class.getResourceAsStream..." kommt).
Deshalb würden mir nur 2 Möglichkeiten ein:

1. Ich entpack die Jar-Files, greif mit ner URL drauf zu und geb den InputStream zurück. Dafür muss ich aber dann bei jedem Methoden-Aufruf das komplette Verzeichniss incl. Unterverzeichnisse durchsuchen

2. Ich öffne jedes JarFile und durchsuch die JarEntrys auf den entsprechenden Namen. Das wäre ja soweit ok, aber dann muss ich wieder ALLE Jar-Files durchsuchen. Das nächste Problem dabei wäre, wie ich nen InputStream von der gefundenen Datei krieg. Mit ner URL funktioniert das ganze irgendwie nicht, kA wieso.

Hätte jemand noch ne andere Idee ?
@Roar: Wie hast du das beim Dashboard gelöst ?
 

Bleiglanz

Gesperrter Benutzer
mach halt für jedes Plugin eine eigene Instanz deines Classloaders, dann "weiss" er gleich wo er ist?
 
B

Beni

Gast
Wieso verwendest du keinen URLClassLoader? Der könnte JAR's und andere Datein (in den JARs) laden :wink:
 

KSG9|sebastian

Top Contributor
@benni: hättest du mir n Beispiel oder sowas ?

Code:
ClassLoader c = new URLClassLoader();

Mit URLClassLoader#addUrl die Jars hinzufügen ?
 

Mag1c

Top Contributor
Hi,

vielleicht hilft:

Code:
import sun.net.[url]www.ParseUtil;[/url]

File jarFile = new File("plugin.jar");
URL jarURL = ParseUtil.fileToEncodedURL(jarFile);

Gruß
Mag1c
 

Bleiglanz

Gesperrter Benutzer
Mag1c hat gesagt.:
Hi,

vielleicht hilft:

Code:
import sun.net.[url]www.ParseUtil;[/url]

File jarFile = new File("plugin.jar");
URL jarURL = ParseUtil.fileToEncodedURL(jarFile);

Gruß
Mag1c

wozu eine der sun* Klassen einziehen, was ist das Problem bei

jarFile.toURI().toURL();


?
 

KSG9|sebastian

Top Contributor
hauptprogramm das plugins lädt

Code:
// die url ist korrekt, hab ich überprüft
loader.addUrl(jFil.toURL());

ClassLoader
Code:
public class PluginLoader extends URLClassLoader {
	private static PluginLoader instance;
	private PluginLoader(URL[] url, ClassLoader parent){
		super(url, parent);
	}
	public void addUrl(URL url){
		super.addURL(url);
	}
	public static PluginLoader getInstance(){
		return instance;		
	}
	
	public static PluginLoader getInstance(URL[] url, ClassLoader parent){
		if(instance == null)
			instance = new PluginLoader(url, parent);
		return instance;
	}
}

Aufruf des ClassLoaders im Hauptprogramm

Code:
// URLs stimmen alle

loader = PluginLoader.getInstance(new URL[]{pluginDir.toURL(), libDir.toURL(), iconDir.toURL()}, ClassLoader.getSystemClassLoader());

Aufruf im Plugin

Code:
InputStream in = PluginLoader.getInstance().getResourceAsStream(FEED_FILE);

org.jdom.Document doc = builder.build(in); // hier wirft er mir ne NullPointerException

StackTrace
Code:
org.jdom.input.JDOMParseException: Error on line 1: java.lang.NullPointerException
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:468)
	at org.jdom.input.SAXBuilder.build(SAXBuilder.java:770)
	at de.fiducia.java.jdit.rss.RssPlugin.readFeeds(RssPlugin.java:125)
	at de.fiducia.java.jdit.rss.RssPlugin.<init>(RssPlugin.java:116)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Unknown Source)
	at java.lang.Class.newInstance0(Unknown Source)
	at java.lang.Class.newInstance(Unknown Source)
	at de.fiducia.java.jdit.deskboard.BoardController.parsePlugin(BoardController.java:102)
	at de.fiducia.java.jdit.deskboard.BoardController.loadPlugins(BoardController.java:81)
	at de.fiducia.java.jdit.deskboard.BoardController.<init>(BoardController.java:52)
	at de.fiducia.java.jdit.deskboard.BoardController.main(BoardController.java:121)
 

KSG9|sebastian

Top Contributor
Gelöst!

Wenn ich mir ne URL von ner Datei in der jar hol und dann nen Stream öffne geht es,
wenn ich direkt den Stream von ner Datei in der Jar hole geht es nicht


Code:
InputStream str = getClass().getResource("blah").openStream();
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
schlingel Webstart/Applet Problem - Classloader-Bug Allgemeine Java-Themen 7
S Problem mit ClassLoader.getSystemResource !! Allgemeine Java-Themen 3
G Classloader Problem Allgemeine Java-Themen 10
G Problem mit URL classloader Allgemeine Java-Themen 10
R Problem mit Classloader Allgemeine Java-Themen 2
C Problem mit ClassLoader Allgemeine Java-Themen 2
krgewb Problem mit Umlauten und Eszett bei InputStream Allgemeine Java-Themen 3
Max246Sch Backtracking Problem Box Filler Allgemeine Java-Themen 6
NightVision402 VisualVM Startskript Problem Allgemeine Java-Themen 3
javaBoon86 Email Server Connection Problem Allgemeine Java-Themen 1
F Problem mit PDFBOX Library Allgemeine Java-Themen 1
A Java modul Problem Allgemeine Java-Themen 4
D Read JSON File Problem Allgemeine Java-Themen 9
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
J Problem mit JasperReports Allgemeine Java-Themen 8
M log4j Problem mit jlink Allgemeine Java-Themen 19
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
torresbig Website login Problem - Jsoup, wie bisher, klappt nicht! Allgemeine Java-Themen 31
P Selenium . getText Problem Allgemeine Java-Themen 9
A Jar zu Exe Problem Allgemeine Java-Themen 13
sserio Variablen Liste erstellt und ein Problem mit dem Index Allgemeine Java-Themen 6
S Folgendes Problem bei einem Programm Allgemeine Java-Themen 1
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
A Thread.sleep Problem Allgemeine Java-Themen 2
A Problem bei der Nachbarschafttest Allgemeine Java-Themen 11
Splayfer Problem: no main manifest attribute Allgemeine Java-Themen 3
G javamail Problem beim Empfangen von Nachrichten Allgemeine Java-Themen 3
Splayfer JDA Problem mit MessageCounter Allgemeine Java-Themen 0
Splayfer Problem mit BufferedWriter Allgemeine Java-Themen 3
F Streams als Alternative für dieses Problem ? Allgemeine Java-Themen 15
N Maven Problem mit Datenbanktreiber (H2 Embedded) Allgemeine Java-Themen 12
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
B Einfach Elemente zweier Arraylisten kreuz und quer vergleichen, min und max Problem? Allgemeine Java-Themen 16
C ArrayList Problem Allgemeine Java-Themen 3
kev34 nim-Spiel problem Allgemeine Java-Themen 1
D Firebase retrieve data Problem, Child Element wird nicht angesprochen Allgemeine Java-Themen 0
G Welches Problem besteht bei den Typparametern? Allgemeine Java-Themen 5
temi Problem mit Aufrufreihenfolge bei Vererbung Allgemeine Java-Themen 3
Sumo_ow "ArrayIndexOutofBoundsException: 2" Array Problem Allgemeine Java-Themen 6
T PIM basierend auf netbeans via AnyDesk Problem Allgemeine Java-Themen 3
xGh0st2014 Problem mit Java Array Allgemeine Java-Themen 1
Kirby.exe Verständnis Problem bei Rucksack Problem Allgemeine Java-Themen 6
B Eclipse-Lombok-Problem Allgemeine Java-Themen 19
I Input/Output ObjectOutputStream - Problem Allgemeine Java-Themen 7
1 Multiple Choice Knapsack- Problem Allgemeine Java-Themen 2
kodela Problem mit strukturiertem Array Allgemeine Java-Themen 18
E Problem mit Gridlayout und Button Allgemeine Java-Themen 2
A Array Problem Allgemeine Java-Themen 8
bueseb84 Problem Allgemeine Java-Themen 0
S Problem mit Arrays Allgemeine Java-Themen 1
D Nullpointer Exception Problem Allgemeine Java-Themen 5
B Problem mit meinen Klassen Allgemeine Java-Themen 6
A HashMap Methode "get()"-Problem Allgemeine Java-Themen 28
J Problem beim Umstellen auf Java jdk 13 Allgemeine Java-Themen 3
J Problem bei Install java 13 Allgemeine Java-Themen 3
X Profitable Reise Problem Allgemeine Java-Themen 32
A Problem beim öffnen von Java-Installern Allgemeine Java-Themen 1
Dann07 Problem mit JavaMail API Allgemeine Java-Themen 26
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
L Klassen Algorithmus für das folgende Problem entwickeln? Allgemeine Java-Themen 30
J Clear-Problem Allgemeine Java-Themen 10
B Problem zu einem Java Projekt Allgemeine Java-Themen 6
S JFileChooser Problem Allgemeine Java-Themen 4
M Traveling Salesman - MST Heuristik Problem Allgemeine Java-Themen 4
J Traveling Salesman Problem Allgemeine Java-Themen 14
E Java Editor Problem mit 2er Exceptions Allgemeine Java-Themen 12
C code oder Bibliotheken für 2-Center Problem Allgemeine Java-Themen 4
M Salesman Problem - Bruteforce Algorithmus Allgemeine Java-Themen 23
S Methoden Problem mit NullPointerException Allgemeine Java-Themen 9
Javafan02 Problem mit if-clause Allgemeine Java-Themen 17
J Lombok Problem mit Konstruktoren bei Verberbung Allgemeine Java-Themen 1
kodela Event Handling Problem mit der Alt-Taste Allgemeine Java-Themen 16
W Threads Problem Allgemeine Java-Themen 15
D (Verständnis-)Problem mit Unterklasse Allgemeine Java-Themen 4
S Problem mit Generic bei unmodifiableCollection Allgemeine Java-Themen 4
S jserialcomm Problem Allgemeine Java-Themen 1
Flynn Thread-Problem... Allgemeine Java-Themen 2
J Generische Interface - Problem Allgemeine Java-Themen 3
G Problem beim GUI Allgemeine Java-Themen 9
L Applet Problem "security: Trusted libraries list file not found" ? Allgemeine Java-Themen 7
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
T Problem mit externen Datenbankzugriff über SSH Tunnel Allgemeine Java-Themen 4
F Problem beim Einlesen einer Textdatei Allgemeine Java-Themen 12
S Java OpenOffice Problem mit Windows-Benutzerwechsel Allgemeine Java-Themen 19
K Threads RAM Problem Allgemeine Java-Themen 20
P Operatoren Problem mit Zähler in recursiver Schleife Allgemeine Java-Themen 2
C Int Problem Allgemeine Java-Themen 8
C J2V8 NodeJs Java Bride Problem und Frage!?!? Allgemeine Java-Themen 1
J Problem bei Hashmap Key-Abfrage Allgemeine Java-Themen 4
C Webseiten Programm problem Allgemeine Java-Themen 5
M LocalDate Problem Allgemeine Java-Themen 4
J "Problem Objektorientierung" Allgemeine Java-Themen 20
geekex Problem Meldung! Was tun?! Allgemeine Java-Themen 19
T Klassen Override Problem Allgemeine Java-Themen 7
L Unbekanntes Problem Allgemeine Java-Themen 1
FrittenFritze Problem mit einer JComboBox, Event temporär deaktivieren Allgemeine Java-Themen 11
Blender3D Java Swing Programm Windows 10 Autostart Problem Allgemeine Java-Themen 2
F HTTPS Zertifikat Problem Allgemeine Java-Themen 3
M OpenCV KNearest Problem Allgemeine Java-Themen 0
Tommy Nightmare Project Euler: Problem 22 Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben