# jar einfach so übernehmen und ausführen, das geht doch nicht?



## oraclin25 (13. November 2013)

Hallo zusammen,

ich habe soeben eclipse installiert, erstes Programm damit erstellt, inklusive Pakete usw.  Einige logische Fragen habe ich:

1. Bei Eclipse ist ja ein Workspace-Path zu setzen.
2. In diesem Workspace befinden sich dann all die Projekte, deren Source-Codes usw.

Angenommen, ich erstelle ein JAR-File (ratna.jar) von meinemProgramm.java, was abhängig von anderen Projekten und externen JAR-Files ist.  Kann ich denn ratna.jar ohne weiteres auf ein Linux-Filesystem kopieren und verwenden?  Gibt's hierbei Überlegungen wegen der Pfade?

Vielen Dank für Eure Hilfe.

Viele Grüße aus Rheinland,

Eure Ratna


----------



## Thinker (13. November 2013)

oraclin25 hat gesagt.:


> Angenommen, ich erstelle ein JAR-File (ratna.jar) von meinemProgramm.java, was abhängig von anderen Projekten und externen JAR-Files ist.  Kann ich denn ratna.jar ohne weiteres auf ein Linux-Filesystem kopieren und verwenden?  Gibt's hierbei Überlegungen wegen der Pfade?



Das kommt darauf an: 

Dein Programm muß grundsätzlich unter Linux laufen. 
Entweder muß das Jar alle Abhängigkeiten enthalten oder aber sie müssen per Hand mit auf das System kopiert werden. 

Wenn dein jar alle Abhängigkeiten enthalten soll, dann kannst du es über die eclipse-exportfunktion erstellen. Da mußt du dann "nur" ein Runnable-Jar erzeugen und die Option "Extract required libraries into generated jar" anwählen.


----------



## sheel (13. November 2013)

Ergänzend:
Ja, auf ein Linuxsystem kopieren geht.
Die Abhängigkeiten müssen in den Verzeichnissen des Classpath enthalten sein,
also a) müssen sie mitkopiert werden (oder direkt in der einen Jar drin sein)
und b) in einem der (relativen) Verzeichnisse,
die man als CP in der manifest-Datei des Jar angegeben hat.
zB. selbes Verzeichnis (also .) wie dir Jar-Datei ist schon mal nicht verkehrt.

Und man kann Javaprogramme schreiben, die unter Windows gut funktionieren
und unter Linux nicht...Wenn das Programm zB. mit Fehlermeldung abbricht,
wenn es das Verzeichnis "C:\Windows" nicht findet.
Dass sowas zu vermeiden ist sollte klar sein.


----------



## oraclin25 (30. November 2013)

Hallo Thinker und sheel,

das heißt, es gibt 2 Alternativen:
1. Abhängigkeiten in dem Jar-File müssen definiert und enthalten sein.
2. Abhängigkeiten müssen per Hand ins Filesystem von Unix kopiert werden.

Zu 1.)
Kann man dies mittels einem Ant-Skript schaffen?

Vielen Dank Euch.

Viele Grüße aus Rheinland


----------



## Thinker (30. November 2013)

oraclin25 hat gesagt.:


> Hallo Thinker und sheel,
> 
> das heißt, es gibt 2 Alternativen:
> 1. Abhängigkeiten in dem Jar-File müssen definiert und enthalten sein.
> ...



Sachlich richtig, entweder sind die enthalten oder aber sie müssen manuell reinkopiert werden. 
Und mittels ant kann man das machen, ja, indem man dem Jar-Task ein zipgroupfileset übergibt, wenn ich mich recht erinnere


----------



## oraclin25 (30. November 2013)

Hallo Thinker,

mhh.. eine Sache habe ich noch nicht verstanden:
Abhängigkeiten manuell reinkopieren.  Meinst Du damit, auf dem Unix-System all die Pfade zu erstellen entsprechend meiner Verzeichnisstruktur in Windows, wo ich die Programme entwickelte?

Viele Grüße aus Rheinland,

Eure Ratna


----------



## Thinker (30. November 2013)

Nein, die jars müssen ja nur im Classpath aufgelistet sein, du mußt also dafür sorgen, daß dieser unter Linux stimmt. 

wenn du dirs einfach machen willst, dann legst du unter Windows eine Verzeichnisstruktur an, die es auch unter Linux gibt. Aber das ist kein Muß.


----------



## oraclin25 (1. Dezember 2013)

Hallo Thinker,

zu der schwierigeren Alternative:

das heißt, wenn ich zum Beispiel unter Windows einen externen Jar verwende und dieser steht unter dem Pfad bzw. Package com.google.gwt.user.User.  Wie muss dann die CLASSPATH-Variable unter Linux aussehen?

Vielen Dank.

Viele Grüße aus Rheinland,

Eure Ratna


----------



## saftmeister (1. Dezember 2013)

Hallo,

in die Umgebungsvariable CLASSPATH kommen jar-Dateien durch den platform-spezifischen Path-Separator getrennt (System.getProperty("path.separator") => http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html) rein. Man kann aber auch 


```
java -cp jar1.jar;jar2.jar... de.tutorials.classpath_beispiel.MainClass
```

aufrufen.


----------



## oraclin25 (1. Dezember 2013)

Hallo zusammen,

am besten mache ich mal ein konkretes Beispiel.  Mein Hauptprogramm heißt Hauptprog.java, das so aussieht:

import de.tutorials.Classname;

public class Hauptprog{
...
...
}

Die externe Klasse Classname ist enthalten in dem JAR-File de.tutorials.jar

Ich erstelle nun für mein Hauptprog das JAR-File namens Hauptprog.jar

Jetzt geht es ums Kopieren auf das Linux-Filesystem:
1. Wo soll ich nun de.tutorials.jar hinkopieren?
2. Wie soll die CLASSPATH-Umgebungsvariable aussehen?

Vielen lieben Dank.

Viele Grüße aus Rheinland,

Eure Ratna


----------



## saftmeister (1. Dezember 2013)

1. Das ist dir überlassen ;-)

Nein ernsthaft, das ist wirklich egal, Hauptsache du gibst im Classpath den korrekten Pfad zu den Jars an. Wenn du alle Jars ins gleiche Verzeichnis kopierst, ist die Zusammenstellung des Klassenpfades natürlich sehr einfach, was uns direkt zur nächsten Frage bringt:

2. Abhängig davon, wo deine Jar-Dateien denn nun liegen, gibst du beim Classpath den Pfad zur Jar-Datei entweder absolut (/ewig/langer/dateipfad/zur/jar-datei.jar) oder relativ (./jar-datei.jar) an. Angenommen, du hast alle jars im gleichen (aktuellen Verzeichnis liegen). Und angenommen, deine Main-Klasse liegt im Package-Pfad de.tutorials.classpath_beispiel. Dann sieht ein Shell-Script so aus:


```
CLASSPATH=./de.tutorials.jar:./Hauptprog.jar

export CLASSPATH

java de.tutorials.classpath_beispiel.Hauptprog
```

Am sichersten ist natürlich die Variante mit dem absoluten Pfad, aber wenn du genau weißt, wo der Kram liegt, gehen auch relative Pfade. Das macht die Sache dann natürlich portabler.

Bei Windows ist es im Übrigen genauso.


----------



## oraclin25 (1. Dezember 2013)

Hallo saftmeister,

mein externes Jar liegt aber unter Windows unter folgendem Pfad:
C:EclipseWS\src\de\tutorials\ext-jar.jar

Und meine Hauptprog-Klasse liegt unter:
C:\EclipseWS\src\Hauptprog.java

Vielleicht erstmal eine ganz einfache Sache, in dem Programm Hauptprog.java kann folgendes Import geben:

Import de.tutorials.ext-jar.Class-Name

****?


----------



## saftmeister (1. Dezember 2013)

Ich glaube, du bringst hier zwei Sachen durcheinander.

Package-Pfad != Klassen-Pfad (Classpath)

- Der Classpath beinhaltet Bibliotheken (Jars) die zur Compile- oder Laufzeit verfügbar sein sollen. Wenn du zur Compile-Zeit ein Jar in den Classpath hinzufügst, und aus dem Jar mittels import eine Klasse in dein eigenes Projekt einbindest, brauchst du das Jar auch im Classpath zur Laufzeit.

- Jede Klasse hat einen Package-Pfad (ggf. auch den default-Package-Pfad). Der zeigt einfach nur an, in welchem Java-Package (nicht JAR-File) die Klasse liegt. Das ist im Grunde der Namensraum, in dem die Klasse existiert. Eine Klasse kann man auch ohne Jar deployen, sie hat dann dennoch einen Package-Pfad. Der Package-Pfad hat den Zweck, Klassen mit unterschiedlicher Funktionalität aber gleichem Klassen-Namen zu ermöglichen (bspw. de.tutorials.Klasse1 => com.google.Klasse1).

Das es möglich sein soll, mittels Angabe des Jars eine Klasse zu importieren, war mir bislang nicht bekannt. Habe es noch nicht ausprobiert, klingt auch ein wenig unlogisch. Das würde bedeuten, ich kann das Library-Jar nicht austauschen, ohne meine Java-Klasse neu kompilieren zu müssen => unportabel.

Vielleicht wäre es ratsam, wenn du dir erstmal angewöhnst, dein Projekt korrekt aufzubauen. Damit meine ich: Libraries gehören NICHT in den src-Ordner. Schau dir mal diese Projekt-Struktur an:

Workspace-Pfad = C:\EclipseWS
Projekt = Test
Libraries = de.tutorials.jar
Main-Klasse = de.ratna.Hauptprogramm

Dann ergibt sich folgende Ordner-Struktur


```
c:\EclipseWS\Test
     |
     |------------- bin
     |                     +-------- de
     |                                    +--------- ratna
     |                                                      +---------- Hauptprogramm.class
     +------------- src
     |                     +-------- de
     |                                    +--------- ratna
     |                                                      +---------- Hauptprogramm.java (hier wird eine Klasse aus de.tutorials.jar importiert)
     +------------- lib
                           +-------- de.tutorials.jar
```

Eclipse erstellt den bin-Ordner normalerweise automatisch und legt dort die kompilierten Java-Klassen ab (.java => .class).
Wenn du jetzt ein Jar daraus erstellst (was im Grunde ein Zip-File ist), werden die kompilierten Java-Klassen in der Struktur aus dem bin-Ordner in das Archiv komprimiert. Du kannst ja spaßeshalber mal ein .jar-File in Winzip oder 7zip (den Packer deiner Wahl) laden und dir die Ordnerstruktur darin anschauen.
Damit das Importieren von Klassen aus "externen" Jars funktioniert, muss es Eclipse (oder jede andere IDE) die Jars im Classpath haben, sonst hättest du eine unaufgelöste Abhängigkeit.
Und damit du zur Laufzeit keine ClassNotFoundException bekommst, muss die "externe" Library de.tutorials.jar auch im Classpath hinterlegt sein.
Java "entpackt" dann die zu importierenden Klassen (und ihre weiteren Abhängigkeiten) und stellt die darin programmierte Funktionalität bereit.


----------



## oraclin25 (1. Dezember 2013)

du bist der Held des Tages


----------



## oraclin25 (1. Dezember 2013)

> - Der Classpath beinhaltet Bibliotheken (Jars) die zur Compile- oder Laufzeit verfügbar sein sollen. Wenn du zur Compile-Zeit ein Jar in den Classpath hinzufügst, und aus dem Jar mittels import eine Klasse in dein eigenes Projekt einbindest, brauchst du das Jar auch im Classpath zur Laufzeit.



Dann würde die CLASSPATH-Umgebungsvariable so aussehen?

CLASSPATH=./de.tutorials.jar:./de/ratna

Wie kommt man aber von da auf hier:

CLASSPATH=./de.tutorials.jar:./Hauptprog.jar


----------



## saftmeister (1. Dezember 2013)

Eclipse-Projekt->Rechte Maustaste->Export... Dort im Assi Java->Jar File und auf Next. Dann im Field "JAR file" den Pfad zur neuen Jar-Datei angeben und auf "Finish"

Das daraus resultierende Jar kannst du dann hinkopieren, wo du es gern hättest.


----------



## oraclin25 (3. Dezember 2013)

Hallo zusammen,

vielen Dank für Eure Hilfestellungen bisher, hat geklappt und ich habs verstanden.

In dem Projekt ist es so konfiguriert, dass zur Distribution(Jar-Files, Java-Doc, usw..) ein Ant-Build-File Gebrauch gemacht wird.  Es ist so, dass bei einer Aktualisierung eines .java-Files man einfach das entsprechende Programm noch mal ausführen tut, NICHT aber das Build-File ausführen.  Ist das eigentlich Standard?

Ich dachte immer, wenn man eine Änderung im Code vorgenommen wird, dass das Build-File neu angestoßen werden muss, damit all die Jars, Java-Doc usw. neu erstellt werden.  Nun ist es aber nicht so.

Könnt Ihr mir dazu was sagen bitte?  Danke schön...

Viele Grüße aus Rheinland,

Eure Ratna


----------

