Wie laufenden Prozess einfangen?

otxws

Mitglied
Guten Tag!


Ich habe eine simple Java-Anwendung geschrieben:
Java:
package com.mydomain.jsm.app.a;

public class MainClass
{
	public static void main(String[] args)
	{
		System.out.println("Application 1");
	}
	
	public MainClass()
	{
	}
	
	public synchronized String Responder()
	{
		return "Well done";
	}
}

Dazu gibt es noch eine zweite Anwedung, wobei der Quellcode der nun folgt funktioniert aber nicht zu dem von mir gewünschten Ergebnis führt:
Java:
package com.mydomain.jsm.app.b;

public class MainClass
{
	public static void main(String[] args)
	{
		System.out.println("Application 2");
		System.out.println((new com.mydomain.jsm.app.a.MainClass()).Responder());
	}
	
	public MainClass()
	{
	}
}

Starte ich Application 2 erscheint auf der Konsole:
Code:
Application 2
Well done

Soweit so gut. Hier wurde von Application 2 aus Application 1 initiiert und dann die Methode aufgerufen. Ich möchte das Application 2 auf die Methode von Application 1 zugreift, aber ohne diese zu initiieren. Das heißt wenn Application 1 läuft erscheint "Well done", wenn Application 1 jedoch nicht läuft entsteht eine Fehlermeldung. Aussehen könnte das im Prinzip so:
Code:
try
{
	System.out.println((no.absolute.idea.GrepWindowByAnything("com.mydomain.jsm.app.a.MainClass")).Responder());
}
catch(no.absolute.idea.AnyException exception)
{
}

Ich habe schon Shared Memory Lösungen Richtung JNI / JavaSpaces angeschaut, würde aber gerne bei diesem Konzept bleiben. Ich vermute mit der ThreadID lässt sich vielleicht was machen, aber an die muss ich erstmal ran kommen. Früher unter Windows 98 mit Visual Basic ging das Anhand des Fenstertitels, von daher bin ich mir sicher das soetwas heute erst recht gehen muss. Die Frage die bleibt ist wie. :bahnhof:


Bernd
 
Zuletzt bearbeitet:

Niki

Top Contributor
ist es richtig dass du wissen willst ob eine Applikation bereits läuft? Am besten ist du öffnest mit ApplikationA einen ServerSocket an einem bestimmten Port und ApplikatonB versucht sich zu verbinden. Haut die Verbindung hin weißt du, dass ApplikationA läuft, ansonsten eben nicht. Über RMI Registry könnte man das auch spielen, oder über ein File welches von ApplikationA geschrieben bzw. wieder gelöscht wird. Nur ein paar Ideen.
 

KrokoDiehl

Top Contributor
Zunächst einmal: Die Zeile
Java:
System.out.println((new com.mydomain.jsm.app.a.MainClass()).Responder());
startet keinen neuen Prozess, sondern erzeugt nur ein neues Objekt von com.mydomain.jsm.app.a.MainClass.

Wenn du aus Anwendung X eine andere Java-Anwendung Y startest (mittels
Code:
Runtime.getRuntime() ...
) erhälst du ein Process-Objekt. Darüber kannst du den gestarteten Prozess etwas kontrollieren und z.B. seine Ausgaben lesen.
Ansonsten hat Niki schon gute Stichpunkte geliefert.
 

otxws

Mitglied
Guten Tag!


RMI scheidet für mich definitiv aus genauso wie jede Art von Netzwerklösungen, z.B. TCP/IP-Verbindung über localhost zwischen den beiden Applikationen. Das aus Application 2 heraus Application 1 aufgerufen wird (sei es ein Objekt davon zu erzeugen oder tatsächlich einen neuen Prozess zu erzeugen) ist auch ausgeschlossen.

Die Idee ist das der Benutzer per Doppelklick im Windows Explorer oder anderen Dateimanager Application 1 start und per Doppelklick im Windows Explorer oder anderen Dateimanager Application 2 startet. Beide Applikationen wurden getrennt voneinander durch den Benutzer gestartet. Aus dieser Situation heraus soll Application 2 die Application 1 einfangen und deren Methode Responder aufrufen. Sollte Application 1 jedoch noch nicht durch den Benutzer gestartet worden sein entsteht ein Fehler (z.B. Ergebnis ist Null, Exception, ...).


Bernd


@KrokoDiehl: Sorry wegen der schlampigen Formulierung, hast natürlich Recht.
 
Zuletzt bearbeitet:

KrokoDiehl

Top Contributor
Gut, wenn das so gehen soll, gibt es schon reichlich weniger Möglichkeiten. Interprozesskommunikation bei Java geht allerdings (fast) nur via Sockets.
Hier die einfachste Variante: App1 belegt beim Starten eine Port und App2 prüft, wenn es startet, ob der Port belegt ist (ggfs auch ob er korrekt antwortet). Sonst gibt es eine entsprechende Meldung.
Doof eben, wenn dieser Port von etwas ganz anderem belegt wird.

Oder wenn's ganz ohne Sockets sein soll: App1 legt irgendwo eine Datei an (Home-Verz. oder so) oder schreibt einen Registry-Eintrag (Preferences-API von Java) und App2 prüft darauf.

Ansonsten muss man ggfs das Betriebssystem bemühen - wird aber schwierig, wenn alle Java-Anwendungen als java.exe laufen, oder man macht es wie die Visual-VM (ist beim JDK dabei). Aber wie die es macht, keine Ahnung ... :)
 
T

tuxedo

Gast
Unter Windows könnte man mit hilfe von SWT noch Subclassing betreiben. Die eine Anwendung schickt dann eine Broadcast Window Message raus, welche von der anderen, welche Subclassing nutzt, abfängt und ein entsprechendes Ergebnis zurückliefert.

Ist allerdings nicht ganz einfach und auch nur im extremfall zu benutzen, da man für's Subclassing und manuelle senden von Window Messages eine etwas tiefer liegende SWT Klasse nehmen muss und man sich somit sofort an die jeweilige Plattform (32bit/64bit) der JVM bindet.

Wenns es absolut keine Sockets sein sollen (warum eigentlich nicht`? Stört doch i.d.R. keinen, läuft ja alles unsichtbar auf localhost), dann bleibt nur noch JNA/JNI oder solche Krücken wie über's Dateisysrem/JavaPreferenceStore (was unter Windows die Registry ist)

- Alex
 

otxws

Mitglied
Guten Tag!


Experimentiere gerade mit JNI herum. Würde den Teil der Anwendung der mit anderen Prozessen kommunizieren soll in eine DLL/SO-Datei auslagern. Momentan arbeite ich unter Microsoft Windows XP mit dem Visual Studio.

Meine Java-Testapplikation sieht nun so aus:
Java:
package com.mydomain.jsm.app.b;

public class MainClass
{
	private native void DoExternalStuff(int value);
	
	private void callback(int result)
	{
		System.out.println("Get: " + result);
	}

	public MainClass()
	{
		
	}
	
	public static void main(String[] args)
	{
		System.out.println("Application 2");
		com.mydomain.jsm.app.b.MainClass testy = new com.mydomain.jsm.app.b.MainClass();
		int i = 3;
		System.out.println("Call: " + i);
		testy.DoExternalStuff(i);
	}
	
	static {
		System.loadLibrary("DLLFileName");
    }
}

Mit javah -jni habe ich das passender Headerfile für C++ generiert. Die DLL in C++ sieht momentan so aus:
Code:
#include <jni.h>
#include <stdio.h>
#include "MainClass.h"

JNIEXPORT void JNICALL Java_MainClass_DoExternalStuff(
	JNIEnv *env, jobject in_obj, jint  parameter_value)
{
	jclass icls = env->GetObjectClass(env, in_obj);

	jmethodID jmid = env->GetMethodID(
		env, icls, "callback", "(I)V");

	if (jmid == 0)
	{
		//...
	}

	int result = 2 * parameter_value;

	env->CallVoidMethod(env, in_obj, jmid, result);
}

Das Problem hier ist, das der Compiler meckert die Anzahl der Argumente würde nicht stimmen:
Code:
error C2660: 'JNIEnv_::GetObjectClass': Funktion akzeptiert keine 2 Argumente
error C2660: 'JNIEnv_::GetMethodID': Funktion akzeptiert keine 4 Argumente
error C2664: 'JNIEnv_::CallVoidMethod': Konvertierung des Parameters 1 von 'JNIEnv *' in 'jobject' nicht möglich

Laut Dokumentation kann das aber nicht sein! :lol:

Die JNI-Headerdateien findet der Compiler und auch die generierte Headerdatei. Auch sind alle define gesetzt, damit der Compiler weiß das es sich um Windows und C++ handelt.

Ich weiß, das ist ein Java-Forum, aber hat trotzdem jemand eine Idee? Die Google-Treffer sind in Sprachen deren Zeichen ich nicht kenne und vermutlich östlich von Europa liegt... ???:L

Für Alternativstrategien bin ich natürlich auch weiterhin offen!


Bernd
 
Zuletzt bearbeitet:

otxws

Mitglied
Guten Tag!


Für alle die es interessiert, in C++ ist die Syntax eine andere wie in C:
Code:
#include <jni.h>
#include <stdio.h>
#include "MainClass.h"

JNIEXPORT void JNICALL Java_MainClass_DoExternalStuff(
	JNIEnv *env, jobject in_obj, jint  parameter_value)
{
	jclass icls = env->GetObjectClass(in_obj);

	jmethodID jmid = env->GetMethodID(icls, "callback", "(I)V");

	if (jmid == 0)
	{
		//...
	}

	int result = 2 * parameter_value;

	env->CallVoidMethod(in_obj, jmid, result);
}


Bernd
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Wert an laufenden Java-Prozess übergeben Allgemeine Java-Themen 10
F Pfad der laufenden JAR ermitteln (mit Archivnamen) Allgemeine Java-Themen 2
N Unter Mac Os X alle laufenden Prozesse ausgeben Allgemeine Java-Themen 3
S Speicherprobleme bei zwei laufenden JAVA-Applikationen Allgemeine Java-Themen 10
J Warten bis cmd Prozess fertig ist Allgemeine Java-Themen 2
L Prozess automatisch beenden Allgemeine Java-Themen 8
R PIPE Kommunikation mit Prozess blockiert Allgemeine Java-Themen 0
L Java Web Start - generierter Prozess Allgemeine Java-Themen 4
Tom299 Beliebiges Windows-Programm / Prozess in den Vordergrund bringen Allgemeine Java-Themen 4
A Linux: Native Library mit Rootrechten ohne Prozess mit sudo zu starten Allgemeine Java-Themen 1
K Problem: Java-Klasse mit mehreren Threads als eigenen Prozess starten Allgemeine Java-Themen 3
Thallius Neuen Prozess starten, der auch nach Beedingung des Starter-Prozesses weiterläuft? Allgemeine Java-Themen 5
B Erkennen, wann Prozess beendet ist, dann Thread beenden. Allgemeine Java-Themen 6
D Grafisches Frontend zu einem Java Prozess erstellen Allgemeine Java-Themen 0
D neuen Prozess starten und anwendung beenden. Allgemeine Java-Themen 3
L Java Prozess 100% -> Analyse Allgemeine Java-Themen 2
P Scanner als Inputstream für Java Prozess Allgemeine Java-Themen 4
J Aktuellen Prozess herausfinden. Allgemeine Java-Themen 3
GUI-Programmer Prozess eine Bezeichnung geben Allgemeine Java-Themen 3
M Einen Prozess "crashen" lassen Allgemeine Java-Themen 9
I %AppData% Variable für einen Prozess setzen Allgemeine Java-Themen 23
E externen Prozess schließen, wenn Programm geschlossen wird Allgemeine Java-Themen 2
S Prozess der von anderem Prozess gestartet wurde beenden? (Windows Bildschirmtastatur) Allgemeine Java-Themen 4
Nicer Prozess über Prozessnamen beenden Allgemeine Java-Themen 15
K Prozess starten, überwachen und beenden Allgemeine Java-Themen 4
X Prozess-Objekt nach Ausführung der destroy-Methode null oder nicht null ? Allgemeine Java-Themen 10
D Shell-Prozess lässt Thread nicht enden Allgemeine Java-Themen 4
0din Prozess einer .jar umbenennen Allgemeine Java-Themen 7
data89 Java als Boot-Prozess/Daemon? Allgemeine Java-Themen 6
reibi Kill eines Java-Prozesses und Stop-Prozess Allgemeine Java-Themen 3
T In der JVM einen weiteren, unabhängigen Prozess starten Allgemeine Java-Themen 11
G Runtime.exec - Prozess "mittendrin" "einfach Allgemeine Java-Themen 4
Y ProcessBuilder, Prozess wird gestartet, aber Anwendung nicht Allgemeine Java-Themen 5
M String an externen Prozess senden/auslesen Allgemeine Java-Themen 25
T Prozess beenden Allgemeine Java-Themen 3
J Zweiter Prozess der alle x Sekunden etwas abfragen soll Allgemeine Java-Themen 2
G Prozess direkt starten beim Start des Appservers Allgemeine Java-Themen 3
G Prozess-Status Allgemeine Java-Themen 8
H Kommunikation mit einem c-Prozess funzt nicht richtig Allgemeine Java-Themen 5
L Zugriff auf anderen Prozess der VM Allgemeine Java-Themen 9
C nur einen Prozess eines Programmes erlauben Allgemeine Java-Themen 8
S was passiert bei diesem filereader prozess Allgemeine Java-Themen 2
A Java Prozess in neuer JVM Allgemeine Java-Themen 8
K Prozess-Visualisierung: Stichwörter gesucht Allgemeine Java-Themen 4
D runtime.exec --> Prozess hängt sich auf Allgemeine Java-Themen 7
S Prozess javaw.exe läuft immer noch, obwohl Programm beendet Allgemeine Java-Themen 6
M Thread als eigenständiger Linux Prozess mit PID Allgemeine Java-Themen 8
clemente Swing Applikation killt kwin Prozess (unter Linux / KDE) Allgemeine Java-Themen 3
M Zweiten Prozess in Java starten! Allgemeine Java-Themen 5
R Kontrolle über Externe Prozess Allgemeine Java-Themen 5
G Prozess beenden, wenn er hängt Allgemeine Java-Themen 9
S Wie eine Anwendung als neuer Prozess starten? Allgemeine Java-Themen 8
P wie beende ich einen prozess? Allgemeine Java-Themen 3
S blockierenden Prozess stoppen Allgemeine Java-Themen 13
G "Einfangen" des Java / Javac outputs. Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben