2 Interprozeßkommunikation

2.1 JVM Ablaufumgebung

2.2 Java Native Interface (JNI)
2.2.1 Verwendung von C-Funktonen in Java Programmen

2.2.2 Zugriff auf Methoden von Java-Objekten in nativem Kode

2.2.3 Zugriff auf Attribute von Java-Objekten in nativem Kode

2.2.4 Ausnahmebehandlung

2.2.5 JNI in Multithread-Anwendungen

2.2.6 Aufruf der JVM in nativen Anwendungen

Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung





Der vom Betriebssystem initiierte Prozess, der durch den Aufruf eines JavaProgramms, erzeugt wird, hat eine Ablaufumgebung, auf die das JavaProgramm zugreifen kann.
Der Zugriff erfolgt über Objekte der Klassen Process und Runtime, die von
der JVM instanziiert werden.
Die aktuelle Umgebung eines Java-Programms erhält man durch Aufruf der
Methode getRuntime, die ein Process-Objekt zurück liefert
Dieses Objekt hat Zugriff auf die Standard-Ein- und -Ausgabe und FehlerStröme der Ablaufumgebung.
Beispiel: Java-Programm, das ein Betriebssystem-Kommando ausführt
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
// Exec.java
import java.io.*;
public class Exec {
public static void main(String args[]) {
try { // create new process, exec command and print output
// of command line by line
String line;
Process p = Runtime.getRuntime().exec(args); // new process
BufferedReader in =
// pipe with
stdout
new BufferedReader
// from p
(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
catch (Exception err) {
err.printStackTrace();
}
} // main
}
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
// Exec.java
import java.io.*;
public class Exec {
public static void main(String args[]) {
try { // create new process, exec command and print output
// of command line by line
String line;
Process p = Runtime.getRuntime().exec(args); // new process
BufferedReader in =
// pipe with
stdout
new BufferedReader
// from p
(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
$ java Exec ps -ao "pid ppid command"
}
PID PPID COMMAND
catch (Exception err) {
771
685 login -pf as
err.printStackTrace(); 772
771 -bash
}
935
772 java Exec ps -ao pid ppid command
} // main
936
935 /bin/ps -ao "pid ppid command"
$
}
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung



Genauso, wie das Java-Programm lesend mit einem erzeugten Prozess
kommunizieren kann, ist es auch möglich, die Standardeingabe eines
erzeugten Prozesses mit Daten zu bestücken.
Beispiel: Arithmetischen Ausdruck vom Programmaufruf senden an bc, das den
Ausdruck auswertet und das Ergebnis wieder an das Java-Programm mit dem
o.a. Mechanismus zurückgibt.
Verwendet wird das Gegenstück zu getInputStream(), die Methode
getOutputStream(), um dem Prozess über seine Standard-Eingabe Daten zu
senden.
$ java Bc (0.8+0.2)*5*2
10
$
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
// Bc.java
import java.io.*;
public class Bc {
public static void main(String args[]) {
try { // create new process, exec bc and print output
String line;
Process p = Runtime.getRuntime().exec("bc"); // new process
BufferedReader in =
// pipe with
new BufferedReader
// stdout from p
(new InputStreamReader(p.getInputStream()));
BufferedWriter out =
// pipe with
new BufferedWriter
// stdin from p
(new OutputStreamWriter(p.getOutputStream()));
out.write("scale=2\n");
// some inits for bc
out.write(args[0],0, args[0].length()); // expression
out.write(’\n');
// bc starts eval
out.flush();
out.close();
// bc is waiting to read from pipe
// program would hang iff not closed
// because in.readLine could not terminate
while ((line = in.readLine()) != null) {
$ java Bc (0.8+0.2)*5*2
System.out.println(line);
10
}
$
in.close();
} catch (Exception err) {err.printStackTrace(); }
} // main
}
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung



In Unix wird jedem Prozess ein Exit-Status zugeordnet, der Auskunft über die
Art der Termination des Prozesses gibt. Der Integer-Wert Null bedeutet dabei
normalerweise, dass ein Prozess fehlerfrei terminiert, ein von Null
verschiedener
Wert
drückt
eine
Beendigung
im
Fehlerfall
aus.
Ein Java-Programm kann auf den Exit-Status des von ihm erzeugten Prozesses
mit der Methode exitValue der Klasse Process zugreifen.
Eine weitere Methode dieser Klasse (destroy) erlaubt es, einen erzeugten
Prozess zu beenden.
Ein Prozess hat eine Ablaufumgebung, in der Umgebungsvariable Werte
annehmen können. Z.B. zeigt die Variable HOME in Unix auf das StandardVerzeichnis eines angemeldeten Benutzers. Durch das Unix-Kommando env
kann
man
sich
die
Umgebungsvariablen
anzeigen
lassen.
Beispiel: Umgebung des erzeugten Prozesses bestimmen
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
// Exec1.java
import java.io.*;
public class Exec1 {
public static void main(String args[]) {
StringBuffer cmdLine = new StringBuffer(args[0]);
for (int i=1; i<args.length; i++)
cmdLine = cmdLine.append(" ").append(args[i]);
try { // create new process, exec command and print output
String line;
// Environment for new process
String[] env = {"NAME=as", new String("HOST=hal")};
Process p = Runtime.getRuntime().exec(cmdLine.toString(),
env);
// Environment
BufferedReader
input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
if (p.exitValue() != 0)
// process terminated normaly?
System.out.println("Command terminated with exit code " +
p.exitValue());
} catch (Exception err) {}
$ java Exec1 env
}
NAME=as
HOST=hal
}
$ java Exec1 cat DateiExistiertNicht
Command terminated with exit code 1
$
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung




Wenn ein Java-Programm ausgeführt wird, so wird es von der JVM in einem
Betriebssystemprozess
verarbeitet.
Jeder Prozess kann asynchron eintretende Ereignisse empfangen. Diese
werden
je
nach
Betriebsystem
unterschiedlich
behandelt.
In Unix reagiert ein Prozess auf ein eintreffendes Signal mit einem je nach
Signal
spezifizierten
Default-Verhalten.
Will man das Verhalten per Programm beeinflussen, muss man einen SignalHandler schreiben, der den gewünschten Kode ausführt, wenn ein Signal
eintrifft.
Die Behandlung von Signalen im JVM-Prozess erfolgt mehrstufig.
 Wenn der JVM-Prozess ein Signal empfängt, wird zunächst geprüft, ob es
für diesen Prozess eine eigene Signalbehandlungsroutine gibt.
 Ist dies der Fall, wird das Signal durch ihn behandelt, ansonsten wird es an
die JVM weitergereicht.
Damit ein Signal von der JVM mit einem in Java geschriebenen Signal-Handler
abgefangen werden kann, kann die Klasse sun.misc.Signal verwendet
werden. Eine Java Signalbehandlung unterscheidet sich nicht viel von einem
Signal-Handler der z.B. in C realisiert ist. Der Unterschied ist, dass ein
eintreffendes Signal bewirkt, dass die JVM einen neuen Thread erzeugt, der die
Signalbehandlung durchführt.
Beispiel: Abfangen von TERM
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JVM Ablaufumgebung
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
// SignalDemo.java
import sun.misc.Signal;
import sun.misc.SignalHandler;
class SignalDemo {
public static void main(String[] args) {
try { // Install signal handler
Handler h = new Handler("TERM");
// 15
while (true) {
System.out.println("main");
Thread.sleep(1000);
}
} catch (Exception e) {
System.out.println("AppWrap exception "+e);
}
}
}
class Handler implements SignalHandler {
Handler (String signalName) {
Signal signal = new Signal(signalName);
Signal.handle(signal,this); // handle signal
}
// Signal handler method
public void handle(Signal sig) {
System.out.println("Signal handler called for signal "+sig);
}
}
Alois Schütte
Advanced System Programming
Interprozeßkommunikation: JNI
Alois Schütte
Advanced System Programming

Interprozeßkommunikation