Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    18

    [JAVA] Errore utilizzando exec (o ProcessBuilder)

    Ottengo questo errore

    quando provo ad eseguire (con netbeans, da shell non ottengo errore ma si pianta la shell) un programma di test scritto in C o in Pascal con le funzioni Runtime.getRuntime().exec(cmd) o come nell'esempio utilizzando il ProcessBuilder. Voglio sottolineare il fatto che se provo a lanciare programmi come calc.exe o cmd.exe funziona tutto bene!

    Per chi volesse provare, questi sono i sorgenti dei vari programmi che ho utilizzato:

    Codice del programma C (simula una shell di echo):
    codice:
    #include <stdio.h>
    
    int main ()
    {
    	char input[100];
    	int cond=1;
    	
    	while (cond) {
    		printf("Prompt: ");
                    scanf("%s", input);
                    printf(" > Output: %s\n\n", input);
    		if (strcmp(input,"quit")==0)
    			cond=0;
    	}
    	
    	return 0;
    }
    Lo stesso programma di echo scritto in pascal
    codice:
    program progPascal;
    
    var	input : string[100];
    	cond : boolean;
    
    begin
    	cond := true;
    	while cond do
    	begin
    		write('Prompt: ');
    		readln(input);		  
            writeln(' Output: ', input);
    		writeln;
    		if input = 'quit' then
    			cond := false;
    	end
    end.
    Ed infine il codice Java del programma che avvia uno dei due programmi scritti sopra
    codice:
    import java.io.*;
    
    public class Test
    {
        public static void main (String[] args) {
            if (args.length < 1) {
                System.out.println("Use: java Test <program.exe>\n\n");
                System.exit(0);
            }
    
            ProcessBuilder builder = new ProcessBuilder(args[0]); // NB: percorso assoluto
    
            try {
                Process p = builder.start();
                BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
                PrintWriter writer = new PrintWriter(new OutputStreamWriter(p.getOutputStream()));
    
                String line;
                // Read output            
                while ((line = reader.readLine()) != null) {
                    System.out.println(line + "\n");
                }
    
                // Write something
                writer.write("Hello!\n");
                writer.flush();
    
                // Read output            
                while ((line = reader.readLine()) != null) {
                    System.out.println(line + "\n");
                }
    
                reader.close();
                writer.close();
    
                // destroy the process
                p.destroy();
    
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    Ho un estremo bisogno di aiuto o di spiegazioni.
    Altrimenti suggeritemi qualche metodo alternativo per costruire interfacce (che non sia inserire il codice dell'eseguibile nell'interfaccia).
    Se qualcuno può provarlo e postare se funziona, magari capisco che è un problema di qualche libreria o altro.
    Vi ringrazio in anticipo.

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Una delle questioni più importanti è che il tuo programma che viene lanciato stampa "Prompt: " ma senza alcun newline dietro. Mentre la readLine() del BufferedReader aspetta fino a quando non riesce a leggere una linea terminata da un newline.
    Quindi la prima questione è che il tuo programmino lanciato non scrive subito una riga completa di newline mentre il tuo programma Java parte cercando di leggere una riga terminata da newline e quindi si blocca.

    Poi comunque la questione è anche un'altra. Se nel tuo programma Java vuoi fare tutto "sincrono" cioè leggi un po', scrivi un po', leggi un po' in sequenza, ecc..... allora devi sapere in anticipo quante righe scrive il programma lanciato. Non puoi fare un normale ciclo while di lettura.
    Se il tuo programma lanciato scrive 1 riga e poi aspetta dell'input, tu da Java non puoi fare un ciclo di readLine() del tipo "finché ce n'é...", perché non ne usciresti più. La riga la leggerebbe ma poi resterebbe lì a leggere.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    18
    Prima di tutto Grazie andbin, alla questione del readLine() non ci avevo proprio pensato.
    La questione del sincronismo invece non è un problema poiché questo è solo un esempio per identificare il problema.
    Però il problema principale è che l'eseguibile non viene avviato: genera l'errore di cui avevo riportato l'immagine, e poi o si pianta la shell, oppure, dopo la chiusura del processo Java, il processo ntvdm.exe inizia ad occupare il 100% della CPU.

    Per dire, non funziona nemmeno questo codice:
    codice:
    import java.io.*;
    
    public class Test3
    {
        public static void main (String[] args) {
            if (args.length < 1) {
                System.out.println("Use: java Test <program.exe>\n\n");
                System.exit(0);
            }        
    
            try {
                Process p = Runtime.getRuntime().exec(args[0]);
    			
                // destroy the process
                p.destroy();
    
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    mi sa tanto che il problema non è banale.
    andbin, ma tu hai provato ad eseguirlo?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Stampede
    Però il problema principale è che l'eseguibile non viene avviato: genera l'errore di cui avevo riportato l'immagine, e poi o si pianta la shell, oppure, dopo la chiusura del processo Java, il processo ntvdm.exe inizia ad occupare il 100% della CPU.

    mi sa tanto che il problema non è banale.
    andbin, ma tu hai provato ad eseguirlo?
    Da quanto ho capito, quello che lanci è un programma in Pascal per DOS (proprio dos puro, 16 bit). In questo caso possono certamente esserci problemi di compatibilità. È capitato anche a me in passato.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    18
    Originariamente inviato da andbin
    Da quanto ho capito, quello che lanci è un programma in Pascal per DOS (proprio dos puro, 16 bit). In questo caso possono certamente esserci problemi di compatibilità. È capitato anche a me in passato.
    Esatto, hai capito bene. Il dubbio mi sorgeva perché fa lo stesso anche con programmi scritti in C. Tu sei riuscito a risolvere in qualche maniera?
    Io ho cercato opzioni sul compilatore pascal per creare eseguibili a 32 bit, ma niente.
    Per questo pensavo di eseguire prima una shell (cmd.exe) fare in modo che questa lanci il mio programma e successivamente inviare comandi al programma e catturarne l'output.
    Non è che ci siano versioni di JDK recenti che hanno risolto il problema?
    Forse dovrei cambiare linguaggio...mah?!

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Stampede
    Non è che ci siano versioni di JDK recenti che hanno risolto il problema?
    Non è di certo un problema di Java o JDK. È proprio il fatto di lanciare un programma DOS puro a 16 bit.

    Potresti provare un progetto su sourceforge (che conosco solo di nome ... non l'ho mai usato) che si chiama DOSBox che è un emulatore per poter far girare sui moderni Windows dei vecchi programmi DOS puri (specialmente giochi, come dice il sito, ma in teoria qualunque programma DOS).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    18
    Originariamente inviato da andbin
    Non è di certo un problema di Java o JDK. È proprio il fatto di lanciare un programma DOS puro a 16 bit.

    Potresti provare un progetto su sourceforge (che conosco solo di nome ... non l'ho mai usato) che si chiama DOSBox che è un emulatore per poter far girare sui moderni Windows dei vecchi programmi DOS puri (specialmente giochi, come dice il sito, ma in teoria qualunque programma DOS).
    Non ho bisogno di un emulatore di DOS, perché i due programmi se vengono avviati da una comunissima shell (Prompt dei comandi) funzionano normalmente. Il problema è che non vengono avviati da un programma Java o da una shell avviata dal programma Java.
    E io dovendo scrivere un'interfaccia grafica non so più come fare.

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    18
    Magari può servire a qualcuno...ho risolto il problema:
    Faccio partire il programma esterno in un Thread, inoltre faccio partire un altro Thread che legge costantemente l'ouput del programma un carattere alla volta, mentre dal main mi occupo della gestione dell'input.
    Il modo corretto per avviare il programma è
    codice:
    process = Runtime.getRuntime().exec("cmd.exe /C G:\\Pascal\\Build\\Galileo.exe", null, new File("G:\\Pascal\Build"));
    eventualmente aggiungendo il percorso assoluto anche di cmd.exe

    Inoltre, non so perché, ma informo che il seguente codice - che dovrebbe essere equivalente - non funziona.

    codice:
    ProcessBuilder builder = new ProcessBuilder("G:\\Pascal\\Build\\Galileo.exe");            
    builder.directory(new File("G:\\Pascal\\Build"));
    process = builder.start();

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.