Jar-Neustart mit geänderten Java Heap Size

Kann man da aber auch noch eine Möglichkeit einbauen, falls der Anwender bereits so schlau war, von sich aus die JHS zu erhöhen?
Ja, könnte man auch.
In MainMethode1 prüfen wieviel Xmx zur Verfügung steht.
Wenn zu wenig, MainMethode2 (via ProcessBuilder) mit mehr HS starten.
(Beide Klassen (mit Main1 und Main2) sind in der gleichen JAR-Datei.)

Via WebStart gehts auch.
Dann braucht man aber auch min 2 Dateien (Jar + JNLP)
Dann kann man auch nen Skript dabei tun.

Grundsätzlich sehe ich jetzt aber nicht so das große Problem oder Umstand die JAR über ein Skript zu starten.
Wie bereits erwähnt: Launch4J ist auch eine Möglichkeit.
 
Zuletzt bearbeitet:
Wie bereits erwähnt: Launch4J ist auch eine Möglichkeit.
Dieses Tool kannte ich nicht und ist mir bei der Recherche nicht auffällig geworden. Aber beim überfliegen dieser Anwendung (http://launch4j.sourceforge.net/) ist mir aufgefallen, dass es ausschließlich für Windows konzipiert ist. Aber für den einen oder anderen sehr interessant.

Grundsätzlich sehe ich jetzt aber nicht so das große Problem oder Umstand die JAR über ein Skript zu starten.
Ich sehe da grundsätzlich auch kein Problem darin. Aber zwei Tatsachen würde ich gerne anführen:
1.)
hansmueller hat gesagt.:
...(Die meisten Anwender sind DAUs, aber eben nicht alle.)...
2.)
Das Grundkonzept hinter ganzen Geschichte besteht auf "einer einzigen" ausführbaren Datei. Dabei möchte ich nochmal auf meinen ersten Beitrag zu diesem Thema verweisen:
roadrunner22x hat gesagt.:
Das Programm wird später nicht von mir genutzt und dem User erklären, dass er ein Batch/Shell starten soll oder wo möglich noch eine Konsole öffnen muss und dort was rein hacken, geht mir persönlich zu weit und hat nix mit Usability zu tun.
Das mit dem WebStarter hatte ich mir auch überlegt. Und das scheint auch eine sehr praktische Lösung zu sein, aber es wurde schon auf die 2 Dateien-Umsetzung hingewiesen. Was dem Grundkonzept widerspricht. Siehe den Vorraussetzungen innerhalb diesem Beitrages, etwas weiter unten.

Die Möglichkeit mit den zwei Jars in einem packen, hatte ich auch schon in anderen Foren gelesen. Dabei sind mir außer "Pack einfach zwei Jars in einem, oder benutze zwei Main-Methoden (Punkt)", keine konkreten Lösungsansätze aufgefallen. Was hilft mir ein theoretischer Ansatz. Aus diesem Grund wählte ich den wohl etwas einfacheren Weg.

hansmueller hat gesagt.:
Ich würde ProcessBuilder.start() statt Runtime.getRuntime().exec() verwenden. Habe mal irgendwo gelesen, daß ProcessBuilder neuer und besser sein soll.
Kannst du das noch etwas genauer erklären? Bzw. hast du einen Link für diese Aussage? Vielleicht kann man das ja wirklich verwenden.

hansmueller hat gesagt.:
... alle Komandos der Reihe nach in den ProcessBuilder ...
Dies hatte ich auch schon versucht, ohne Erfolg. Wenn der Java Heap Size geändert werden soll, muss dieser mit dem Aufruf des Programms übergeben werden, das setzt aber einen separaten Prozess voraus. Aber du kannst mir gerne einen Implementierungsvorschlag unterbreiten.

hansmueller hat gesagt.:
Kann man da aber auch noch eine Möglichkeit einbauen, falls der Anwender bereits so schlau war, von sich aus die JHS zu erhöhen?
Diese Prüfung übernimmt diese bereits "von Anfang an implementierte" Methode:
Code:
/**
     * This method examines the need for a restart. This is based on the size of the maximum java heap size of 
     * JVM and the desired maximum java heap size.
     * @param parameters - arguments on startup
     * @return
     */
    public static boolean checkNeedToRestart(String [] parameters)
    {
        delTempBatchFile();
        if (getMaxHeapSpace() < referenceMaxJavaSize)
        {
            try {
                restart(parameters);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

wakoz hat gesagt.:
Aber dein Weg ist umständlich und die Verbesserungs Ideen von uns musst du nicht kaputt schreiben.
Ich muss hier keinen „kaputt schreiben“. Ich verweise nur auf meinen ersten Beitrag zu diesem Thema hin. Dieser erklärt ausführlich meine Umsetzung und den Background. Und wenn man diesen nicht richtig liest oder auch nicht richtig lesen will, kannst du oder wer auch immer seine Zeit auch sinnvoller nutzen, als hier etwas zuschreiben. Die meisten deiner Nachfragen oder so genannten Verbesserungsvorschläge werden mit dem ersten Beitrag erfüllt.
Beispiele, gefällig?:
1.)
wakoz hat gesagt.:
...aus der Anwendung heraus das OS ermitteln ...
siehe:
Code:
filterOnOSSystem(String [] parameters, String jarFile)
2.)
wakoz hat gesagt.:
...Oder zum Beispiel die Anwendung mit Scripten auszugeben ...
siehe:
roadrunner22x hat gesagt.:
Die Prämisse liegt darauf, dass dem User nur eine Datei zugesendet wird. ...

3.)
wakoz und benhaze haben mir bis zum heutigem Tag noch nicht sagen können, wie man den Java Heap Size zur „Laufzeit“ erhöhen kann. Den eine konkrete Umsetzung liegt mir von euch nicht vor. Ich kann ja euch nochmal die Voraussetzungen geben, vielleicht hilft das euch weiter:
- Das eigentliche Programm ist eine Standalone-Version
- keine Möglichkeit für Internet
- nur eine Jar, keine extra Batch, Shell etc. („temporär“ ist dies aber erlaubt, muss aber für User nicht sichtbar sein)
- User soll ausschließlich per „Doppelklick“ auf die Jar das Programm starten, keine Konsole oder Batch, Shell etc.
- der User sollte an seiner JVM nichts an den Einstellungen ändern müssen ( siehe http://www.duckware.com/pmvr/howtoincreaseappletmemory.html), da dieser meistens nicht in der Lage dazu ist.
- zusammenfassend ist sagen, ich gehe davon aus, dass der User so "dumm wie ein Sack Reis" ist. Das ist jetzt nicht böse gemeint, soll aber meine Lage verdeutlichen
4.)
wakoz hat gesagt.:
jetzt soll es auf einmal Plattform unabhängig sein?
siehe:
roadrunner22x hat gesagt.:
Wie bereits erwähnt, ist die hier vorgestellte Klasse vorrangig für Windows ausgelegt. Kann aber beliebig erweitert werden.
Für mich sind momentan erst mal nur Windows-Systeme interessant. Zukünftig werden auch andere Systeme betrachtet. Die Funktion „linuxScriptFile (String [] parameters, String jarFile)“ sollte zeigen an welche Stelle man „ beliebig erweitert“ kann, um eine Plattformunabhängigkeit zu erzielen.

Verstehst du was ich damit sagen will?!
Hätte "von und zu Gutenberg" seiner Arbeit auch genau gelesen, hätte er jetzt auch nicht die Probleme.

So lange mir einer keine „konkreten“ alternativen Lösungsvorschläge (auf Quellcode-Ebene) für ein autarkes Programm (entsprechend den Voraussetzungen die ich oben genannt habe) unterbreiten kann, glaube ich, dass ich einen guten Lösungsansatz produziert habe. Und durch eure Aussagen werde ich in meiner Meinung bestättigt.

@wakoz und @benhaze:
Ihr könnt mir gerne alternative Quelltext-Passagen zuschicken bzw. hier schreiben. Vielleicht kann man ja einen gemeinsamen Nenner oder eine exemplarische Lösung für dieses Problem finden.

Lieben Gruß
de roadrunner ;-):p
 
Zuletzt bearbeitet:
Hallo,

roadrunner22x hat gesagt.:
Kannst du das noch etwas genauer erklären? Bzw. hast du einen Link für diese Aussage? Vielleicht kann man das ja wirklich verwenden.
Ok, hab mal ein bißchen gegoogelt. Den ProcessBuilder gibt es erst seit Java 5 und soll die Sache mit der Runtime ersetzen. Das Teil bietet anscheinen mehr Möglichkeiten als die Runtime-Geschichte. Habe hier mal auf die Schnelle diesen Link gefunden: http://www.java-tips.org/java-se-tips/java.util/from-runtime.exec-to-processbuilder.html

roadrunner22x hat gesagt.:
Wenn der Java Heap Size geändert werden soll, muss dieser mit dem Aufruf des Programms übergeben werden, das setzt aber einen separaten Prozess voraus. Aber du kannst mir gerne einen Implementierungsvorschlag unterbreiten.
Der seperate Prozess sollte eigendlich gegeben sein. Dafür ist ja das Runtime bzw. ProzessBuilder da. Muß allerdings zugeben, daß ich noch nie versucht habe mit einen Javaprogramm ein anderes bzw. das gleiche Java-Programm mit veränderter JHS zu starten.
Für einen kurzen Moment müßte man ein und dasselbe Programm 2 mal auf dem Desktop haben.

Ich habe hier mal einen kleinen Code-Schnipsel:
Code:
Progjarsigner = new File(VerzeichnisJDK.getPath() + "\\bin\\jarsigner.exe");//Ist das Programm jarsigner.exe, welches ausgeführt werden soll.
//DateiKeyStore ist ein File, daß die Schlüssel verwaltet bzw. lagert.
//ftpassword ist ein Textfeld, in dem das zu benutzende Passwort steht.
//tfalias ist ein Textfeld, in dem der Name bzw. das Alias des Schlüsselpaares steht.
//VerzeichnisZiel ist der Ordner in dem sich die Datei Programm.jar befindet. Diese soll signiert werden.

try
				{
					pb4 = new ProcessBuilder("cmd", "/C", Progjarsigner.getAbsoluteFile().toString(), "-keystore", DateiKeyStore.getAbsoluteFile().toString(), "-storepass", tfpasswort.getText(), VerzeichnisZiel.getAbsolutePath() + "\\Programm.jar", tfalias.getText());
					
					pc4 = pb4.start();
				
					pc4.waitFor();
					
					
					if(pc4.exitValue() == 0)
	    			{
						
	    				Weiter = true;	//Alles hat funktioniert
						
	       			}
	    			else
	    			{
	    				Weiter = false;
	    				Meldung = "Fehler beim Signieren ->ABBRUCH\n";
	    				
	    			}
							
					
				}
				catch(Exception ex)
				{
					ex.printStackTrace();
					Weiter = false;
					Meldung = "Fehler beim Signieren ->ABBRUCH\n";
				}

Das ganze führt den Befehl: "C\:Programme\Java\jdkxxx\bin\jarsigner.exe -keystore C\:Pfad\zu\dem\Keystore -storepass MeinPasswort C\:Pfad\zum\zu\signierenden\Programm.jar NamedesSchlüsselpaares" aus. Durch das "cmd" und "/C" wird es in der Konsole ausgeführt.
Eigendlich sollte der folgende Code daher auch funktionieren:
Code:
pb4 = new ProcessBuilder("cmd", "/C", C:\Pfad\zur\java.exe, "-Xms" + initJavaSize, "-Xmx" + maxiJavaSize, "-jar", C:\Pfad\zum\zu\startenden\Programm.jar)

Ich habe das Teil jetzt nicht getestet, ist jetzt nur mal so schnell dahingeschrieben. (Weiß jetzt nicht, ob es nach dem -Xms und den -Xmx ein Leerzeichen braucht und ob man besser java.exe oder javaw.exe nimmt.)
Hoffe es hilft dir evtl. weiter.

MfG
hansmueller
 
Wie ich aus deinen Posts erkennen kann, fehlen dir wichtige Grundlagen-Informationen.

1.
Das dein JAR via Doppelklick gestartet wird, liegt nicht an Java!

2.
Den konkreten Lösungsansatz erkennst du nicht, da dir offensichtlich die Grundlagen nicht ausreichen bekannt sind.

- Was passiert bei einem Doppelklick auf einer JAR ganz genau?
- Wofür ist die Manifest-Datei im JAR?
- Wofür ist die Main-Methode?
- Wie startet man ein JAVA-Programm via Konsole?

Wenn du diese Fragen wirklich beantworten kannst, verstehe ich absolut nicht, wie du meinen Lösungsansatz nicht erkennen kannst******

Erkläre uns bitte auch, wo zur Hölle der Unterschied liegt, zwischen:

Doppelklick auf EXE
und
Doppelklick auf BAT/CMD/SH

BEDENKE:
Die meisten DAUs( ! ) haben die Dateinamen-Erweiterung (unter Windows) ausgeblendet!
Das ist die Windows Standard-Einstellung!
(KEIN DAU WIRD DIESE EINSTELLUNG JEMALS ÄNDERN!)
Das bedeutet: Der DAU kann gar nicht erkennen, ob es sich um eine EXE oder BAT handelt.
Wenn die BAT-Datei dann auch noch wie folgt (für DAUs) benannt wird:
BITTE_KLICKEN_SIE_DOPPELT_AUF_DIESE_DATEI.bat
sollte es auch keine Probleme geben.

Der User muss auch nix in die Konsole tippen, wenn du nen Skript benutzt.
(naja, zumindest nicht mehr als sonst (linux))

zu Webstart:
Es ist korrekt, das du dann min. 2 Dateien hast.
Der User allerdings, bekommt diese gar nicht zu sehen.
Hast du eine Idee, wie man üblicherweise Webstart-Anwengunden startet?

ProcessBuilder:

Java:
public int importCert(String pathToKeyStore, String alias, String certFile, String storepass, String keypass)throws Exception
    {
        String pathToJavaHome = System.getenv("JAVA_HOME");
        File javaHome = new File(pathToJavaHome + "/bin");
        
        List<String> cmds = new ArrayList<String>();
        
        cmds.add(javaHome + "/keytool");
        cmds.add("-import");
        cmds.add("-v");
        cmds.add("-alias");
        cmds.add(alias);
        cmds.add("-trustcacerts");
        cmds.add("-file");
        cmds.add(certFile);
        cmds.add("-keypass");
        cmds.add(keypass);
        cmds.add("-storepass");
        cmds.add(storepass);
        cmds.add("-keystore");
        cmds.add(pathToKeyStore);

        ProcessBuilder pb = new ProcessBuilder(cmds); 
        pb = pb.redirectErrorStream(true);
        Process proc = pb.start();
        
        String text = "";    // Lesepuffer
        BufferedReader in;
        PrintWriter out = new PrintWriter(System.out);
        
        // Eingabestream holen
        in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        while ((text = in.readLine()) != null) 
        {
            out.println(text); 
            out.flush();
        }
        return proc.exitValue();
        
    }

Diesen Code kannst du als Beispiel benutzen.
Statt dem "/keytool" nimmst du einfach "/java"
und dann eben deine Parameter.

Zuletzt frage ich mich wie deine DAUs mit PDF-Dateien klarkommen? (oder gar mit LINUX ******)
Das Adobe-Reader(9)-Verzeichnis ist über 200 MB groß und beinhaltet über 500! Dateien.

(Das sage ich, weil du gesagt hast: )
meine Jar-Applikation ist an den Rand des Möglichen gestoßen.
Ist sie das wirklich?
Oder bist du an den Rand deiner Möglichkeiten gestoßen?

Ich versuche gerne zu Helfen, aber auch hier macht der Ton die Musik.
Ob deine Lösung tatsächlich die Beste ist, nur weil dir niemand Code für ein *autarkes* Programm gibt was all deinen Vorstellungen entspricht?
 
Zuletzt bearbeitet:
Hallo,

benhaze hat gesagt.:
Den konkreten Lösungsansatz erkennst du nicht,

Doch, hat er, aber deine Lösung entspricht nicht ganz seinen Anforderungen:
roadrunner22x hat gesagt.:
Ich kann ja euch nochmal die Voraussetzungen geben, vielleicht hilft das euch weiter:
- Das eigentliche Programm ist eine Standalone-Version
- keine Möglichkeit für Internet
- nur eine Jar, keine extra Batch, Shell etc. („temporär“ ist dies aber erlaubt, muss aber für User nicht sichtbar sein)
- User soll ausschließlich per „Doppelklick“ auf die Jar das Programm starten, keine Konsole oder Batch, Shell etc.
- der User sollte an seiner JVM nichts an den Einstellungen ändern müssen ( siehe http://www.duckware.com/pmvr/howtoin...letmemory.html), da dieser meistens nicht in der Lage dazu ist.
- zusammenfassend ist sagen, ich gehe davon aus, dass der User so "dumm wie ein Sack Reis" ist. Das ist jetzt nicht böse gemeint, soll aber meine Lage verdeutlichen
Was hier noch fehlt ist die Plattformunabhängigkeit. Also nicht nur Windows.

benhaze hat gesagt.:
Oder bist du an den Rand deiner Möglichkeiten gestoßen?

Ich versuche gerne zu Helfen, aber auch hier macht der Ton die Musik.
Wenn ich mir deine Beiträge so durchlese, dann hast du allerdings auch ganz schön kräftig auf die falschen Tasten gehaut.

benhaze hat gesagt.:
Ob deine Lösung tatsächlich die Beste ist, nur weil dir niemand Code für ein *autarkes* Programm gibt was all deinen Vorstellungen entspricht?
Er hat SEINEN Code hier gepostet. Es ist eine Lösung die SEINEN Anforderungen entspricht. SEINE Lösung funktioniert. Er läßt UNS daran teilhaben.
Das einzige was von dir rüberkommt ist (Ist jetzt rein meine persönliche Meinung): "Was soll den dieser Unfug." und "Das macht man ganz anderst."
Jedenfalls kommen deine Beiträge so rüber. (Ist jetzt wirklich nur meine persönliche Meinung.)

Ach ja, bzgl. WebStart, wenn keine Internetverbindung vorhanden ist, ist WebStart hierfür wirklich keine gute Lösung. Ist zwar auch möglich, aber nicht sehr konfortabel.

MfG
hansmueller
 
ja, manchmal ärgere ich mich etwas schnell:

1. meine Jar-Applikation ist an den Rand des Möglichen gestoßen.
2. wenn mir niemand das Gegenteil beweist (mit vollst. Code!), habe ich die beste Lösung.
3. die sinnlose Diskussion über all die Nachteile eines Start-Skripts (JAR oder BAT, der DAU siehts doch eh nicht)

aber deine Lösung entspricht nicht ganz seinen Anforderungen
Welche seiner Anforderungen kann man denn nicht mit meiner Lösung abdecken?
Ich rede von der Lösung mit den 2 Main-Methoden in einem JAR.
 
@benhaze:

Sorry, aber ab sofort kann ich nur noch über dich lachen. Wer hat
benhaze hat gesagt.:
2. wenn mir niemand das Gegenteil beweist (mit vollst. Code!), habe ich die beste Lösung.
das behauptet? Ich habe nur angedeutet, dass ich
roadrunner22x hat gesagt.:
...einen guten Lösungsansatz produziert habe.
Hier spricht keiner davon, der Bester zu sein oder das Beste programmiert zu haben.
Und zweitens, ich habe niemals und werde es auch niemals von jemanden verlangen meine Problematiken
benhaze hat gesagt.:
...mit vollst. Code!...
zu lösen. Nur besteht eine massiver Unterschied zwischen der Aussage "Da kann man zwei Mains verwenden" und kleinen Quelltext-Passagen oder UML-Veranschaulichungen.

benhaze hat gesagt.:
3. die sinnlose Diskussion über all die Nachteile eines Start-Skripts (JAR oder BAT, der DAU siehts doch eh nicht)
Ich werde es jetzt zum vierten mal wiederholen, dass ich und der Auftragsgeber zum starten keine Batch/Shell etc. verwenden wollen. Wenn du mir sagen kannst wie man eine Batch/Shell und eine Jar in eins packen kann, können wir sofort diese Diskussion beenden.

Ich sage auch nicht, dass es Nachteile mit Start-Skripten gibt, nur sollen sie hier einfach keine Verwendung finden. EINE DATEI MEHR NICHT!!

Einer meiner ersten Aussagen war:
roadrunner22x hat gesagt.:
Mit diesem Beitrag möchte ich meinen Umsetzung vorstellen, um erstens eine mögliche Gedankenstütze zu geben und zweiten euch aufwendige Recherchezeit zu ersparen.
Und jetzt wo wir beim Ton sind - Sarkasmus -> "Eh Alter es gäht und das auch jut."
Ich hatte nur vor meine Lösungsvariante der Gemeinde vorzustellen. Ich musste viel Zeit in Recherche über Java Heap Size, Runtime, Batch und Shell investieren und wollte nur eine mögliche Offerte geben.

Mit diesen Worten verabschiede ich mich aus diese Diskussionsrunde, die ja keine ist. Es wird mir eine Lehre sein, hier nochmal zu "erdreisten" einen Beitrag zu schreiben.

Lieben Gruß
de roadrunner ;-):p

P.S.: Natürlich werde ich mir die Beiträge mit den kleinen Code-Beispiele von hansmueller und benhaze gründlich anschauen. Vielleicht kann man dort etwas für das eigene Projekt wahrnehmen.
 
Sorry, aber ab sofort kann ich nur noch über dich lachen.
Ok, das höre ich zwar zum ersten Mal hier, aber es freut mich für dich.

Ich will deinen Ansatz auch gar nicht verändern.
Wenn es so OK für dich ist, dann ist doch alles in Ordnung.

Mein Ansatz mit der Main-Methode, welche einfach eine weitere Main-Methode im gleichen JAR startet (via ProcessBuilder)
ist evtl. zu komplex. (trotz meines Code-Beispiels mit dem ProcessBuilder, welches der größte Part ist)
(obwohl er eigentlich ziemlich trivial ist)

Deine Vorstellungskraft reicht hier scheinbar nicht aus, um meinen Ansatz zu verstehen.

Hättest du wirklick eine *konkrete* Frage zu meinem Ansatz, hätte ich dir evtl. helfen können.
Dir aber deine Arbeit erledigen, wollte ich allerdings nicht. (es sind evtl. max 40 Zeilen CODE!)
Da du offensichtlich dafür bezahlt wirst (und nicht ich...)

Die Idee mit den temporären Skripten und dem Neustart hört sich doch ganz gut an.
Bleib einfach dabei. Besser (oder einfacher, oder sauberer) wird es wohl nicht gehen.

Der Thread könnte eigentlich als erledigt gekennzeichnet werden.
(Ich will hier jetzt auch keine Endlosdiskussion daraus machen)
 
Zurück