PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : java: ausführen externer programme (auch) unter win 32 !?



peschmae
02-09-2002, 10:58
Hallo, Java Programmierer!

Ich hab (wieder) mal nen (blödes ;-)) Problem (bitte angucke und ausprobieren, bei
mir tritt das Problem nur unter Win32 auf):

import java.io.*;
import java.util.*;

public class winprob {
public static void runCommand(String command) {
try {
Process proc = Runtime.getRuntime().exec(command);
proc.waitFor(); //<-- Hier kommt er nicht weiter, da sich der
//Prozess nicht beendet!

System.out.println("Process returned: "+proc.exitValue());
}
catch (Exception e){System.err.println(e);}
}

public static void main(String[] args) {
System.out.println("Going to run");
runCommand("cmd"); //<-- oder irgend ein anderes Konsolenprogram
//mein Ziel: ein "cdrecord -scanbus"
System.out.println("Executed");

}
}


Ziel ist es, mit der Methode runCommand() ein externes Kommmandozeilen - Programm
aufzurufen (konkret: "cdrecord -scanbus", aber das Problem ist überall dasselbe)

Das Problem ist, dass sich die mit getRuntime().exec() ausgeführten Programme nicht
beenden (zu sehen im Taskmanager) und deshalb mein Programm bei proc.waitFor() hängen
bleibt. Das waitFor() ist nötig, da ich ja nacher den Stdout des Programms lesen will
(den Code dazu habe ich der Übersichtlichkeit wegen weggelassen)

Das Problem tritt bei mir _nur_ unter Windows XP auf. Unter Debian funktioniert der Code
perfekt (Beides mit jdk 1.3.02 von Sun/Blackdown)

Funktioniert der Code bei euch? Gibt es einen Workaround?

MfG Peschmä

peschmae
03-09-2002, 13:12
habs selber rausgefunden:

es geht nicht! Win programme können nicht mit ner java shell kommunizieren, nachzulesen unter http://www.java.de/forum/message/2844/

bäääh

soweit ist es also mit javas plattformunabhängigkeit her!

oder ein bisschen linux - patriotischer:
so scheisse ist windows!

MfG Peschmä

anda_skoa
03-09-2002, 14:13
Trifft das auf alle Win32 Programme zu?

Betrifft das nur den waitFor oder auch die Streamkommunikation?

Ciao,
_

peschmae
03-09-2002, 15:21
keine Ahnung...

allerdings hat jedit (www.jedit.org) ein console - plugin mit dem man win consolen progs ausführen kann (unlogik das!)

irgendwie überzeugt mich das zeugs das der typ da geschrieben hat mittlerweile nicht mehr

MfG Peschmä

georgm
03-09-2002, 21:30
Hab da was gefunden:



...
Process p = Runtime.getRuntime().exec("programmname");
...


habs aber noch nicht selber probiert...

anda_skoa
03-09-2002, 22:58
Das stand eh schon im ersten Posting dieses Threads.

Das Problem ist offensichtlich, dass es Probleme mit der Interprozess Kommunikation unter Windows gibt.

Ciao,
_

peschmae
04-09-2002, 10:26
Ich zitiere dazu die Sun - JDK Doku (1.3):

The Runtime.exec methods create a native process and return an instance of a subclass of Process that can be used to control the process and obtain information about it. The class Process provides methods for performing input from the process, performing output to the process, waiting for the process to complete, checking the exit status of the process, and destroying (killing) the process.

The Runtime.exec methods may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Win32, or shell scripts. The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (Process.getOutputStream(), Process.getInputStream(), Process.getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

The subprocess is not killed when there are no more references to the Process object, but rather the subprocess continues executing asynchronously.

There is no requirement that a process represented by a Process object execute asynchronously or concurrently with respect to the Java process that owns the Process object.

Irgendwie komm ich da nicht ganz mit...
wofür braucht den ein prozess ein eigenes Terminal hä?
Das java programm kann also stdin und so lesen/schreiben, soso...

Dieser Text beantwortet aber immer noch nicht die Ursprungsfrage, wieso
die Prozesse, die über meinen (geposteten) code unter win32 gestartet
werden (z.B. cdrecord --scanbus) einfach ins blaue hinaus weiterlaufen...

ich versteh das wirklich nicht, und beim JEdit Console Plugin läuft das
Ganze (z.B. cdrecord --scanbus) reibungslos.

Ich glaub ich lass mal meinen Decompiler auf das Plugin los :-)) ist ja Open Source

MfG Peschmä

anda_skoa
04-09-2002, 13:47
Original geschrieben von peschmae

Irgendwie komm ich da nicht ganz mit...
wofür braucht den ein prozess ein eigenes Terminal hä?
Das java programm kann also stdin und so lesen/schreiben, soso...


Manche Prozesse setzen eine Terminal voraus, zB um das Passwort abzufragen.
ssh zum Beispiel.



Ich glaub ich lass mal meinen Decompiler auf das Plugin los :-)) ist ja Open Source


Wenn es OpenSource ist, warum brauchst du dann einen Decompiler?

Ciao,
_

peschmae
04-09-2002, 15:56
doppelgrins...

hab ich mir schon gedacht, das du das fragst...

hab drum zuhause keine internet-anbindung (auch das gibts noch)

MfG Peschmä

peschmae
05-09-2002, 14:20
puh, das scheint ne ganze menge code zu sein ...
irgendwie wird auch zwischen Betriebssystemen unterschieden, eigentlich nicht gerade das, was ich mir unter java erträumt habe....

ich schau den code mal durch, und falls ichs (übers wochenende) zum Laufen bringe, poste ich das zeugs mal

MfG Peschmä

peschmae
09-09-2002, 11:54
hallo,

hab mal n bisschen im console-plugin code geschnüffelt. irgendwie unterscheidet es zwischen winnt/win9x und unices um dann unterschiedlichen code auszuführen ...

bin dann aber nicht weiter in den code hineingestiegen, da ich folgendes herausgefunden habe:
verwendet man Excelsiors JET (http://www.excelsior-usa.com/jet.html), einen native compiler für win32, so läuft es problemlos.

Nach überlegungen und so kann ich nur sagen: I'm still confused but on a higher level!

Kann mir da jemand helfen? Wieso geht es mit JET, mit normalem Java unter win32 aber nicht?

MfG Peschmä

anda_skoa
09-09-2002, 12:02
Hmm, das hört sich schon ziemlich nach einem JVM Fehler an.

Kannst du es mal mit einer anderen versuchen?
1.2 von Sun, oder einer von IBM.

Ciao,
_

peschmae
09-09-2002, 12:04
ja wie ohne netzanschluss (fluch!)

ich beweg mich mal in die richtung,

allerdings verwendet jet die klassen von sun (jdk 1.3.1), da sollte doch der Fehler auch auftreten, wenn es dann einer ist

MfG Peschmä

peschmae
13-09-2002, 10:57
ich weiss, es gehört sich nicht, aber ich bringe meinen Thread mal wieder nach vorne, da Ceisserer anscheinend (aus den Ferien) wieder da ist...

MfG Peschmä

P.S. bin gerade am ibmjdk kopieren

peschmae
24-09-2002, 09:11
hab mal das aktuelle Sun - Jdk installiert (1.4.1) (n haufen thanks an Schorsch).
Geht wirklich definitiv nicht. Irgendwie kann sich eine extern gestartete Anwendung erst beenden, wenn ich auch die JVM beende...
aber ein Win32 Konsolenprogramm gehört ja nicht zu den Aufgeführten Problemkandidaten die laut api doc da sind:


The Runtime.exec methods may not work well for special processes on certain native platforms, such as native windowing processes, daemon processes, Win16/DOS processes on Win32, or shell scripts. The created

irgendwie ein verd. scheissdreck

hab jetzt drei wochen ferien und werd mir das Console - Plugin von JEdit mal ganz genau anschauen

Falls irgend jemand noch irgend eine Idee hat, die vielleicht gehen könnte, bitte umbedingt melden!

MfG Peschmä

P.S. von wegen Java sei Plattformunabhängig! Pha!

The Ripper
24-09-2002, 12:32
wenn du statt "cmd" beispielsweise "netstat" startest, funktioniert das programm aber korrekt.
Das lässt sich ganz einfach erklären: cmd läuft so lange, bis man ihm über stdin "exit" schickt. Da dein Programm dies aber nicht macht, wartet es vergeblich darauf, dass der befehlsinterpreter beendet wird.

peschmae
28-09-2002, 13:00
das problem ist aber: ich starte cmd gar nicht! ich rufe cdrecord -scanbus direkt auf und das beendet sich ja normalerweise auch sofort
versuch auch mit md5sum und cvs durchgeführt

hab jetzt einfach das waitFor() weggelassen und es läuft. Scheint mir aber ein bisschen riskant, da ja nicht garantiert ist, dass cdrecord den output schon geschrieben hatt, wenn ich mit dem programm weiterfahre... aber bisher gehts

ein weiteres problem, das nur unter win auftrat war, dass ich mit zwei LineNumberReadern abwechslungsweise in einer Schleife versuchte von stdout und stderr zu lesen, bis processState oder so (vom Process her) keine exception mehr wirft, d.h. beendet wurde. Unter windows blockiert sich nun aber das/der Thread, wenn ich versuche aus stdout zu lesen, das programm aber überhaupt keinen stdout generiert, jetzt hab ich das halt für jeden aufruf mit nem flag getrennt gesetzt

MfG Peschmä

anda_skoa
29-09-2002, 21:24
Original geschrieben von peschmae
hab jetzt einfach das waitFor() weggelassen und es läuft. Scheint mir aber ein bisschen riskant, da ja nicht garantiert ist, dass cdrecord den output schon geschrieben hatt, wenn ich mit dem programm weiterfahre... aber bisher gehts


Du könntest versuchen, solange von stdout zu lesen, bis es eine IOException gibt.
Oder, da read() ja blockiert, available() aufrufen.

Ciao,
_

peschmae
01-10-2002, 11:05
afaik gibt available() ja die noch zu lesende bytezahl an, also bringts doch nichts, da ich ja darauf warte, dass cdrecord noch was schreibt und deshalb ist available() sowohl beim warten als auch bei programmende (von cdrecord) jeweils 0 oder?

MfG Peschmä

anda_skoa
01-10-2002, 15:04
Hmm, du hast recht.
Der Stream wird ja nicht geschlossen, wenn der Prozess fertig ist.
Denn das gäbe bei available() eine IOException.
Bei Sockets funktioniert das so, darum ist es mir eingefallen.

Ciao,
_