Klasse aus Jar File laden

Status
Nicht offen für weitere Antworten.

PowerPaul

Mitglied
hi,

ich braeuchte recht dringend hilfe bei einem problem. zum theman jar file gibts hier war schon viel aber ich finde keine gute loesung fuer mein problem.

ich habe halt ein groeßeres program in welchen auch per classloader klassen geladen werden. das funktioniert so auch alles gut. nur soll das ganze jetzt als jar file verpackt werden und sobal das der fall ist werden die klassen welche per loeader aus einem package geladen werden nichtmehr geladen.

kann ich irgentwie dafuer sorgen das das program bei der pfad angabe vom jar file ausgeht?
ich habe mir schon ueberlegt die ganzen klassen einfach in einen temp ordner zu entpacken. nur finde ich dazu keine java methode (wobei ich eigentlich davon ausgehe das es sowas gibt, wenn ja , welche methode?) und ist das auch doof weil mein jar file dan nicht mehr umbenant werden kann. (den pfad in welchen sich das file befindet bekomme ich ja leicht ueber system raus. )

einfach so etwas geht sicher nicht, oder: c:\foo\bar.jar\klasse1.class ? also java sagen das es jar files einfach wie ordner behandeln soll?

Code:
public class Loader<A> {

	private A newInstance(String path, String classname) throws Exception 
	{
		URL url = new File(path).toURL();
		URLClassLoader cl = new URLClassLoader(new URL[] { url });
		Class<A> c = (Class<A>) cl.loadClass(classname);
		return c.newInstance();
	}
	
		
	public ArrayList<A> getAllClasses(String dir)
	{
		File handle = new File(dir);
		
		ArrayList<A> list = new ArrayList<A>();
					
		try{
		
			for(String x : handle.list() )
			{
				if((x.contains(".class")) && !(x.contains("Interface")))
				{
					x=x.replace(".class",""); 
					A temp = newInstance("",dir+"."+x);
					list.add(temp);
				}
						}
				
		}catch(Exception e){};		
	
		return list;	

		
	}
	
}
 
Bevor ich irgendwas unpacken würde, was war dein Ursprungsgedanke?

Du wolltest eine Klasse laden die sich in einem externen Jar File befindet?
 
Nein, also es ist ein kompletes Program wobei bestimmte funktionen erweiterbar sind indem man einfach eine klasse hinzufuegt die ein bestimmtes interface implementiert. damit man die neuen klassen nicht an allen moeglichen stellen im code eintragen muss, kuckt der loader einfach in ein package rein (des gleichen projektes) und laed dort alles raus was auf .class endet. das funktioniert auch alles darum gehts nicht.

jetzt soll das teil aber als jar datei abgeliefert werden. also muss ich dem loader irgentwie sagen das er in der jar file drin kucken soll. ich geh mal davon aus das genau das bei der pfad angabe nicht funktioniert. daher das er sonstwo kuckt nur nicht im jar file.
 
thE_29 hat gesagt.:
Klasse JarFile anschauen (such hier im Board oder API)

also respekt , das hat mich jetzt echt weitergebracht, vielen dank.

also das file entpacken und dan auf diesem temp ordner arbeiten geht jetzt. allerdings ist diese losung total schlecht da ich jetzt mein prog nichtmehr von eclipse aus starten kann weil er ja jetzt immer versucht eine jar datei zu entpacken.

hat nicht noch wer einen tip oder link wie ich besser an datei ran komme?
 
Weil du selber ja nicht weißt was du willst..


Willst du jetzt irgendwo hinpacken? Falls ja, ist das die korrekte Antwort!

Willst du es gleich aus dem Jar laden (was ich dich gefragt habe) ist das natürlich net die Antwort..

Du wolltest das ja auch net..


ch habe mir schon ueberlegt die ganzen klassen einfach in einen temp ordner zu entpacken. nur finde ich dazu keine java methode

Mit JarFile geht das!

Frage => Antwort!
 
thE_29 hat gesagt.:
Weil du selber ja nicht weißt was du willst..


Willst du jetzt irgendwo hinpacken? Falls ja, ist das die korrekte Antwort!

Willst du es gleich aus dem Jar laden (was ich dich gefragt habe) ist das natürlich net die Antwort..

Du wolltest das ja auch net..


ch habe mir schon ueberlegt die ganzen klassen einfach in einen temp ordner zu entpacken. nur finde ich dazu keine java methode

Mit JarFile geht das!

Frage => Antwort!

ich bin der meinung das ich schon recht deutlich gesagt habe das ich AUS DER JAR-FILE laden will. habe doch geschrieben das in der jar das ganze projekt drin steckt.
 
Naja, wenn du mir das mal zeigen kannst, aber hier ein Code

Code:
    File fJar = new File(strJar); //Pfad zur jar Datei halt
    URL url = null;
    try
    {
      //holt sich das jar file in url form
      url = fJar.toURL();
      URLClassLoader urlcl = new URLClassLoader(new URL[] {url});
      String strPackage = "at.jta.bla"; //hier halt das package eintragen was du willst
	  Class clazz = Class.forName(strPackage, true, urlcl);
	  
	  //jetzt könntest du Konstruktoren oder ähnliches laden, ich lade einen Konstruktor OHNE parameter als Bsp
      Constructor cons = null;
      cons = clazz.getConstructor(null); //null heißt er hat keine Parameter, hier müsstest du ein class[] Objekt haben mit den Parametern wenn er welche hat
	  Object instance = cons.newInstance(null); //führt den Konstruktor aus -> mit diesem instance Objekt könntest du jetzt alle Methoden aus der Klasse starten
	}
	catch(Exception ex)
	{
		ex.printStackTrace();
	}
 
Wenn ich das richtig verstanden habe, dann möchtest Du zur Laufzeit Klassen laden, die
a) zum gleichen Package gehören wie der aufrufende Code,
b) sich im gleichen Jar-File bzw. (im Falle von einzelnen, nicht in ein Jar-File verpackten Klassen) im gleichen Verzeichnis befinden und
c) deren Namen nicht vorab bekannt sind (offenbar handelt es sich um eine Art Plugin-Konzept)

Dazu muss man ja zunächst wissen, woher der aufrufende Code gerade geladen wurde.
Code:
Class cls = this.getClass();
String clsNam = cls.getName();
String binaryClsNam = clsNam.replace( '.', '/') + ".class";
URL clsURL = ClassLoader.getSystemResource( binaryClsNam);
System.out.println( clsNam + " -> " + binaryClsNam + " -> " + clsURL);

Damit bekommt Du Ausgaben in der Art:
Jar-File: test.Test -> test/Test.class -> jar:file:/C:/home/work/060628/jars/test.jar!/test/Test.class
Class-Files: test.Test -> test/Test.class -> file:/C:/home/work/060628/lib/test/Test.class

Jetzt muss man zwischen beiden Varianten unterscheiden; im Falle von Class-Files ermittelst Du aus der URL das Verzeichnis, in dem Du suchen musst (ähnlich wie bisher)

Beim Jar-File konstruierst Du wie thE_29 vorgeschlagen ein java.util.jar.JarFile-Objekt und kannst dann über dessen entries-Methode die enthaltenen Klassen finden.

HTH
 
Murray hat gesagt.:
Wenn ich das richtig verstanden habe, dann möchtest Du zur Laufzeit Klassen laden, die
a) zum gleichen Package gehören wie der aufrufende Code,
b) sich im gleichen Jar-File bzw. (im Falle von einzelnen, nicht in ein Jar-File verpackten Klassen) im gleichen Verzeichnis befinden und
c) deren Namen nicht vorab bekannt sind (offenbar handelt es sich um eine Art Plugin-Konzept)

Dazu muss man ja zunächst wissen, woher der aufrufende Code gerade geladen wurde.
Code:
Class cls = this.getClass();
String clsNam = cls.getName();
String binaryClsNam = clsNam.replace( '.', '/') + ".class";
URL clsURL = ClassLoader.getSystemResource( binaryClsNam);
System.out.println( clsNam + " -> " + binaryClsNam + " -> " + clsURL);

Damit bekommt Du Ausgaben in der Art:
Jar-File: test.Test -> test/Test.class -> jar:file:/C:/home/work/060628/jars/test.jar!/test/Test.class
Class-Files: test.Test -> test/Test.class -> file:/C:/home/work/060628/lib/test/Test.class

Jetzt muss man zwischen beiden Varianten unterscheiden; im Falle von Class-Files ermittelst Du aus der URL das Verzeichnis, in dem Du suchen musst (ähnlich wie bisher)

Beim Jar-File konstruierst Du wie thE_29 vorgeschlagen ein java.util.jar.JarFile-Objekt und kannst dann über dessen entries-Methode die enthaltenen Klassen finden.

HTH

ok danke. muss ich also doch ein bissel if abfragen. danke fuer den denkanstoß. @beide
 
thE_29 hat gesagt.:
Naja, wenn du mir das mal zeigen kannst, aber hier ein Code

Code:
    File fJar = new File(strJar); //Pfad zur jar Datei halt
    URL url = null;
    try
    {
      //holt sich das jar file in url form
      url = fJar.toURL();
      URLClassLoader urlcl = new URLClassLoader(new URL[] {url});
      String strPackage = "at.jta.bla"; //hier halt das package eintragen was du willst
	  Class clazz = Class.forName(strPackage, true, urlcl);
	  
	  //jetzt könntest du Konstruktoren oder ähnliches laden, ich lade einen Konstruktor OHNE parameter als Bsp
      Constructor cons = null;
      cons = clazz.getConstructor(null); //null heißt er hat keine Parameter, hier müsstest du ein class[] Objekt haben mit den Parametern wenn er welche hat
	  Object instance = cons.newInstance(null); //führt den Konstruktor aus -> mit diesem instance Objekt könntest du jetzt alle Methoden aus der Klasse starten
	}
	catch(Exception ex)
	{
		ex.printStackTrace();
	}

nochmal ne frage dazu: ist das bei strPackage so gemeint "Package.Foo.class" ? also kann ich da direkt eine class datei waehlen ? ich weis ich koennte es probieren aber ich schlage mich jetzt schon 4 stunden mit dem bloeden problem rum und keine version will funktionieren (naja jedenfalls kann ich jetzt zwischen file und jar unterscheiden).... ich kann eclipse enfach nichtmehr sehen. danke
 
Ja, aber ohne .class hinten!


Also bei JButton wäre es

javax.swing.JButton

Wenn du Fehler hast, poste mal die Exception!
 
Hi, ich habe ebenfalls den Jar-Loader-Code genommen und frage mich jetzt, wie ich über das "Instance"-Object die Methoden der Klasse aufrufen kann.
Wenn ich einfach interface.Methodenname mache, dann sagt er mir, dass ein Object der Klasse "Object" diese Methode nicht kennt.

Gruss
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben