# ClassLoader



## MQue (19. Jul 2007)

Hallo,

ich lese gerade das Buch "Java ist auch eine Insel" und wollte folgende Klasse ausprobieren aber leider habe ich keine Ahnung von ClassLoaders.
Class c = Class.forName("LightedPushButton.build.classes"); -> welchen Pfad muss ich hier angeben, irgendeinen auf meinem Computer oder einen Pfad in einem bestimmten Verzeichnis oder iwe geht das?

herzlichen Dank für Antworten!!

lg
Michl



```
import java.net.*;

public class FindClassLocation {
	static String findLocation(Class clazz)
	{
		ClassLoader loader = clazz.getClassLoader();
	
		if (loader == null)
			return null;
	
		URL url = loader.getResource(clazz.getName().replace('.', '/') + ".class");
	
		return (url != null) ? url.toString() : null;			
	}
	
	public static void main (String[] args) throws Exception
	{
		Class c = Class.forName("LightedPushButton.build.classes");
	
		System.out.println("Class: " + c.getName());
		System.out.println("Filename: " + findLocation(c));
	}


}
```


----------



## Roar (19. Jul 2007)

> welchen Pfad muss ich hier angeben


gar keinen, sondern den namen der klasse:


			
				dokumentation hat gesagt.:
			
		

> forName(String className)


----------



## Guest (19. Jul 2007)

Roar hat gesagt.:
			
		

> ...gar keinen, sondern den namen der klasse:


und zwar vollstänfig, mit Package.


----------



## MQue (19. Jul 2007)

und wo kann di eKlasse sein, in dem Ordner, wo ich mein aktuelle Projekt habe oder irgendwo?

lg und vielen Dank


----------



## Murray (19. Jul 2007)

Michael1234 hat gesagt.:
			
		

> und wo kann di eKlasse sein, in dem Ordner, wo ich mein aktuelle Projekt habe oder irgendwo?


Irgendwo im Classpath


----------



## MQue (19. Jul 2007)

was heißt im ClassPath? Den Pfad, den ich in der Umgebungsvariable eingegeben habe


----------



## Murray (19. Jul 2007)

Ja, es sei denn, du hättest die VM mit der "-cp"-Option gestartet; in dem Fall überschreibt der da angegebene Pfad die Umgebungsvariable. Und wenn du die VM mit -"jar" gestartet hast, muss sich die Klasse in diesem Jar-File befinden; auch in diesem Fall wird der Classpath nicht gezogen.

Und noch eine Ausnahme: Klassen aus der JRE werden in jedem Fall gefunden, egal wie der explizite Classpath gesetzt ist.


----------



## MQue (19. Jul 2007)

ich verstehs nicht, ich bekomme immer diese Exception:
was mache ich da falsch?


```
Exception in thread "main" java.lang.ClassNotFoundException: LightedPushButton
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Unknown Source)
	at FindClassLocation.main(FindClassLocation.java:20)
```


----------



## Murray (19. Jul 2007)

Was ist den LightedPushButton für eine Klasse? Deine eigene? Hat die ein Package? Lieg das Class-File dort, wo auch FindClassLocation.class liegt? Wie rufst du FindClassLocation auf?


----------



## Gast (20. Jul 2007)

Aber wie kann ich dem ClassLoader einen Pfad mitgeben, wenn er angenommen alle Klassen in jar Files unter D:\jars laden soll???


----------



## Guest (20. Jul 2007)

Hallo ich habe ein ähnliches Problem.
Ich habe zum Bespiel diese Klasse, welche unter C:\ liegt:

```
public class NeuZuLadeneKlasse
{
  static
  {
    System.out.println( "NeuZuLadeneKlasse gefunden" );
  }
  
  public static void ausgabe()
  {
	  System.out.println("static Methode ausgabe wurde aufgerufen");
  }
  
  public void ausgabe2()
  {
	  System.out.println("Methode ausgabe2 wurde aufgerufen");
  }
  
}
```

Und diese Klasse zum Laden:

```
import java.io.File;
import java.net.*;

public class KlassenNeuladen
{
  static Object neuesExemplar( String pfad, String klassename ) throws Exception
  {
    URL url = new File( pfad ).toURL();

    URLClassLoader cl = new URLClassLoader( new URL[]{ url } );

    Class c = cl.loadClass( klassename );

    return c.newInstance();
  }

  public static void main( String args[] ) throws Exception
  {
    Object neu = neuesExemplar( "c:/", "NeuZuLadeneKlasse" );
    //neu.ausgabe();
  }
}
```

Das funktioniert auch.
Nun stellt sich mir die Frage, wie ich zum Beispiel ein Object dieser Klasse erstellen kann und Methoden ausführen kann?
Zusätzlich würde ich gerne wissen wie ich diese Klasse laden kann wenn sie in einem jar File liegt, sagen wir z.B. in c:\tmp.jar in dem package testA.testB.NeuZuLadendeKlasse ??


----------



## Gast (20. Jul 2007)

Das kann doch nit sein das keiner, aber wirklich keiner weis wie man z.B. einen ClassLoader überscreiben kann, also somit jede Klasse in einem jar file von diesen geladen/erneut geladen wird.


----------



## Gast (20. Jul 2007)

Scheinbar kann das doch sein!!


----------



## Wildcard (20. Jul 2007)

Einen eigenen Classloader kannst du genau dann einsetzen wenn keiner der Standard Classloader deine Klasse findet.
Dein konkretes Problem ist nun welches?


----------



## Gast (20. Jul 2007)

Ich habe eine Klasse, welche sich an einem bestimmten Ort im FileSystem in einem jar File befindet, die ich ladet möchte.


----------



## Guest (20. Jul 2007)

Also es sieht bei mir zur Zeit so aus:

```
public static void main( String args[] ) throws Exception
  {    
	  Class clazz = new URLClassLoader(new URL[] { new File("c:/").toURL()}).loadClass("NeuZuLadeneKlasse");
	  System.out.println(clazz.getName());
	  Method[] method = clazz.getMethods();
	  
	  Method methodTestAusgabe = clazz.getMethod( "ausgabe", new Class[0]); 
	  Object o = clazz.newInstance(); 
	  methodTestAusgabe.invoke( o, new Object[0]); 
	  
	  for(int i=0; i<method.length; i++)
	  {
		  System.out.println(method[i].getName());
	  }
  }
```

Das heist, das ich die Klasse "NeuZuLadendeKlasse" von C:\ laden möchte und davon ein Object erzeugen 
will, damit ich diese in meinen weiteren Projekt ganz normal nutzen kann.

Und das jede weitere Object von dieser Klasse wieder ganz normal mittels des Namen der Klasse erstellt werden kann.

```
NeuZuLadendeKlasse neu = new NeuZuLadendeKlasse();
neu....
```

So sollte das laufen.


----------



## Murray (20. Jul 2007)

Das sollte der URLClassLoader doch können, wenn man der Dokumentation Glauben schenken kann (meistens kann man das).


			
				javadoc hat gesagt.:
			
		

> This class loader is used to load classes and resources from a search path of URLs referring to both JAR files and directories. Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be opened as needed.


----------



## Guest (20. Jul 2007)

```
Class NeuZuLadendeKlasse = new URLClassLoader(new URL[] { new File("c:/").toURL()}).loadClass("NeuZuLadeneKlasse");
	  NeuZuLadendeKlasse test = new NeuZuLadendeKlasse();
```

Ich wollte das das irgendwie so in etwa funktioniert, aber das tut es nicht.

Brauche Hilfe.


----------



## DarkHappyAffe (6. Aug 2007)

Bau dir doch einfach ein Interface, dass die zu ladende Klasse implementieren muss. Dann kannst du es wie folgt machen (wichtig sind zeilen 14 und 15 von ClTest.java):

ClassToLoad.java

```
package org.sofarockers.addon;

import org.sofarockers.Bar;

public class ClassToLoad implements Bar {
	
	static {
		System.out.println("Hallo Welt! Ich wurde geladen!");
	}
	
	public static void printFoo() {
		System.out.println("Foo!");
	}
	
	public void printBar() {
		System.out.println("Bar!");
	}
}
```

Bar.java

```
package org.sofarockers;

public interface Bar {
	
	public void printBar();
}
```

ClTest.java

```
package org.sofarockers;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class ClTest {

	public static void main(String[] args) {
		try {
			URL url = new File("/Users/stefan/workspace/Test/org/sofarockers/addon/").toURI().toURL();
			URLClassLoader cl = new URLClassLoader(new URL[]{url});
			Class<?> c = cl.loadClass("org.sofarockers.addon.ClassToLoad");
			Bar o = (Bar) c.newInstance();
			o.printBar();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}
```


----------

