# Executable in Jar einbinden



## carsten123 (18. Feb 2009)

Hallo,

ich rufe aus Java heraus ein externes Programm auf. Das klappt auch soweit. 

Nun soll aber dieses Executable mit in das Jar-File gepackt werden. Es soll also von außen nicht mehr sichtbar sein. Es einfach mit hinzufügen ist ja einfach. Aber wie spreche ich es dann an? Gibt es da irgendwie einen relativen Pfad oder sowas?

Kann man das Problem eventuell anders lösen? Das externe Programm (z.B. ein Batchjob oder ein fertig Compiliertes C-Programm) soll nur in der Jar-Datei vorhanden sein. Es soll auch möglichst nicht vor dem Ausführen an eine andere Stelle auf dem Rechner kopiert werden.

Kann mir da jemand einen Tipp geben wie es funktionieren könnte?

Vielen Dank im Vorraus

Tschau

carsten


----------



## MarcB (18. Feb 2009)

Meines Wissens geht das nicht.

Man müsste die Datei die im Jar liegt immer temporär rausschreiben. Das könnte in etwa so gehen:


```
InputStream in = getClass().getResourceAsStream("<Pfad zu der Datei im Jar>");
File tempFile = File.createTempFile("<name der datei>", "<endung>");
OutputStream out = new FileOutputStream(tempFile);

byte[] bytes = new byte[1024];
        int read;
        try{
            while((read=in.read(bytes))!= -1)
                out.write(bytes, 0, read);
        }finally{
                in.close();
                out.close();
}
}

String s = tempFile.getAbsolutePath();
Process p = Runtime.getRuntime().exec(s);
```

(nicht getestet, nur im Browser getippt)

Sonderlich performant wird es auf jeden Fall nicht.


----------



## carsten123 (18. Feb 2009)

dankeschön @MarcB

mmmhhhhh okay

das klingt nicht so toll.
Das mit dem temporären Rausschreiben hab ich mir auch schon überlegt. Aber das ist ja unperformant hoch 3. Es würde ja nur Sinn machen wenn das Jar-Archiv auch gepackt wäre und man beim Rauskopieren gleich mit entpacken könnte. Können Jar-Archive denn gepackt und immer noch ausführbar sein?

Anderer Lösungsansatz:
Angenommen ich habe den C-Quellcode der Executables. Könnte ich diese dann mittels Java Native Interface einbinden und ausführen? Wie sieht es hier mit der Performance aus? Ich habe C und Fortran Programme, die Berechnungen durchführen. Eine solche Berechnung dauert mehrere Minuten bis Stunden. Es dürfte als möglichst zu keinem Geschwindigkeitsverlust führen.

Wie schaut es beim Java Native Interface mit dem Reverse-Engineering aus? Das vorhandene C-Code so auf jeden Fall unbekannt bleiben. Bei Java-Bytecode ist das ja so eine Sache.

Ich hoffe auch hierzu kann jemand was sagen. 

Vielen Dank schon mal


----------



## Wildcard (18. Feb 2009)

carsten123 hat gesagt.:


> dankeschön @MarcB
> 
> mmmhhhhh okay
> 
> ...


-Ja, jars können gepackt und gleichzeitig ausführbar sein.
-Du sagst deine Berechnung dauert lange. Über JNI ist der Zugriff natürlich (etwas) langsamer als direkt, aber wenn die Berechnung lange dauert, sind die 0,0001% der Rechenzeit, die das triggern der Rechnung ausmacht, doch völlig irrelevant.
-Ist doch lächerlich sich darüber Gedanken zu machen ob das kopieren einer kleinen Binärdatei langsam ist, wenn die Berechnung die man damit anstellt Minuten bis Stunden dauert. 




carsten123 hat gesagt.:


> Wie schaut es beim Java Native Interface mit dem Reverse-Engineering aus? Das vorhandene C-Code so auf jeden Fall unbekannt bleiben. Bei Java-Bytecode ist das ja so eine Sache.


Du kannst auch aus Java Bytecode den Quellcode nicht mehr herstellen, allerdings einen Quellcode der mehr "Sinn" macht als bei zB einem C Kompilat.
Die Frage verstehe ich sowieso nicht, wenn du JNI verwendest, sprichst du "direkt" mit deinem C Kompilat. Wenn das C Kompilat dafür im bytecode vorliegen müsste, wofür bräuchte man dann JNI?


----------

