Classpath putty.exe aus JAR starten

ralfb1105

Bekanntes Mitglied
Hallo,

ich bräuchte Unterstützung bei der Frage wie ich putty.exe, welches ich mit in meinem JAR File verpackt habe, aus dem Java Programm heraus starten kann. Meine File Struktur sieht folgendermaßen aus:

11992

Der Code dazu:
Java:
public void puttyButtonTapped() {
        String puttyCmdString = "putty.exe -ssh -l " + sde.getSshUser() + " -P " + sde.getSshport() + " -pw "
                + model.getServerRootPasswordString() + " " + sde.getIpaddress();
        Platform.runLater(() -> {
            try {
                Utils.execCmd(puttyCmdString);
            } catch (Exception ex) {
                String msg = String.valueOf(ex);
                messages.appendText("Failed to execute cmd: " + puttyCmdString + "\n" + msg + "\n");
                LOGGER.severe("Failed to execute cmd: " + puttyCmdString + "\n" + msg);
            }
        });
        ;
    }
Java:
public static void execCmd(String cmdString) throws Exception {
        @SuppressWarnings("unused")
        Process process = Runtime.getRuntime().exec(cmdString);
    }

Das Programm läuft ohne Probleme so lange es auf dem ausführenden Rechner putty.exe im Pfad gibt 😉 doch leider gibt es dann einen I/O Fehler wenn das nicht der Fall ist, und somit wäre es natürlich elegant wenn ich immer die mitgebrachte .exe starten könnte.

Ist das möglich .. und wenn ja wie kann ich den Pfad addressieren?

Gruß

Ralf
 
Hallo Tobias,

erst einmal Danke für Deine Antwort "geht nicht" - schade. Das Thema Lizenz könnte ich hier vernachlässigen, da es sich um eine reine Test Applikation im Lab handelt die nie die "offene Welt" sehen wird 🙂 Es wäre halt einfacher, so muss ich einen Weg bestreiten das der User eine Möglichkeit hat den Pfad zu seinem Putty anzugeben, da es auf den unterschiedlichen Test Systemen natürlich unterschiedliche Pfade sein könnten.

Mir würde hier die Properties Klasse einfallen - die Idee wäre dann in etwa:
1. default.properties mit Wert vorbelegen (app.puttyexe=C:\ProgramFiles\Putty\putty.exe
2. Beim programm Start überprüfen ob es eine application.properties gibt, wenn nein dann default.properties
3. User kann über Menu den Wert für app.puttyexe setzen, danach Wert in application.property setzen, ggf. vorher File erstellen.
4. Beim nächsten Programm Start --> siehe 2.

Gruß

Ralf
 
ich bräuchte Unterstützung bei der Frage wie ich putty.exe, welches ich mit in meinem JAR File verpackt habe, aus dem Java Programm heraus starten kann.
Warum nutzt du statt Putz nicht irgendeine Java-Lib?

Für putty: erst irgendwo hin entpacken, und dann starten.

Geht nich. Und warum auch?
Doch.

Du darfst Putty gar nicht ausliefern.
Doch.
 
Hallo mrBrown,

Warum nutzt du statt Putz nicht irgendeine Java-Lib?
Ich benötioge eine vollwertiges ssh Terminal. ich nutze javash um mir Infos im Vorfeld vom server zu holen.

Für putty: erst irgendwo hin entpacken, und dann starten.

Könntest Du hier ein paar Detail Infos geben?
Ich bringe putty.exe wie von mir gezeigt im jar mit. Dann "kopiere" ich putty .exe in das Filesystem - richtig?

Leider habe ich mit diesen I/O Operationen noch nicht gearbeitet - wäre für einen Tipp dankbar.

Gruß

Ralf
 
Könntest Du hier ein paar Detail Infos geben?
Ich bringe putty.exe wie von mir gezeigt im jar mit. Dann "kopiere" ich putty .exe in das Filesystem - richtig?

Leider habe ich mit diesen I/O Operationen noch nicht gearbeitet - wäre für einen Tipp dankbar.
Java:
Files.copy(getClass().getResourceAsStream("/de/ralfb_web/putty.exe"), Paths.get("pfad","für","putty.exe"))
 
@mihe7 Er hat doch aber nicht danach gefragt, wie er es entpacken kann sondern er möchte es aus dem .jar heraus starten - und das geht nicht (so einfach).
Also liege ich mit meiner Antwort doch nicht daneben...
 
Mein Fehler. Folgendes sollte gehen:
Java:
File jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath());
System.out.println(jarDir.getAbsolutePath());
 
Hallo zusammen,

vielen Dank für die vielen Tipps und Erläuterungen.

Ich will aber kein trojanisches Pferd haben.

Deine Bedenken teile ich natürlich, aber wie erwähnt ist das eine rein interne Applikation und somit würde ich das riskieren 😉

Ich habe das erst einmal folgendermaßen implementiert:

Java:
public void puttyButtonTapped() {
        File jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath());
        File puttyFile = null;
        try {
            puttyFile = File.createTempFile("putty", ".exe", jarDir);
            puttyFile.deleteOnExit();
            Files.copy(getClass().getResourceAsStream("/de/ralfb_web/putty.exe"), Paths.get(puttyFile.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String puttyCmdString = puttyFile.getAbsolutePath() + " -ssh -l " + sde.getSshUser() + " -P " + sde.getSshport() + " -pw "
                + model.getServerRootPasswordString() + " " + sde.getIpaddress();
        Platform.runLater(() -> {
            try {
                Utils.execCmd(puttyCmdString);
            } catch (Exception ex) {
                String msg = String.valueOf(ex);
                messages.appendText("Failed to execute cmd: " + puttyCmdString + "\n" + msg + "\n");
                LOGGER.severe("Failed to execute cmd: " + puttyCmdString + "\n" + msg);
            }
        });
    }

Das funktioniert soweit auch sehr gut, bis auf das kleine Problem das putty*.exe nicht gelöscht wird wenn der user die Applikation beendet aber das putty Fenster noch geöffnet ist. Das könnte natürlich dazu führen das sich viele Files "putty*.exe" anhäufen die keiner mehr aufräumt ...

Eine andere Möglichkeit wäre dann für mich folgende:

Java:
public void puttyButtonTapped() {
        File jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath());
        try {
            Files.copy(getClass().getResourceAsStream("/de/ralfb_web/putty.exe"), Paths.get(jarDir.getAbsolutePath() + File.separator + "putty.exe"), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String puttyCmdString = jarDir.getAbsolutePath() + File.separator + "putty.exe -ssh -l " + sde.getSshUser() + " -P " + sde.getSshport() + " -pw "
                + model.getServerRootPasswordString() + " " + sde.getIpaddress();
        System.out.println(puttyCmdString);
        Platform.runLater(() -> {
            try {
                Utils.execCmd(puttyCmdString);
            } catch (Exception ex) {
                String msg = String.valueOf(ex);
                messages.appendText("Failed to execute cmd: " + puttyCmdString + "\n" + msg + "\n");
                LOGGER.severe("Failed to execute cmd: " + puttyCmdString + "\n" + msg);
            }
        });
    }

Wie würde Ihr das sehen?

Gruß

Ralf
 
Hallo mrBrown,

das hört sich gut an, aber wie müsste ich das denn in meiner JavaFX Applikation implementieren?

Der User beendet die Applikation über das "x" im Fenster. Darauf kann ich vermutlich irgendwie reagieren, habe so etwas z.B. bei mir implementiert:

Java:
primaryStageStartup.setOnCloseRequest(event -> {
                dao.removeExceptionListener();
                LOGGER.info("Close JavaFX Stage: StartupController");
            });

Dann müsste ich ja noch irgendwie abfragen ob der Prozess noch läuft den ich gestartet habe .. ??

Hättest Du auch hierfü ein paar Code Schnipsel wie so etwas aussehen könnte?

Gruß

Ralf
 
Ja, ich nutze das Process API zum starten, sow ie ich das sehe ;-)
Java:
Process process = Runtime.getRuntime().exec(puttyCmdString);
model.setPuttyProcessBooleanProperty(process.isAlive());
System.out.println("Putty Process is Alive:" + model.getPuttyProcessBooleanProperty().getValue());

Das mit dem BooleanProperty habe ich mal gemacht um zu sehen ob ich mit dem Process Objekt "arbeiten" kann.

Wie müsste ich denn jetzt das warten auf den process kodieren?
1. Das Process Objekt merken, z.B. im Model, worauf ich dann von überall zugreifen kann da ich das überall mitgebe.

Java:
Process process = Runtime.getRuntime().exec(puttyCmdString);
model.setPuttyProcess(process);

Wie würde ich aber denn jetzt den Exit des Fenster verhindern, bzw warten. Ich müsste den User ja vermutlich auch mit einem Dialog Fenster darüber informieren. Dieser Schritt und an welcher Stelle ist mir nicht ganz klar. Könntest Du mir hier noch einen Tipp geben?

Gruß

Ralf
 
Hallo mrBrown,

mein erster quick and dirty Versuch:
Java:
stageActionBox.setOnCloseRequest(event -> {
            model.setValidSqlCmdBooleanProperty(false);
            model.setExecuteSqlCmdProperty("");
            if (model.getPuttyProcess() != null) {
                if (model.getPuttyProcess().isAlive()) {
                    System.out.println("Putty isAlive: " + model.getPuttyProcess().isAlive());
                    try {
                        model.getPuttyProcess().waitFor();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            
            
            LOGGER.info("Close JavaFX Stage: ActionBoxController.");
        });

Es passiert nun folgendes ... wenn ich das Fenster "ActionBoxController" schließe (x - Button) und der putty Prozess ist noch aktiv, dann "hängt" das Fenster (Not responding) solange bis ich den putty Prozess beende. Ist ja auch genau das was ich gesagt habe im Code (process.waitFor()), sieht allerding nicht schön aus wenn ein Fenster "so hängt".

Ich vermute Du hattest eine andere Implementation im Kopf.

Gruß

Ralf
 
Wie würde ich aber denn jetzt den Exit des Fenster verhindern, bzw warten. Ich müsste den User ja vermutlich auch mit einem Dialog Fenster darüber informieren. Dieser Schritt und an welcher Stelle ist mir nicht ganz klar. Könntest Du mir hier noch einen Tipp geben?
Du kannst setOnCloseRequest nutzen, um dem Nutzer einen Dialog anzuzeigen und drauf btw auf den laufenden Prozess zu reagieren.

Bin grad unterwegs und hab daher keinen Code zur Hand :/
 
Ups, den Beitrag auf der zweiten Seite übersehen...

Das geht schon in die richtige Richtung. Was genau soll denn passieren, wenn man das Fenster schließt und Putty noch läuft?
 
Im Prinzip passiert ja genau das was passieren soll - das Fenster wird nicht geschlossen bis der putty Prozess beendet wird. Was mir daran nicht gefällt ist das Verhalten des Fenster in der Situation --> Not responding und die Eieruhr dreht. Das gibt mir immer das Gefühl - Programm Fehler - Programm abgestürzt 😵 man könnte das natürlich mit einem Dialog der das Verhalten erklärt abmildern, besser wäre für mich wenn die "Exit Routine" verlassen würde, man erneut auf X clicken könnte bis halt der putty Przoess beendet wurde. Ich vermute aber das wird JavaFX nicht so sehen, denn genau genommen bin ich ich ja im CloseRequest.

Wenn das so "Works as designed" ist werde ich noch mal über das Design an dieser Stelle nachdenken.

Mein Plan B ist hier nicht putty mit auszuliefern, sondern dem User nach dem putty Executable zu fragen und den Pfad dann in einer Apllication.property zu speichern und im Filesystem abzulegen, für den nächsten Programm Start. Im Programm nutze ich dann das vom User auf dem System bereitgestellte putty.

Noch einmal VIELEN Dank für die Unterstützung und schon mal einen schönen sonnigen Feiertag und ggf. ein langes W'ende 😎

Gruß

Ralf
 
Im Prinzip passiert ja genau das was passieren soll - das Fenster wird nicht geschlossen bis der putty Prozess beendet wird.
* Fenster blockiert, bis Putty geschlossen wird.
* Schließen des Fensters wird einfach kommentarlos ignoriert
* Nutzer bekommt einen Warten-Dialog
* Nutzer bekommt einen Dialog, über den er Putty beenden kann
* ...

Alle Möglichkeiten sind umsetzbar 😉


man könnte das natürlich mit einem Dialog der das Verhalten erklärt abmildern, besser wäre für mich wenn die "Exit Routine" verlassen würde, man erneut auf X clicken könnte bis halt der putty Przoess beendet wurde. Ich vermute aber das wird JavaFX nicht so sehen, denn genau genommen bin ich ich ja im CloseRequest.

Wenn das so "Works as designed" ist werde ich noch mal über das Design an dieser Stelle nachdenken.
Lässt sich alles mit ein bisschen Threading umsetzen, im einfachsten Fall bricht man das bebenden ab und startet im Hintergrund einen Thread, der auf Putty wartet und dann das Programm selbst beendet.
 
Ich würde mir folgendes Verhalten vorstellen:
  • Schließen des Fenster wird ignoriert wenn putty noch läuft
  • User bekommt einen Dialog mit den Optionen:
    • Cancel: putty läuft weiter - keine Aktionen
    • Close Putty: putty Prozess wird beendet und schließen Fenster jetzt möglich
Einen Dialog bekomme ich hin 😉 aber wie und wo verhindere ich das schließen des Fenster?
Wäre super wenn Du mir hierzu ein paar Tips geben könntest.

Gruß

Ralf
 
Bin nicht mehr in Eclipse, aber aus dem Kopf würde es dann in etwa so aussehen:
Java:
stageActionBox.setOnCloseRequest(event -> {
            model.setValidSqlCmdBooleanProperty(false);
            model.setExecuteSqlCmdProperty("");
            if (model.getPuttyProcess() != null) {
                if (model.getPuttyProcess().isAlive()) {
                    System.out.println("Putty isAlive: " + model.getPuttyProcess().isAlive());
                    try {
                        event.consume();
                        <<< OPEN dialog >>>
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            
            
            LOGGER.info("Close JavaFX Stage: ActionBoxController.");
        });

So in etwa?
 
Hallo mrBrown,

es funktioniert mit
Code:
event.consume()
so wie von Dir beschrieben. Ich habe das bei mir jetzt eingebaut mit folgendem Verhalten:
  • Beim starten wird ein temporäres File mit dem Inhalt von putty.exe aus dem JAR erstellt. Dieses wird nach beenden der JVM gelöscht.
  • Ist beim beenden des ActionBoxController Window noch ein putty Prozess aktiv, wird das schließen unterbunden und ein Dialog angezeigt. Hier hat man zwei Möglichkeiten:
    • 1. Close putty -> putty Prozess wird beendet.
    • 2. Cancel -> keine Aktion, Fenster bleibt offen, putty läuft weiter.
Hier der Code dazu:

1. Model.class

Java:
public Process getPuttyProcess() {
        return puttyProcess;
    }

    public void setPuttyProcess(Process puttyProcess) {
        this.puttyProcess = puttyProcess;
    }

    public Path getPuttyFile() {
        return puttyFile;
    }

    public void setPuttyFile(Path puttyFile) {
        this.puttyFile = puttyFile;
    }

2. ActionBoxController (Initialize)

Java:
// Create Putty Executable File
        File jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath());
        File puttyFile = null;
        try {
            puttyFile = File.createTempFile("putty", ".exe", jarDir);
            puttyFile.deleteOnExit();
            Files.copy(getClass().getResourceAsStream("/de/ralfb_web/putty.exe"), Paths.get(puttyFile.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING);
            model.setPuttyFile(Paths.get(puttyFile.getAbsolutePath()));
        } catch (IOException ex) {
            String msg = String.valueOf(ex);
            messages.appendText("Failed to creaty putty executable!" + msg);
            LOGGER.severe("Failed to creaty putty executable!" + msg);
        }

3. ActionBoxController (puttyButtonTapped)

Java:
public void puttyButtonTapped() {
        String puttyCmdString = model.getPuttyFile() + " -ssh -l " + sde.getSshUser() + " -P " + sde.getSshport() + " -pw "
                + model.getServerRootPasswordString() + " " + sde.getIpaddress();
        Platform.runLater(() -> {
            try {
                Process process = Runtime.getRuntime().exec(puttyCmdString);
                model.setPuttyProcess(process);
            } catch (Exception ex) {
                String msg = String.valueOf(ex);
                messages.appendText("Failed to execute cmd: " + puttyCmdString + "\n" + msg + "\n");
                LOGGER.severe("Failed to execute cmd: " + puttyCmdString + "\n" + msg);
            }
        });
    }

4. MainController ( Aufruf ActionBoxController Stage -> setOnCloseRequest)

Java:
stageActionBox.setOnCloseRequest(event -> {
            // We don't close the window (event.consume()) if the putty process isAlive.
            if (model.getPuttyProcess() != null) {
                if (model.getPuttyProcess().isAlive()) {
                    event.consume();
                    // Open a Dialog for the User: Close putty or Cancel
                    Integer puttyExistDialogResultInteger = getInputConfirmationDialogPuttyExist();

                    switch (puttyExistDialogResultInteger) {
                    case 0:
                        LOGGER.info(
                                "getInputConfirmationDialogPuttyExist: Error: Error: Return type 0 shouldn't occur!");
                        break;
                    case 1:
                        model.getPuttyProcess().destroyForcibly();
                        break;
                    case 2:
                        break;
                    case 3:
                        LOGGER.info(
                                "getInputConfirmationDialogPuttyExist: Error: Error: Return type 3 shouldn't occur!");
                        break;
                    default:
                        break;
                    }
                    LOGGER.info("Close JavaFX Stage: Couldn't close ActionBoxController. PuTTY process still alive!");
                }
            } else {
                model.setValidSqlCmdBooleanProperty(false);
                model.setExecuteSqlCmdProperty("");
                LOGGER.info("Close JavaFX Stage: ActionBoxController.");
            }

        });

5. MainController (getInputConfirmationDialogPuttyExist)

Java:
private Integer getInputConfirmationDialogPuttyExist() {
        Alert confirmPuttyExist = new Alert(AlertType.CONFIRMATION);

        confirmPuttyExist.setTitle("PuTTY still running ...");
        confirmPuttyExist.setHeaderText("PuTTY application is still running.\nPlease close PuTTY to exit this window!");

        // Create new Buttons
        ButtonType closePutty = new ButtonType("Close PuTTY");
        ButtonType cancel = new ButtonType("Cancel");

        // Remove default ButtonTypes
        confirmPuttyExist.getButtonTypes().clear();

        // Set new defined Buttons
        confirmPuttyExist.getButtonTypes().addAll(closePutty, cancel);
        Optional<ButtonType> option = confirmPuttyExist.showAndWait();

        int r = 0;

        if (option.get() == null) {
        } else if (option.get() == closePutty) {
            r = 1;
        } else if (option.get() == cancel) {
            r = 2;
        } else {
            r = 3;
        }

        return r;
    }

So scheint es nach den ersten schnellen Tests zu funktionieren.

Es gibt lediglich ein Problem wenn der user Cancel drückt und dann im Window ein zweites Mal den putty Button drückt. Jetzt wird ein zweiter putty Prozess gestartet. Dieses Objekt überschreibt das vorherige im Model. Wird danach erneut das Fenster geschlossen und der User wählt "Close Putty" wird das 2 putty Fenster geschlossen und danach lässt sich auch das ActionBoxController Fenster schließen -> der 1. putty Prozess überlebt und somit wird beim schließen der JVM das temporäre putty File nicht gelöscht :-(

Ich sehe hier 2. Ansätze zur Lösung:

1. Ich erlaube nur einen putty Start, sprich ich disable den button wenn 1x gedrückt wurde.
2. Ich erstelle ein Array um die Process Objekte im Model zu speichern. Beim schließen müsste ich dann sicher stellen das alle Prozess Objekte im Array nicht mehr existieren bevor ich das schließen erlaube.

Lösung 1. würde ich mir zutrauen, wobei 2. natürlich besser wäre, bin mir aber nicht sicher ob ich das Code teschnich so auf die reihe bekomme.

Wie seht Ihr das?

Gruß

Ralf
 
Was wäre denn für den Nutzer sinnvoller?

Technisch ist auch Variante zwei nicht schwierig, einfach in eine Liste einfügen und am Ende prüfen, ob einer aus der Liste noch läuft.
 
Hallo mrBrown,

ich habe noch einmal nachgedacht und werde versuchen Lösung 2. zu implementieren. Warum sollte ich das Programm einschränken wenn es nicht nötig ist, unabhängig davon ob der User es nun nutzt oder nicht 😉 mal sehen ob es klappt - werde es dann hier posten.

Gruß

Ralf
 
Hier mal mei erster Versuch, bisher ohne große Tests - scheint aber zu funktionieren:

1. Model

Java:
public List<Process> getPuttyProcessList() {
        return puttyProcessList;
    }

    public void setPuttyProcessList(List<Process> puttyProcessList) {
        this.puttyProcessList = puttyProcessList;
    }
    
    public BooleanProperty getPuttyProcessAliveBooleanProperty() {
        return puttyProcessAliveBooleanProperty;
    }

    public void setPuttyProcessAliveBooleanProperty(Boolean puttyProcessAlive) {
        this.puttyProcessAliveBooleanProperty.setValue(puttyProcessAlive);
    }

2. ActionBoxController

Java:
public void puttyButtonTapped() {
        String puttyCmdString = model.getPuttyFile() + " -ssh -l " + sde.getSshUser() + " -P " + sde.getSshport() + " -pw "
                + model.getServerRootPasswordString() + " " + sde.getIpaddress();
        Platform.runLater(() -> {
            try {
                Process process = Runtime.getRuntime().exec(puttyCmdString);
                model.getPuttyProcessList().add(process);
            } catch (Exception ex) {
                String msg = String.valueOf(ex);
                messages.appendText("Failed to execute cmd: " + puttyCmdString + "\n" + msg + "\n");
                LOGGER.severe("Failed to execute cmd: " + puttyCmdString + "\n" + msg);
            }
        });
    }

3. MainController

Java:
stageActionBox.setOnCloseRequest(event -> {
            model.setPuttyProcessAliveBooleanProperty(false);
            // We don't close the window (event.consume()) if the putty process isAlive.
            if (!model.getPuttyProcessList().isEmpty()) {
                for (Process puttyProcess : model.getPuttyProcessList()) {
                    if (puttyProcess.isAlive()) {
                        model.setPuttyProcessAliveBooleanProperty(true);
                    }
                }
                if (model.getPuttyProcessAliveBooleanProperty().getValue()) {
                    event.consume();
                    // Open a Dialog for the User: Close putty or Cancel
                    Integer puttyExistDialogResultInteger = getInputConfirmationDialogPuttyExist();

                    switch (puttyExistDialogResultInteger) {
                    case 0:
                        LOGGER.info(
                                "getInputConfirmationDialogPuttyExist: Error: Error: Return type 0 shouldn't occur!");
                        break;
                    case 1:
                        for (Process puttyProcess : model.getPuttyProcessList()) {
                            puttyProcess.destroyForcibly();
                        }
                        //model.getPuttyProcess().destroyForcibly();
                        break;
                    case 2:
                        break;
                    case 3:
                        LOGGER.info(
                                "getInputConfirmationDialogPuttyExist: Error: Error: Return type 3 shouldn't occur!");
                        break;
                    default:
                        break;
                    }
                    LOGGER.info("Close JavaFX Stage: Couldn't close ActionBoxController. PuTTY process still alive!");
                }
            } else {
                model.setValidSqlCmdBooleanProperty(false);
                model.setExecuteSqlCmdProperty("");
                LOGGER.info("Close JavaFX Stage: ActionBoxController.");
            }
            });

Gruß

Ralf
 
Die puttyProcessAliveBooleanProperty sieht überflüssig aus, aber sonst siehts okay aus, das if (!model.getPuttyProcessList().isEmpty()) könnte man aber noch entfernen, der Body kann auch bei leerer Liste ausgeführt werden
 
Hallo mrBrown,

den Boolean nutze ich um zu entscheiden ob es noch einen mind. einen aktiven putty Prozess gibt, um dann den Dialog auszugeben und event.consume() auzuführen. Wenn es keinen aktiven Prozess mehr gibt soll der event.consume() nicht ausgeführt werden -> Fenster wird jetzt geschlossen. Ich wusset nicht wie ich es sonst machen soll, das ich ja den Code mit event.consume() und Dialog nicht in die foreach Loop machen kann - könnte dann ja mehrfach ausgeführt werden. Habe ich hioer etwas falsch verstanden?

Gruß

Ralf
 
Einen Boolean brauchst du schon, aber da reicht eine lokale Variable statt der property im Model 😉

So müsste es passen (vermutlich ist aber irgendwo die Klammersetzung falsch).
Das SQL-Zeugs soll vermutlich in jedem Fall gesetzt werden? Bei dir passiert das bisher nur, wenn kein Prozess läuft.

Java:
stageActionBox.setOnCloseRequest(event -> {
           model.setValidSqlCmdBooleanProperty(false);
           model.setExecuteSqlCmdProperty("");

           boolean puttyIsAlive = false; 
           for (Process puttyProcess : model.getPuttyProcessList()) {
                if (puttyProcess.isAlive()) {
                    puttyIsAlive = true
                }
            }
            // oder mit Stream-API:
            // boolean puttyIsAlive = model.getPuttyProcessList.stream().anyMatch(Process:isAlive)

            if (puttyIsAlive) {
                event.consume();
                // Open a Dialog for the User: Close putty or Cancel
                Integer puttyExistDialogResultInteger = getInputConfirmationDialogPuttyExist();
                switch (puttyExistDialogResultInteger) {
                    case 0:
                        LOGGER.info(
                                "getInputConfirmationDialogPuttyExist: Error: Error: Return type 0 shouldn't occur!");
                        break;
                    case 1:
                        for (Process puttyProcess : model.getPuttyProcessList()) {
                            puttyProcess.destroyForcibly();
                        }
                        //model.getPuttyProcess().destroyForcibly();
                        break;
                    case 2:
                        break;
                    case 3:
                        LOGGER.info(
                                "getInputConfirmationDialogPuttyExist: Error: Error: Return type 3 shouldn't occur!");
                        break;
                    default:
                        break;
                }
                LOGGER.info("Close JavaFX Stage: Couldn't close ActionBoxController. PuTTY process still alive!");
            }
        });
 
Hallo mrBrown,

Das SQL-Zeugs soll vermutlich in jedem Fall gesetzt werden?
Vollkommen richtig, habe ich nicht gesehen - Danke für den Hinweis.
Danke auch für den Hinweis mit dem BooleanProperty. Da ist man so im MVC Rausch das man schon gar nicht mehr "lokal" denkt 😉 habe es so geändert und funktioniert.

Vielen Dank für Deine Hilfe!

Gruß

Ralf
 

Neue Themen


Zurück
Oben