# Jar mit eigener JRE ausliefern



## Kaibear (6. Dez 2013)

Moin moin,

ich habe ein Tool, dass in JRE 7 compiliert wurde. Nun soll dieses aber auch auf anderen System verfügbar sein, die kein JRE 7 haben und auch keines haben sollen.

Deshalb stellt sich mir die Frage: Wie kann ich mit dem jar-File meines Tools eine eigene JRE mitliefern, auf die mein Tool zurückgreift?

Ich habe es mit dem selben Ansatz wie beim Auto-Start einer .jar von CD aus versucht. Aber dabei greift das ganze irgendwie nicht, das Tool öffnet sich durch die Batch-Datei nicht bzw. nennt einen Fehler, der auf das fehlende JRE zurückschließen lässt.

Beim googlen stoße ich entweder auf Ergebnisse, die mir als Leihen wenig Bezug zur Thematik liefern und andere Ergebnisse verlangen die aktuelle JRE mitzuliefern, allerdings basierend auf einer Installation dieser, WAS gerade NICHT geschehen soll. Also soll mein Tool nur auf die Sachen zurückgreifen, die es wirklich brauch um ausgeführt zu werden.

Gibt es solche Möglichkeiten?

Wenn ja, wie wende ich diese an?


----------



## nvidia (6. Dez 2013)

Egal wie, eine Java-Anwendung benötigt immer ein JRE. Du wirst also als Ergebnis ein JRE auf dem
Zielrechner haben. Entweder installiert oder nur kopiert. Da Ersteres nicht für dich in Frage kommt
bleibt nur das kopieren.

Wir liefern z.B. die dem aktuellsten JDK beiliegende Server-JVM mit aus. Für 64Bit befindet die sich
meist unter C:\Program Files\Java\jdk1.7.0_xx\jre. Diesen "jre"-Ordner kann man einfach nehmen 
und kopieren und mit ausliefern. Um das Jar dann damit zu starten muss man sich im einfachsten
Fall eine Batchdatei schreiben die die java.exe mit dem Jar aufruft. Ich bevorzuge jedoch 
Launch4j - Cross-platform Java executable wrapper um 
einen Launcher zu bauen der dann das Jar mit der beigelegten JRE startet. Beim Kunden sieht dann 
das Ordnerlayout wie folgt aus


```
|-Laufwerk
     |-Ordner in dem das Programm liegt
         |-jre              <<< Kopierter Ordner aus dem Entwicklungs-JDK
         |-Programm.exe    <<< Launch4j generierte exe
         |-Programm.l4j.ini <<< JVM/Kommandozeileneinstellungen für exe
         |-Ordner-X    <<< irgendwelche weiteren Ordner
         |-Ordner-Y
         ....
```


----------



## Kaibear (9. Dez 2013)

Ich hab das nach einiger Recherche wie vorgeschrieben gemacht, aber dennoch benutzt er nicht das gebundlete JRE sondern versucht weiterhin auf dem des Systems rumzueiern.

Dabei sieht meine XML, die von L4J erstellt wird wie folgt aus:

[XML]<launch4jConfig>
  <dontWrapJar>false</dontWrapJar>
  <headerType>gui</headerType>
  <jar>D:\xpiUtil\xpiUtil.jar</jar>
  <outfile>D:\xpiUtil\xpiUtility.exe</outfile>
  <errTitle></errTitle>
  <cmdLine></cmdLine>
  <chdir></chdir>
  <priority>normal</priority>
  <downloadUrl>http://java.com/download</downloadUrl>
  <supportUrl></supportUrl>
  <stayAlive>false</stayAlive>
  <manifest></manifest>
  <icon></icon>
  <jre>
    <path>..\java_vm\jre7\</path>
    <bundledJre64Bit>false</bundledJre64Bit>
    <minVersion>1.6.0</minVersion>
    <maxVersion>1.8.0</maxVersion>
    <jdkPreference>preferJdk</jdkPreference>
    <opt>%Utility%</opt>
  </jre>
</launch4jConfig>[/XML]

Meine Ordnerstruktur des zu verschiebenden Ordners:

```
|- Utility
    |- java_vm
        |-jre7
           -|bin
           -|lib
    |- templates // xmls, die das Tool braucht
    |- util.jar
    |- util.exe
    |- utility.xml // die XML die Launch4J erstellt.
```


----------



## nvidia (9. Dez 2013)

Kaibear hat gesagt.:


> Ich hab das nach einiger Recherche wie vorgeschrieben gemacht, aber dennoch benutzt er nicht das gebundlete JRE sondern versucht weiterhin auf dem des Systems rumzueiern.[...]



Woran merkst du das er die installierte Version nimmt? Ich habe mal ein kleines Testprogramm geschrieben das nur etwas auf der Konsole ausgibt, die 64Bit JDK-JRE verwenden soll und eine entsprechende Launch4J-XML generieren lassen. Das sieht dann wie folgt aus. 

[XML]
<launch4jConfig>
  <dontWrapJar>true</dontWrapJar>
  <headerType>console</headerType>
  <jar>l4jtest.jar</jar>
  <outfile>l4jtest.exe</outfile>
  <errTitle>Launch4JTest</errTitle>
  <cmdLine></cmdLine>
  <chdir>.</chdir>
  <priority>normal</priority>
  <downloadUrl>http://java.com/download</downloadUrl>
  <supportUrl></supportUrl>
  <stayAlive>false</stayAlive>
  <manifest></manifest>
  <icon></icon>
  <classPath>
    <mainClass>HelloLaunch4J</mainClass>
    <cp>l4jtest.jar</cp>
  </classPath>
  <jre>
    <path>JRE</path>
    <bundledJre64Bit>true</bundledJre64Bit>
    <minVersion></minVersion>
    <maxVersion></maxVersion>
    <jdkPreference>jdkOnly</jdkPreference>
  </jre>
</launch4jConfig>
[/XML]

Das l4jtest.jar wurde als ganz normales Jar exportiert (aus Eclipse) und dann in folgende Ordnerstruktur kopiert.


```
|-Laufwerk
   |-Testprogramm
      |-jre           <<< Kopierte JRE aus dem JDK-Ordner der installierten 64-Bit-Version
      |-l4jtest.jar
      |-l4jtest.exe
```

Führe ich die Exe auf der Konsole gibt mir das Programm das aus was ich programmiert habe. Benenne ich den jre-Ordner in jre-1 um startet das Programm nicht mehr, weil es die JRE nicht mehr findet. D.h. bei mir funktioniert alles ohne Probleme. Du wirst sicher irgendwo Fehler in deiner XML für Launch4j haben.


----------



## Kaibear (9. Dez 2013)

Dass ich das merke, liegt daran, dass ich auf einer Umgebung mit 1.6 als JRE den Fehler bekomme, den ich dann sonst mit meiner Jar bekomme. "Main-Class not found". Auf 1.7 passiert das nicht und alles (auch die Exe) lässt sich ausführen.


----------



## nvidia (9. Dez 2013)

Hatte meinen Beitrag oben noch mal großflächig editiert. Hier der Link zum kleinen Eclipse-Testprojekt. Launch4JTest.zip


----------



## Kaibear (11. Dez 2013)

Hmm hat alles nicht funktionieren wollen... Spricht nicht für Launch4J in Zukunft für mich...

Etwas hässlicher aber ausführbar auf Windows-Maschinen hab ichs nun aber auch endlich mit nem Batch-File hinbekommen, der die java.exe der Custom-JRE aufruft (vorher hab ich immer javaw.exe versucht - war zur Verdammung verurteilt).

Dennoch danke!


----------



## nvidia (11. Dez 2013)

Kaibear hat gesagt.:


> Hmm hat alles nicht funktionieren wollen... Spricht nicht für Launch4J in Zukunft für mich...



Hast du mein kleines Testprojekt mal derart ausgeführt wie ich das getan habe, d.h. gleiche Ordnerstruktur etc? Dafür musst du natürlich noch das JRE aus dem aktuellen 64Bit JDK in Eigeninitiative reinkopieren. Und wenn selbst das nicht gehen sollte gibt es bei dir irgendein grundsätzliches Problem.


----------



## turtle (12. Dez 2013)

Ich mische mich ungerne ein, aber...

Ich habe mehrfach jSmooth eingesetzt. (Es wird bei launch4j wohl ähnlich sein)

Jedenfalls kann man bei jSmooth die Konfiguration per GUI zusammen klicken. Und im Ordner, in dem die JAR-Datei liegt, gibt es dann auch einen Ordner jre in dem die zu verwendende JRE liegt. In Smooth gibt man dazu an ,das die jre im besagten Ordner liegt (siehe Screenshot)

Beim Start meines Mini-Programms wird auch genau die jre verwendet, weil es die Version ausgibt

```
System.out.println("Gestarted mit " + System.getProperty("java.version"));
```


----------



## rilla (30. Jan 2014)

Guten Morgen,

gibt es einen Unterschied zwischen einem kopierten JRE Ordner gegenüber einem kopierten JDK Ordner?
Tut mir Leid wenn dir Frage dumm erscheint, ich bin noch in der Java-Findungs-Phase =))

lG Carina


----------



## max40 (30. Jan 2014)

Der JDK-Ordner beinhaltet ein JRE-Ordner. Also die jre wird mit dem jdk ausgeliefert.


----------



## rilla (30. Jan 2014)

Vielen Dank Max, dann muss ich es nicht erst installieren um zu schauen wo der Unterscheid ist 
lG Carina


----------



## nvidia (30. Jan 2014)

Normalerweise macht man einen neuen Thread auf und schreibt nicht in einen älteren rein. Aber zu deiner Frage, das JDK ist dafür da um überhaupt mit Java entwickeln zu können. Die Installation eines JDK enthält die sog. Server-JRE. Bei der Installation des JDK wird man aber noch gefragt ob man zusätzlich eine public JRE installieren möchte, das ist dann IMHO die normale "Client-JRE"

Die Server-JRE beinhaltet folgendes:



> Server JRE: (Server Java Runtime Environment) For deploying Java applications on servers. Includes tools for JVM monitoring and tools commonly required for server applications, but does not include browser integration (the Java plug-in), auto-update, nor an installer. Learn more arrow



Die normale Client-JRE beinhaltet folgendes:



> JRE: (Java Runtime Environment). Covers most end-users needs. Contains everything required to run Java applications on your system.



D.h. die Client-JRE hat solche Sachen wie ein Browserplugin, Autoupdater etc. pp. Weitere Unterschiede zwischen Server und Client JRE sind, dass das Server-JRE aggressiver optimiert, aber dafür z.B. eine längere Startphase hat usw.

Wenn man das Server-JRE oder das Client-JRE ohne Installation verwenden möchte, so kann man es sich regulär als gezipptes Tar-Archiv von der Oracle-Seite herunterladen[1]. Das muss dann nur in einen Ordner entpackt werden. Natürlich müssen dann, wenn benötigt, Pfade manuell gesetzt werden, was einem der Installer sonst abnimmt.


[1] Java SE - Downloads | Oracle Technology Network | Oracle


----------



## rilla (30. Jan 2014)

Hi nvidia,

tut mir Leid, dass ich hier so reingefunkt habe - ich dachte die Frage ist vielleicht zu unwichtig um einen neuen Thread zu starten. Ich habe mich das auch in diesem Kontext gefragt - ich suche auch nach einer guten bis besten Möglichkeit das JRE mitzuliefern.

Vielen Dank, dass du mir trotzdem eine so gut verständliche Antwort gegeben hast. Vielleicht ist die Server-JRE dann doch interessant für mich und ich kann mich nun weiter informieren und austesten =)

lG Carina


----------

