Newsgroup: it.comp.java
Titolo: waitFor()

Il seguente codice ...
import java.io.*;
class Esecutore
{
public static void main(String[] S) throws Exception
{
  Process p = Runtime.getRuntime().exec("javac a.java");
  System.out.print("Faccio waitfor....");
  int exitCode=p.waitFor();  //! ! ! ! ! Il prg. si blocca qui
  System.out.println("fatta");
  if (exitCode!=0)
  {
   System.out.println("L'errore di compilazione e' stato: ");
   BufferedReader e = new BufferedReader (new
InputStreamReader(p.getErrorStream()));
   for(;;)
   {
    String line=e.readLine();
    if (line==null) break;
    System.out.println(line);
   }
  }
}
}
... chiama il compilatore "javac" chiedendogli di compilare il file java
"a.java" che metto qui di seguito e che come si vede contiene un errore
sintattico (manca una virgoletta nella println)
public class a
{
public static void main(String[] a)
{
  System.out.println(Prova");
}
}
Quello che mi aspettavo dall'esecuzione del main della classe "Esecutore" e'
che esso stampasse l'errore riportato dal compilatore "javac" quando si
accorge che mancano le virgolette. Invece la classe "Esecutore" rimane
bloccata sulla waitFor() a fare non so cosa. Se come errore nella classe "a"
metto il seguente (mancanza della virgoletta a fine stringa)
  System.out.println("Prova);
oppure questo (chiamata ad un metodo che non esiste)
System.out.rintln("Prova");
la classe esecutore fa il suo dovere riportando la segnalazione di errore. A
parte il fatto che non riesco a spiegarmi perche' con alcuni errori il prog.
si comporta correttamente ed in altri no, ho pensato che gli stream
dovessero essere letti prima della terminazione del programma e quindi prima
di fare la waitFor() ed ho trasformato la classe "Esecutore" cosi':
import java.io.*;
class Exec
{
public static void main(String[] S) throws Exception
{
  Process p = Runtime.getRuntime().exec("javac a.java");
  BufferedReader e = new BufferedReader (new
InputStreamReader(p.getErrorStream()));
  //if (e.ready())            // Si noti che la riga e' commentata
  {
   System.out.println("L'errore di compilazione e' stato: ");
   for(;;)
   {
    String line=e.readLine();
    if (line==null) break;
    System.out.println(line);
   }
  }
  System.out.print("Faccio waitfor....");
  int exitCode=p.waitFor();  //! ! ! ! ! Il prg. si blocca qui
  System.out.println("fatta");
}
}
Ora tutto va correttamente. Riprende pero' a non funzionare se tolgo il
commento alla riga che prima di leggere dallo stream testo se stderr
contiene qualcosa.
Domande:
1 Gli stream dove il processo scrive non dovrebbero essere disponibili anche
quando il processo e' terminato?
2 Oppure: non dovrebbe il processo terminare ed essere distrutto solo quando
ha finito di computare e gli stream su cui ha scritto sono stati letti da
qualcuno?
3 Come faccio a leggere da uno stream solo se ci sono dei dati e quindi
senza bloccarmi?
4 Non ho capito niente? Indicatemi un libro che tratta in dettaglio queste
cose.
P.S. Tutte le prove le ho fatte con il jdk1.1.6 sotto NT. Se qualcuno
potesse/volesse provare sotto Unix o altro farebbe una cosa utile. Grazie.


[deletia]
| --
| Bruno Bossola
| Groupware/Intranet B.U.           Phone:  +39-11-2252211
| ATOS SpA v.Vaninetti 27           Fax:    +39-11-2203182
| I-10148 Torino ITALY              Change NOSPAM in atos to email me!

1.0 allora puoi invocare direttamente il compilatore:
[....]
Ho provato il seguente codice
-----------------------
import java.io.*;
class prova
{
 public void compile(OutputStream os, String tag, String filename)
 {
  sun.tools.javac.Main javac;
  javac  = new sun.tools.javac.Main(os, tag);
  boolean result = javac.compile(filename);
 }
}
-----------------
....fatto sul modello di quello da te consigliatomi ma purtroppo non si
compila. Mi viene segnalato l'errore
prova.java:8: Incompatible type for method. Can't convert java.lang.String
to java.lang.String[].
                boolean result = javac.compile(filename);
Ho anche provato a chiamare
    javac.compileClasses
ma mi viene segnalato l'errore:
prova.java:8: Method compileClasses(java.lang.String) not found in class
sun.too
ls.javac.Main.
                boolean result = javac.compileClasses(filename);
bho! Grazie di tutto e ciao!