# in eigenes jar-file externe jar einbinden



## hankenberge (10. September 2004)

Ich habe nach der Anleitung von Tom, mit eclipse mir ein eigenes Jar-File erstellt.
dieses läuft auch sehr gut.

Mittlerweile habe ich in mein programm zwei externe jar-Files (jFreeChart and JCommand) eingebunden. Dazu habe ich sie in eclipse in den "JBiuld Path" eingebunden.
Wenn ich aber nun ein jar-Foile erstelle, kommt es zu einer fehlermeldungder virtuell maschine!

mir ist klar, dass das Programm die eingebundenen jars nicht kennt, aber wie kann ich das machen?

Danke

Ingo


----------



## Thomas Darimont (11. September 2004)

Hallo!

Hier mal ein Ansatz für eine mögliche Lösung (eigener ClassLoader),...
man könnte sich aber auch mal in den Sourcen gäniger Applikationsserver wie JBoss oder Tomcat (ja ist auch einer)  umschauen... dort gibt es auch öfters Situtationen in denen jars in jars liegen ... bzw. jars in ears/wars/rars etc...

hier mal das Beispiel:

Ich habe mir ein beliebiges jar geschnappt (swt.jar) und das ganze entpackt und im root des jars eine leere Klasse namens Dummy  und  ein neues Verzeichnis namens test angelegt . Dort habe ich nun das JUnit .jar hinkopiert und das ganze wieder zu einem Jar verpackt. ->swt_test.jar

Mit folgendem Code kann ich nun ganz normale Klassen aus dem junit.jar laden:

```
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

public class Demo {

	public static void main(String[] args) {
		new Demo().doIt();
	}

	private void doIt() {

		try {
			File file = new File(
					"D:/eclipse/workspace/JarInJarDemo/swt_test.jar");
			URL url = file.toURL();
			URLClassLoader ucl = new URLClassLoader(new URL[] { url });
			Class root = ucl.loadClass("Dummy");
			URL res = root.getResource("test/junit.jar");
			System.out.println(res);
			String lookForClass = "junit/framework/Test.class";
			JarInputStream jis = new JarInputStream(res.openStream());
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			JarEntry entry = null;
			while ((entry = jis.getNextJarEntry()) != null) {
				String entryName = entry.getName();
				if (entryName.equals(lookForClass)) {
					byte[] buffer = new byte[1024];
					int len = 0;
					while ((len = jis.read(buffer)) != -1) {
						baos.write(buffer, 0, len);
						break;
					}
				}
			}

			jis.closeEntry();
			jis.close();
			byte[] classBytes = baos.toByteArray();
			baos.close();

			Class clazz = new ClassLoader() {
				public Class defineClass(byte[] data) {
					return super.defineClass("junit.framework.Test", data, 0,
							data.length);
				}
			}.defineClass(classBytes);

			System.out.println(clazz.getName());

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
```

... Probleme gibts allerdings bei Klassen mit inneren Klassen bzw. Anonymen Klassen. Wenn ich mit dieser Methode eine Klasse mit Anonymen Klassen lade kann der dafür zuständige ClassLoader die passenden ClassName$X..class Klassen nicht ausfindig machen ... hier müßte man ene passende findClass / findResource / loadClass  Methode schreiben welche die Klassen findet schreiben.

Na ja war zumindest mal ein Versuch...

Weshalb brauchst du denn genau ein jar im jar ? Falls du Applets verwendest gibts da auch noch den Archive Tag in welchem du eine Liste von Jars angeben kannst die dann inerhalb des Browsers zum Classpath des Browsers hinzugefügt werden ...

Gruß Tom


----------



## hankenberge (13. September 2004)

danke schon mal.

wieso ich nur ein jar haben will! weil man so eine abgeschlossene anwendung hat, und nicht zig dateien mitschleppen muss. (vorgabe meines Diplombetreuers :-( )

wie würde es denn gehen, wenn ich das jar nicht ins andere jar einbinde sondern extern mitnehme?
ich muss dann ja den classpath setzen, damit er die dateien findet. wie könnte ich denn das machen?

danke


----------



## nicolam (27. Oktober 2004)

Das Problem hab ich auch. Ich brauche eine jar-Datei, welche mehrere jar-Dateien enthält, da ich in dem Programm nur eine jar einfügen kann. Hat da jemand vielleicht noch eine Idee?
Danke!


----------



## squeaker (27. Oktober 2004)

Eine einfache Möglichkeit - zur Auslieferung - ist es einfach alle benötigten jars zu entpacken und diese Dateien dann gemeinsam in ein jar Zusammenpacken. Funktioniert, und ist für eine begrenzte Anzahl mal praktikabel. Für einen automatischen Auslieferungsprozess aber ist es eher weniger geeignet.


----------



## AKST (27. Oktober 2004)

Am besten mit ant eine jar erstellen in der du im classpath auf die benötigten jars referenzierst. 
Die Lösung ist nur ein paar Zeilen weiter unten:
http://www.tutorials.de/forum/showthread.php?t=173260


----------



## nicolam (27. Oktober 2004)

Danke! 
Mit der build.xml hat es schon mal funktioniert, da ist jetzt bloß noch ein anderer Fehler ( der passt aber eher zu einem anderen Thema ;-)


----------



## squeaker (28. Oktober 2004)

Weiß jemand wie der Ant-Task funktioniert den Netbeans verwendet? Ich würde ihn gerne modifizieren - weiß aber nicht wie.


----------

