Externe Jar sehr langsam

Micha2903

Mitglied
Ich habe eine Konsolenanwendung welche ich über eine weitere Javaanwendung (noch Konsole, später GUI) starte und deren Streams (Input, Output und Error) ich im aufrufenden Programm kontrolliere.

Ich möchte damit erreichen, dass ich der Konsolenanwendung, welche nicht von mir ist, via GUI Konsoleneingaben geben kann und den entsprechenden Output bekomme.

Hier mal ein vereinfachtes Beispiel, nur zum Anzeigen des Errorstreams:

Java:
class Test {

    public mindcraft() throws IOException {
        System.out.println("Minecraft Tool");
        Process p = Runtime.getRuntime().exec("java -Xms1024M -Xmx1024M -jar externesProgramm.jar");
        BufferedReader buff = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        String temp;
        while ((temp = buff.readLine()) != null) {
            System.out.println(temp);
        }
    }
}

public class JavaApplication {

    public static void main(String[] args) {
        new Test();
    }
}

Starte ich externesProgram.jar direkt in einem Command Prompt, läuft die Startroutine dieses Programms unter einer Sekunde. Starte ich es über den geposteten Code, dauert es 15 Sekunden.

Das externe Programm wird für gewöhnlich mit den Parametern -Xms1024M -Xmx1024M (wie im .exec zu sehen) gestartet. Funktioniert diese Resourcenvergabe eventuell nicht, wenn das externe Programm über ein anderes Javaprogramm aufgerufen wird, oder hat jemand sonst eine Idee, woher dieser enorme Unterschied her kommen kann?
 
G

Gast2

Gast
Verwende statt Runtime besser den ProcessBuilder. Außerdem musst du die Parameter in einem String[] Array übergeben.

Gehts dir nur darum die Streams auf die Konsole umzuleiten? Das kannst du doch auch in der Konsole machen.
 

Micha2903

Mitglied
Ich kann spaßenshalber mal den ProcessBuilder testen, um zu sehen, ob das einen Unterschied macht, aber wirklich vorstellen kann ichs mir nicht.

Der Aufruf in der exec war jetzt mal nur exemplarisch. Real schaut der etwas anders aus. Der Aufruf an sich klappt ja auch, ist nur eben kriechend langsam.

Ich will die Streams nicht nur auf die Konsole umleiten. Wäre auch quatsch. Da könnte ich direkt das externe Programm aufrufen.

Sinn und Zweck soll sein, dass dieses externe Programm bestimmte eingaben erlaubt, wie das manuelle zwischenspeichern, beenden des Programms u.s.w. Da ich das externe Programm nicht verändern kann, bzw. darin einen zu großen Aufwand sehe und gleichzeitig diese Eingaben später via GUI und Buttons zu realisieren, war meine Idee, das externe Programm von einem weiteren Programm aufzurufen, dass sich dann über die Streams in die Konsole "klingt".

Drücke ich also später in "meiner" GUI den Button Speichern, soll der Konsole des externen Programms die eingabe /saveall übergeben werden.

Wenn es dafür eine bessere Methode gibt als die, die ich mir bis hierhin erdacht habe, dann bin ich da natürlich offen und dankbar für Anregungen.

Für Hinweise diesbezüglich bitte ich zu bedenken, dass ich zwar kein Anfänger mehr bin, aber mich noch nich als Profi bezeichnen würde. Ein "Fundamentals of Java Programming" kann ich mein eigen nennen. Arg weit darüber hinaus geht mein Wissen aber noch nicht.



EDIT: Habe das ganze mal mit einem ProcessBuilder probiert. Ergebnis ist das gleiche.
 
Zuletzt bearbeitet:
J

JohannisderKaeufer

Gast
So wie du das machst hast du später zwei Virtuelle Maschinen am laufen. Das hat Vorteile aber auch Nachteile. Speicherbedarf, etc.

Eine Möglichkeit wäre das externe Programm in den cp mit aufzunehmen und dann dort einfach die main Methode aufzurufen, das externe Programm also wie eine lib verwenden.
Dann läuft oder läuft auch nicht alles in einer VM und Konsole.

Je nachdem wie komplex die Anwendung ist oder auch wie gut Sie geplant ist, kann es durchaus auch sehr einfach sein, sich irgendwo einzuhängen um da zusätzliche Funktionalität unterzubringen.
 

Micha2903

Mitglied
Es direkt mit einzubinden wäre eine Möglichkeit. Allerdings sehe ich mich als Lernender der sehr viel mehr Interesse daran hat ein Problem erst einmal im Kern zu verstehen, anstatt direkt einen Workaround zu verwenden, ohne überhaupt zu begreifen, warum die ursprüngliche Methodik nicht funktioniert hat.

Mir fehlt da derzeit komplett der Ansatz. Mein Konsolenprogramm tut doch nicht mehr als drei Streams vom Externen Programm zu holen. Wie kann allein das dazu führen, dass ein externes, auch noch in eigener VM laufendes Programm, um den Faktor 15 langsamer wird?

Falls es als Zusatzinfo von Belang sein sollte, sei noch erwähnt, dass ich mit Netbeans 7.1 (JRE7, JDK 1.7) entwickle.
 
B

bygones

Gast
ehrlich gesagt seh ich solche Konsolenaufrufe eher als workaround. Sinnvoller ist es das externe jar in seiner Application einzubinden und dessen API nehmen und direkt nutzen.
 

fastjack

Top Contributor
Eigentlich braucht Du das gar nicht in der shell zu starten. Binde das Jar doch in den Classpath ein und startet dann die Main-Class. Also einfach " MeineKlasse.main()" und fertig. Die Mainklasse steht im Manifest.
 

Micha2903

Mitglied
Okay. Ich werde das mal ausprobieren. Allerdings würde mich nach wie vor interessieren, wo die Performanceprobleme herkommen. Es muss doch dafür irgendeine Erklärung geben.
 

Micha2903

Mitglied
Naja. Schau dir den Code an. Sehr viel gibts da nicht. Im Grunde nur zwei Dinge. Das Abfragen einer Zeile aus dem Stream und das Anzeigen dieser Zeile auf der Konsole. Ich hab auch schon versucht dem Ganzen kleine Pausen zu geben (100ms) um auszuschließen, dass der Andauernde durchlauf der While Schleife zu sehr bremst. Dem ist aber nicht so.

Könnte das ein Shedule Problem sein? Quasi dass zwischen jedem Zyklus des Externen Programms gewartet wird, bis der Zyklus des Durchlaufs der While Schleife beendet ist? Kann mir das nicht so wirklich vorstellen, da das externe Programm ja in einer eigenen Virtuellen Maschine läuft und daher eigentlich nicht auf Kontext des Aufrufenden Programms warten sollen müsste. Oder etwa doch?
 

FerFemNemBem

Bekanntes Mitglied
Mahlzeit,

nicht Pausen reinmachen sondern (im Zweifelsfall nach jeder Zeile) ein "System.currentTimeMillis();" mit einem entsprechenden Zeilenmarker auf die Konsole Schreiben. Irgendwo muss die Zeit ja verbraten werden.

Gruss, FFNB.
 

Micha2903

Mitglied
Ja das ist schon klar, aber es kann nicht sein, dass es direkt an meinem Code liegt, denn selbst wenn ich Pause von 1000ms rein bringe, ist die Sache haargenauso schnell, oder langsam. Es muss also an der Konstellation liegen.
 

FerFemNemBem

Bekanntes Mitglied
Halloechen,

Was hast Du denn bloss immer mit Deinen Pausen? Du sollst KEINE Pausen reinmachen sondern Dir die Dauer jeden einzelnen Codezeile ausgeben lassen. Dann kann man weiterschauen wo es genau hakt.

Gruss, FFNB.
 

Micha2903

Mitglied
Mir ist das vollkommen klar, aber selbst wenn ich die Ausgabe komplett außen vor lasse und einfach nur die externe .jar starte, ist die kriechend langsam. Es bleibt also dabei, an meinem Code liegt es nicht.
 

FerFemNemBem

Bekanntes Mitglied
Halloechen,

aber natuerlich liegt es an Deinem Code. Das schreibst Du doch selbst:

Starte ich externesProgram.jar direkt in einem Command Prompt, läuft die Startroutine dieses Programms unter einer Sekunde. Starte ich es über den geposteten Code, dauert es 15 Sekunden.

Aber wenn Dir das zuviel ist, hier weitere Informationen zu posten (die Dich in Summe 3 Minuten kosten wuerden)...

Gruss, FFNB.
 

Micha2903

Mitglied
Das ist falsch. Das Starten des Programs erfolgt über eine einzige Zeile. Besteht das Programm nur aus dieser einen Zeile, also dem Starten des Programmes, ist das externe Programm kriechlangsam. Alles was also im Code danach kommt, hat keine Einfluss auf die Geschwindigkeit.

Es geht also im Kern lediglich darum zu verstehen, warum ein irgendwie geartetes .jar Programm, gestartet aus einem anderen Programm, zu solch dermaßen rapiden Performanceverlusten führt.

Um es für dich nochmals zu verdeutlichen:

externesProgramm.jar über die Windows Konsole mit java -jar externesProgramm.jar starten und das Programm durchläuft seine Startroutine in 1-2 Sekunden.

externesProgramm.jar über ein weiteres Java Programm und den Aufruf

Process p = Runtime.getRuntime().exec("java -jar externesProgramm.jar");

starten und selbige Routine, ohne das im Aufrufenden Programm noch irgendwas getan wird und der Spaß dauert 15-16 Sekunden.
 

FerFemNemBem

Bekanntes Mitglied
Halloechen,

was bitte hindert Dich daran, mal rasch folgenden Test durchzufuehren?

Java:
class Test {
 
    public mindcraft() throws IOException {
        System.out.println("Minecraft Tool");
        System.out.println("1: " + System.currentTimeMillis());
        Process p = Runtime.getRuntime().exec("java -Xms1024M -Xmx1024M -jar externesProgramm.jar");
        System.out.println("2: " + System.currentTimeMillis());
        BufferedReader buff = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        System.out.println("3: " + System.currentTimeMillis());
        String temp;
        while ((temp = buff.readLine()) != null) {
            System.out.println(temp);
        }
    }
}
 
public class JavaApplication {
 
    public static void main(String[] args) {
        new Test();
    }
}

Nach Deiner Vermutung muesste die Zeit zwischen "1" und "2" draufgehen. Das moechte ich aber gerne gesichert wissen, nicht nur als Deine Vermutung.

Gruss, FFNB.
 

Micha2903

Mitglied
Nein, die Zeit geht nicht dort zwischen verloren. Ich sage ja nicht, dass das Programm an irgend einer Stelle hängen würde. Es ist insgesamt einfach viel langsamer.

Ich kann beim Startup den Speicherbedarf des externen Programmes sehr gut Nachvollziehen, da der zu beginn bei 12mb liegt, dann direkt nen Sprung auf 40mb macht und dann nochmal einen Sprung auf 400mb. Das Programm über die Windows Konsole gestartet zeigt dieses Verhalten, jedoch sehr sehr schnell, so schnell dass man es kaum wahrnehmen kann. Dabei kann in der Konsole bestimmter Output gelesen werden. Status des Ladens verschiedener Module.

Starte ich das Programm als externes im Javaprgramm, dann dauert eben dieser Startup ca 10 mal so lang. Lasse ich über die While Schleife den Output der Konsole des Externen Programms anzeigen, sehe ich auch jede einzellne Zeile an Output und die kommen nicht Ruckartig mit einem mal, oder haben verzögerungen drin. Es dauert zwischen den einzellnen Zeiten nur eben sehr viel länger.

Lasse ich nun den Output komplett weg, also Starte nur das Programm, kann ich über die Vergabe des Arbeitsspeichers sehen, dass im Hintergrund immernoch genau das gleiche Passiert.

Bitte glaube mir also, wenn ich dir sage, dass es nicht am Code liegt. Gerne zeige ich dir auch genauer über Medien wie Teamspeak, oder einen IM was genau ich da treibe. Um das hier im Forum hoch zu laden ists zum einen zu groß und zum andern zu heikel.
 

FerFemNemBem

Bekanntes Mitglied
Mahlzeit,

also nich der Start dauert lange sondern die Performance des gestarteten Prozesses ist schlecht. Ich hab das hier mal mit Deinem Code getestet (mit einem Programm, dessen Start sehr Prozessorhungrig ist und so um die 15 Sekunden dauert).

Java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Test 
{ 
    public Test()
    {        
        try 
        {
			Process p = Runtime.getRuntime().exec("java -Xms1024M -Xmx1024M -jar I:/Test/cputest.jar");
	        BufferedReader buff = new BufferedReader(new InputStreamReader(p.getInputStream()));
	        String temp;
	        while ((temp = buff.readLine()) != null) 
	        {
	            System.out.println(temp);
	        }
		} 
        catch (IOException e) 
		{
			System.out.println("IOException");
		}
    }
}
 
public class JavaApplication 
{
    public static void main(String[] args) 
    {
        new Test();
    }
}

Hier ist es voellig egal, ob ich das Programm von der Konsole oder mittels Deiner Methode starte.

Wie sieht denn bei Dir die CPU-Auslastung aus, wenn das Programm als Prozess startest? Haenge Dich doch mal mit VisualVM o.ä. an den Prozess, den Du startest (also an den Prozess von "externesProgramm.jar"). Kannst Du da im Tab "Sampler" unter "CPU" etwas auffaelliges erkennen?

Gruss, FFNB.
 

Micha2903

Mitglied
Ich denke, ich kann das Thema nun abschließen. Manchmal sind es doch die einfachsten Dinge, die einem die Suppe versalzen und hin und wieder sieht man halt den Wald vor lauter Bäumen nicht.

Schlussendlich lag es daran, dass dieses ominöse externe .jar beim ersten Start ein paar zusätliche Aufgaben erledigt, wie das Anlegen einer Datenbank und dergleichen. Ich hatte die jar am Ursprünglichen Ort aus gestartet und dabei nicht beachtet, dass dadurch das Stammverzeichnis der externen .jar auf das des Netbeansprojekts gesetzt wird, wodurch das sämtliche Drumherum zur .jar gefehlt hat. Also die eigentlich schon vorhandenen Datenbanken und Konfigurationen. Nachdem ich die in das Projektverzeichnis kopiert hatte, geschah, was ich solange ersehnt hatte. Der Start ging in der gleichen Zeit wie beim direkten Starten der externen .jar

Ich habe die Geschichte nun auch so aufgebaut, dass ich wie vorgeschlagen die .jar in mein Projekt einbinde, was auch super funktioniert. Ich kann auch wunderbar mit dem Error und Outputstream herumhantieren, allerdings bin ich mir nicht wirklich darüber im Klaren, wie ich es hin bekomme, dass ich einen Button dazu vergewaltigen kann, etwas in den Inputstream der Konsole zu schreiben.

Aber das ist wohl ein Problem das in einen anderen Thread gehört.

Vielen Dank allen die hier versucht haben mir zu helfen. Am Ende saß einmal mehr das Problem 50cm vor dem Bildschirm.
 

jobima

Mitglied
Ich nehme an das Dein im Prozess gestartetes Programm Ausgaben in die Konsole tätigt und Du daran die Zeit misst die für den Start benötig wird.
Falls nicht wie misst Du die Zeit ?

Unter welchem Betriebssystem arbeitest Du ?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
X Java gewerblich nutzen mit externe Bibliothek. Was zu beachten? Allgemeine Java-Themen 18
OSchriever Externe Anwendung beenden Allgemeine Java-Themen 41
T Externe Java Klasen zur Laufzeit einbinden Allgemeine Java-Themen 10
J File in Package erstellen & lesen mit Programmstart in externe Projekt Allgemeine Java-Themen 3
X Threads Externe Variablen in Run Methoden verändern Allgemeine Java-Themen 4
V JTable Externe Lib Allgemeine Java-Themen 2
JavaWolf165 Externe .jar-Dateien in .jar-Datei intigrieren Allgemeine Java-Themen 0
Neumi5694 Externe Skripte Allgemeine Java-Themen 9
L JavaFX JavafX externe FXML laden? Allgemeine Java-Themen 4
S Externe Eclipse Projekte dynamisch einbinden Allgemeine Java-Themen 3
Thallius Externe .jar dynamisch einbinden Allgemeine Java-Themen 5
W Threads Mit Thread und Runtime externe Programme öffnen Allgemeine Java-Themen 0
C Prozesssteuerung - Speicherhungrige externe Programme werden blockiert Allgemeine Java-Themen 2
F externe module. geht das in Java? Allgemeine Java-Themen 3
G Eclipse Wie mit Ant build.xml externe Jar´s einbinden? Allgemeine Java-Themen 5
M Wie externe System-Ressourcen zwangsweise freigeben Allgemeine Java-Themen 2
B Externe Programme und ProcessBuilder Allgemeine Java-Themen 5
nrg Externe Library Lizenzen Allgemeine Java-Themen 14
D externe programme / Jdesktoppane, ... Allgemeine Java-Themen 6
U Externe Logiken möglich? Allgemeine Java-Themen 8
G externe Properties datei aus Jar File heraus lesen Allgemeine Java-Themen 12
G externe Steuerung von Sprachsoftware Allgemeine Java-Themen 3
C Externe Bilder in Java-Applet blocken? Allgemeine Java-Themen 2
B Eclipse externe Dateien mit einbinden Allgemeine Java-Themen 10
H externe JARs in eigenem Programm-Jar einbinden. Allgemeine Java-Themen 5
N externe Anwendung aktivieren (nicht starten!) Allgemeine Java-Themen 3
H Externe Prozesse und Inputstreams - ausgabe in JTextArea Allgemeine Java-Themen 3
oliver1974 Zugriff auf externe .class Dateien (und resourcen) aus JAR Allgemeine Java-Themen 11
G externe package Allgemeine Java-Themen 7
E externe Anwendung aufrufen und sich selbst beenden Allgemeine Java-Themen 8
W Java und externe Anwendungen Allgemeine Java-Themen 3
J Externe File Emails für JavaMail Allgemeine Java-Themen 4
J Externe .jar bibis in programm .jar einbinden? Allgemeine Java-Themen 9
R externe Libraries in jar-file Allgemeine Java-Themen 16
R Kontrolle über Externe Prozess Allgemeine Java-Themen 5
O Externe Jars in eigene JAr packen in Eclipse Allgemeine Java-Themen 5
M Standardpfad für externe Dateien? Allgemeine Java-Themen 2
R aus Jar auf externe XML-Datei zugreifen Allgemeine Java-Themen 14
I externe Namensliste auslesen Allgemeine Java-Themen 13
M Java2exe Externe Packages einbinden! .JAR und sowas Allgemeine Java-Themen 7
thE_29 Externe (unbekannte) Klasse nutzen Allgemeine Java-Themen 11
J Externe Ansteuerung (Motor,Licht) mit Java? Allgemeine Java-Themen 4
B Sehr großen Graph mit Verbindungen bauen und minimieren? Allgemeine Java-Themen 35
javamax2000 Sehr sonderbares Verhalten Allgemeine Java-Themen 6
B Welcher Datentyp für sehr große Zahlenbereiche? Allgemeine Java-Themen 1
P Rechnen mit sehr kleinen Zahlen Allgemeine Java-Themen 5
R JDK installieren OpenJDK-Aufruf sehr langsam Allgemeine Java-Themen 4
Thallius String erzeugen sehr langsam Allgemeine Java-Themen 16
D Verwaltung von sehr vielen Objekten Allgemeine Java-Themen 12
S JNLP startet seit 1.8.0_31 sehr langsam + Windows-Systemverzeichnis Allgemeine Java-Themen 3
Creylon Java verursacht sehr starkes ruckeln Allgemeine Java-Themen 5
N Bin to Dez und umgekehrt mit sehr großen Zahlen Allgemeine Java-Themen 2
T Gleiche Operation dauert teilweise sehr lange Allgemeine Java-Themen 12
M JUnit & Multithreading - sehr seltener Fehler Allgemeine Java-Themen 3
H Sehr viele Threads effizient Verwalten Allgemeine Java-Themen 13
J Laden von JAR Files geht ohne ADMIN Rechte sehr langsam Allgemeine Java-Themen 6
H Kopieren sehr langsam Allgemeine Java-Themen 5
B Cipher.getInstance Aufruf sehr langsam Allgemeine Java-Themen 2
nrg Arbeiten mit sehr großen CSV Dateien Allgemeine Java-Themen 20
K replaceAll bei sehr großen String Allgemeine Java-Themen 3
B Eingabemaske Komponenten aktivieren, funktionert nicht (sehr kurios) Allgemeine Java-Themen 2
hdi Heap Sapce Error bei sehr großem String Allgemeine Java-Themen 5
G RXTX library braucht sehr lange zum laden. Ist das normal? Allgemeine Java-Themen 8
L Java 1.5 - Anwendung unter 1.6 JRE sehr langsam geworden Allgemeine Java-Themen 8
O Speicherverbrauch von Java / VM sehr hoch? Allgemeine Java-Themen 27
M Rechnen mit sehr kleinen Zahlen Allgemeine Java-Themen 8
G Lesen von sehr großen dateien Allgemeine Java-Themen 8
M String zusammensetzen->sehr langsam Allgemeine Java-Themen 3
G Sehr sehr merkwürdige Ereignisse mit Fibonacci Programm Allgemeine Java-Themen 6
G Sehr gutes Java-Framework(Gui-Builder) auf XML-Basis gesucht Allgemeine Java-Themen 21
E String.replace für (sehr) großen Text Allgemeine Java-Themen 9
T [SVNKit] Commit sehr langsam. Allgemeine Java-Themen 7
G Arraylist statt List - Sehr schlimm? Allgemeine Java-Themen 8
F JAVA Applikationen starten sehr langsam Allgemeine Java-Themen 14
D Datei öffnung sehr langsam Allgemeine Java-Themen 17
G Neue Warenwirtschaft aber sehr langsam! Allgemeine Java-Themen 3
H Entpacken sehr langsam Allgemeine Java-Themen 10
Bleiglanz Benchmarks sind sehr schwierig Allgemeine Java-Themen 2
K Arbeitsspeicher wird langsam voll Allgemeine Java-Themen 6
E JavaFX RMI extrem langsam wenn Server nicht läuft Allgemeine Java-Themen 5
P Eclipse langsam/unbrauchbar bei größeren Quelldateien? Allgemeine Java-Themen 8
W Threads NullPointer: Konstruktor "zu langsam"? Allgemeine Java-Themen 3
C JEditorPane langsam großes HTML Allgemeine Java-Themen 8
B util.Timer zu langsam? Allgemeine Java-Themen 3
W Java Applet läuft langsam Allgemeine Java-Themen 2
N Liste mit Map abgleichen extrem langsam Allgemeine Java-Themen 6
C Darstellung der Liste bei vielen Daten extrem langsam Allgemeine Java-Themen 11
B JavaPanels langsam schliessen und öffne Allgemeine Java-Themen 6
L Java Debugmodus ist unerträglich langsam! Allgemeine Java-Themen 30
H JID3 + vdheide schreiben zu langsam Allgemeine Java-Themen 11
T ObjectOutputStream#writeObject() zu langsam. Allgemeine Java-Themen 13
N Berechnungsthreads zu langsam. Allgemeine Java-Themen 2
G Java Socket langsam unter Linux Allgemeine Java-Themen 21
T String.split() - viel zu langsam Allgemeine Java-Themen 9
W sin und cos bei hohen Werten extrem langsam Allgemeine Java-Themen 12
G Domainen crawlen & Domainnamen listen -> LANGSAM! Allgemeine Java-Themen 19
M Performance enorm langsam Allgemeine Java-Themen 26
H java.util.Vector langsam ? Allgemeine Java-Themen 5
T Jtree zu langsam beim klappen Allgemeine Java-Themen 8
H Verschlüsselungsprogramm zu langsam Allgemeine Java-Themen 12

Ähnliche Java Themen

Neue Themen


Oben