# Klasse aus Jar File laden



## PowerPaul (28. Jun 2006)

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?


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

		
	}
	
}
```


----------



## thE_29 (28. Jun 2006)

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

Du wolltest eine Klasse laden die sich in einem externen Jar File befindet?


----------



## PowerPaul (28. Jun 2006)

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 (28. Jun 2006)

Klasse JarFile anschauen (such hier im Board oder API)


----------



## PowerPaul (28. Jun 2006)

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?


----------



## thE_29 (28. Jun 2006)

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!


----------



## PowerPaul (28. Jun 2006)

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!
> ...



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.


----------



## thE_29 (28. Jun 2006)

Naja, wenn du mir das mal zeigen kannst, aber hier ein 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();
	}
```


----------



## PowerPaul (28. Jun 2006)

danke, ich kucks mir mal an


----------



## Murray (28. Jun 2006)

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.

```
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


----------



## PowerPaul (28. Jun 2006)

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



ok danke. muss ich also doch ein bissel if abfragen. danke fuer den denkanstoß. @beide


----------



## PowerPaul (29. Jun 2006)

thE_29 hat gesagt.:
			
		

> Naja, wenn du mir das mal zeigen kannst, aber hier ein Code
> 
> 
> ```
> ...



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


----------



## thE_29 (29. Jun 2006)

Ja, aber ohne .class hinten!


Also bei JButton wäre es

javax.swing.JButton

Wenn du Fehler hast, poste mal die Exception!


----------



## Gast (28. Jun 2007)

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


----------

