# Auf Java-Objekt aus anderer Instanz zugreifen



## erazor2106 (6. Sep 2012)

Hallo Leute,

ich hoffe ich rede jetzt nicht zu viel Müll 

Undzwar starte ich auf einem Server ein Javaprogramm in welchem ich ein Objekt erzeuge:


```
Player testplayer = new Player();
```

Jetzt starte ich ein zweites Programm mit welchem ich das Player-Objekt des anderen Programmes verändern möchte, z.b.


```
testplayer.setPath(pfad);
```

Ist es möglich auf diese Instanz zuzugreifen, z.b. mit Threads oder so?

VIelen Dank schon mal und viele Grüße
erazor


----------



## Marcinek (6. Sep 2012)

Stichwort "Interprozess-Kommunikation" via Sockets, Datei, oder RMI


----------



## erazor2106 (6. Sep 2012)

danke für deine Antwort. 

und wie ist es wenn ich das gleiche Programm 2mal starte?


----------



## maki (6. Sep 2012)

Genauso.


----------



## erazor2106 (6. Sep 2012)

also RMI sieht auf den ersten blick wirklich gut aus, aber auch recht kompliziert für meinen jetzigen wissensstand.

Könnte mir da vllt. jemand weiterhelfen bzw. starthilfe geben?
Super wäre es wenn ich das Objekt in mein 2. Programm holen könnte und dort darauf zugreifen kann als hätte ich es dort generiert


----------



## Michael... (6. Sep 2012)

Die Möglichkeiten wurden ja bereits genannt. Alternative zur Datei: Datenbank.
Wenn das ein Multiplayer Spiel werden soll, kommst Du um Sockets oder RMI nicht herum.


----------



## erazor2106 (6. Sep 2012)

nene, kein Spiel.

OK, kurz zum Hintergrund. Ich rufe das Programm auf und lasse ein Video darin abspielen (ich starte einen Stream auf dem Server über das javaprogramm)
Wenn ich das gleiche Programm oder ein anderes Programm (egal jetzt) starte möchte ich auf diesen Stream einwirken können, also das Video z.b. anhalten können. Dazu brauche ich Zugriff auf das Objekt "mediaPlayer" aus dem ersten Programm


----------



## erazor2106 (7. Sep 2012)

Hier hab ich eine schöne Anleitung zu RMI gefunden:

Der Netzlogger: Einfache RMI-Anwendung mit Java

Ich probier mich mal dran


----------



## SlaterB (7. Sep 2012)

> Dazu brauche ich Zugriff auf das Objekt "mediaPlayer" aus dem ersten Programm 

bevor du auf die Idee kommst: 
du kannst dir nicht das Objekt 'rüberholen', verändern und annehmen dass es auf das Originalprogramm Auswirkungen hat, 
eher hast du eine Kopie, wobei man gewisse Daten wie GUI/ Stream/ Konstrollstrukturen die diese beinhalten sowieso nur begrenzt kopieren kann,

richtiger ist die Sichtweise, dass du einfache Kommandos/ Text-Nachrichten überträgst und daraufhin auf der anderen Seite irgendjemand, der aktiv auf diese Nachrichten wartet, reagiert und das Objekt dort verwendet

freilich können höhere Frameworks wie RMI intern so arbeiten und es dennoch für den Programmierer wie einen einfachen Direkt-Zugriff aussehen lassen


----------



## erazor2106 (10. Sep 2012)

Habe das ganze nun anhand mehrerer Beispiele versucht aufzubauen, erhalte aber folgende Fehler:

Serverfehler (getRegistry): non-JRMP server at remote endpoint
Serverfehler (RemoteException):Connection refused to host: localhost; nested exception is:

Quellcodeaufruf Server:

```
public class Server extends UnicastRemoteObject implements ServerInterface
{
...

    public Server()     throws RemoteException
     {
        super();

        Registry reg = LocateRegistry.createRegistry(1084);                
        reg.rebind("rmi://192.168.70.10/MeinServer", new Server());
     }
}
```


Quellcodeaufruf Client:

```
String ServerIP      = "192.168.70.10:1084";
String RMIServerName = "MeinServer";
         
ServerInterface server = (ServerInterface) Naming.lookup("//" + ServerIP + "/" + RMIServerName );
```
 
Habe  da schon einiges rumprobiert: anderer Port, die URL mit oder ohne rmi, anderer Servername, bind statt rebind, ....

Statt obigen Fehler erhalte ich dann ObjId already in use, Port in use, ...

Verzweifel dann langsam ;(


----------



## SlaterB (10. Sep 2012)

oha, leider kann ich persönlich da nicht helfen, richte so gut wie nie sowas neu ein und kann legendär schnell solche Einstellungen vergessen

Moderator-Hinweis:
wenn keiner bald antwortet und wirklich alle Tutorials im Internet 'RMI einrichten' nix bringen,
dann vielleicht neues Thema erstellen für mehr Aufmerksamkeit


----------



## FArt (10. Sep 2012)

Das passt nicht: die Fehlermeldung sagt, dass du dich nicht auf localhost verbinden kannst, der lookup wird aber mit der IP Adresse durchgeführt.
Auch wenn deine aktuelle IP Adresse obige Adresse ist, ist das nicht localhost!


----------



## erazor2106 (10. Sep 2012)

ok, ist der Rest sonst ok?

Hab jetzt noch eine Klasse ServerInterfaceImpl hinzugefügt in der nun die ganzen Methoden liegen. Server sieht nun wie folgt aus:


```
public class Server
{
...

    public Server()     throws RemoteException
     {
         Registry reg = LocateRegistry.createRegistry(1084);                
         reg.rebind("rmi://192.168.70.10/MeinServer", new ServerInterfaceImpl());
     }
}
```

ServerInterfaceImpl:


```
public class ServerInterfaceImpl extends UnicastRemoteObject implements ServerInterface
  {
        public ServerInterfaceImpl() throws RemoteException
         {
            super();
         }

     ...
  }
```

Das ganze lässt sich nun starten, erhalte aber andere Fehlemreldungen:
"access denied (java.net.SocketPermission 192.168.1.210:1077 connect,resolve)
[CoyoteAdapter] An exception or error occurred in the container during the request processing
java.security.AccessControlException: access denied (java.lang.RuntimePermission org.jboss.security.SecurityAssociation.setPrincipalInfo)"


----------



## FArt (10. Sep 2012)

erazor2106 hat gesagt.:


> [CoyoteAdapter] An exception or error occurred in the container during the request processing
> java.security.AccessControlException: access denied (java.lang.RuntimePermission org.jboss.security.SecurityAssociation.setPrincipalInfo)"



Du Held! Das ganze läuft in einem Tomcat, also einer gemanagten Umgebung? Das ist ja etwas völlig anderes. 

Ist natürlich suboptimal, so wichtige Informationen hier zu unterschlagen. Wenn du sinnvolle Hilfe erwartest, solltest du relevante Inforamtionen mitliefern: Infrastruktur, Laufzeitumgebung, minimaler Testcode, der das Problem isoliert und relevante Konfigurationen.

Beschreib mal die Infrastruktur. Es sieht nicht aus, als hättest du etwas sinnvolles vor. Vermtlich möchtest du einen Applicationserver um den Tomcat nachbauen ?!?

Nimm TomEE oder gleich einen echten Applicationserver und hör auf mit RMI rumzupopeln.

Warum benötigst du überhaupt einen Tomcat? Vielleicht tut es ja auch z.B. Spring und SpringRemoting.


----------



## FArt (10. Sep 2012)

Ahrg, jetzt sehe ich es erst.. ist ja noch schlimmer... das kommt ja aus dem JBoss...

Du hast schon einen AS?
Was machst du dann da eigentlich?


----------



## erazor2106 (10. Sep 2012)

Achso, JBoss ist ein Problem :lol: oder lieber ;(

Mit dem JBoss hab ich einen Webservice laufen mit dem Leute auf einer JSp-Seite den Server manipulieren sollen, daher brauche ich RMI


----------



## SlaterB (10. Sep 2012)

ein JBoss, ein WebService usw. ist doch schon bzw. gerade zu Kommunikation in der Lage, wozu noch RMI?
der Server selber kann natürlich nicht ganz so gut aktiv werden, falls die andere Seite nicht auch ein Server ist,
(und Aufbau einer Client-Verbindung nicht genauso verhindert wird..)

aber was ist mit der Gegenseite, die muss bei RMI ja sowieso mitspielen,
 kann die nicht zu dem Server irgendeine Verbindung aufbauen, periodisch nachfragen ob ein Objekt zu ändern ist usw.?
ok, ständiges Nachfragen klingt nicht sehr attraktiv..


----------



## erazor2106 (10. Sep 2012)

@SlaterB: ich danke dir sehr für deine Bemühungen und deine Geduld.

Ja klar kann der JBoss einiges machen. Ich habe allerdings 2 verschiedene Serveranwendungen welche RMI verwenden. Von daher dachte ich ist es sinnvoll die Clientseite im JBoss auch auf RMI aufzubauen.

D.h. ich könnte nur an der Clientseite was ganz anderes machen, die serverseite ist wie oben beschrieben. Verstehe die ganzen Fehler auch nicht, auch nicht warum ich das ganze nicht auch auf Port 1099 unter dem Namen "MeinServer" registrieren kann.


----------



## erazor2106 (10. Sep 2012)

muss ich die rmiregistry.exe noch starten oder ist das mittlerweile hinfällig?

Habe da gegenteilige aussagen gelesen


----------



## FArt (10. Sep 2012)

erazor2106 hat gesagt.:


> Von daher dachte ich ist es sinnvoll die Clientseite im JBoss auch auf RMI aufzubauen.


Nein.



erazor2106 hat gesagt.:


> D.h. ich könnte nur an der Clientseite was ganz anderes machen, die serverseite ist wie oben beschrieben.


Ja, z.B. EJB Kommunikation.



erazor2106 hat gesagt.:


> Verstehe die ganzen Fehler auch nicht, auch nicht warum ich das ganze nicht auch auf Port 1099 unter dem Namen "MeinServer" registrieren kann.


Ich schon. Weil auf dem Port bereits ein JBoss Service läuft: JNP. Und JBoss hat auch schon einen eigenen RMI Server.



erazor2106 hat gesagt.:


> muss ich die rmiregistry.exe noch starten oder ist das mittlerweile hinfällig?
> Habe da gegenteilige aussagen gelesen


Vergiss RMI.


----------



## erazor2106 (10. Sep 2012)

hmm ok, kannst du mir dann bitte erklären wie ich es im JBoss ohne RMI mache?

Binde nur meine JSP-Datei wie folgt ein:


```
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,	"org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES,   	    "org.jboss.naming:org.jnp.interfaces");
p.put(Context.PROVIDER_URL, 			    "jnp://localhost:1099");
Context ctx = new InitialContext(p);
		 
Object ref = ctx.lookup("anwendung/remote");
anwendungRemote connection = (anwendungRemote) PortableRemoteObject.narrow(ref, anwendungRemote.class);

connection.FunktionA();
```


----------



## FArt (10. Sep 2012)

Sorry, ich habe dir schon zwei mal gesagt, was du machen solltest, um sinnvolle Hilfe zu erhalten: beschreibe erst mal genau deine Infrastruktur und die Laufzeitumgebung. Wie die verschiednenen Teilnehmer zusammenhängen, was deine genauen Anforderungen dabei sind usw.

Bewege dich erst mal von Implementierungsdetails weg. Du bist schon längst auf einem Holzweg. Mache nicht einen Schritt zurück, sonder vier oder fünf.

Aus deiner JSP-Frage liest man schon wieder raus, dass hier ein JNDI Kontext erstellt wird (fehlerhaft) und dann versucht wird auf ein EJB2 (?) zuzugreifen (auch fehlerhaft).

Ohne genaue Informationen stelle ich jetzt mal den Support hier ein.

Soll sich SlaterB damit rumschlagen, der ist Moderator und muss somit moderater antworten ;-)


----------



## SlaterB (10. Sep 2012)

ich verweise nur auf neues Thema eröffnen, allerdings ist nun ja wieder das Thema das Themas fraglich,
da musst du schon dabei bleiben 
stell du dir doch vor es bleibt jetzt etwa so wie angegeben, ein JBoss-Server, und das Ziel ist ein anderes Java-Programm zu benachrichtigen,
auf welche Weise könnte der JBoss-Server selber eine Kommunikation aufmachen? die Gegenseite hilft dabei so gut es geht mit,
geht ein einfacher Socket noch?

Java Socket Programming Example
zum Austausch von String-Nachrichten völlig ausreichend


----------



## FArt (10. Sep 2012)

SlaterB hat gesagt.:


> auf welche Weise könnte der JBoss-Server selber eine Kommunikation aufmachen?


Muss er doch gar nicht. Laut TS erstellt der Server das Player-Objekt und ein neuer Client muss darauf zugreifen.

Die Frage ist: warum und wann erstellt der Server das Objekt (Player)? Und wie kann der Client das richtige Objekt erkennen? Oder gibt es nur eines? Oder hat es eigentlich der Client durch einen Call dafür gesorgt, dass der Player angelegt wird? Oder besteht tatsächlich der Bedarf nach einem Callback (Server benachrichtigt aktiv den Client)? Warum eigentlich? Ist hier nicht schon das Design fehlerhaft? Vermutlich...

Mit clientseitigen Serversockets wg. Callbacks zu hantieren ist suboptimal. Da gibt es zusammen mit einem JBoss auch bessere Lösungen.


----------



## erazor2106 (10. Sep 2012)

es tut mir leid wenn ich verwirrung bzw. missmut erzeugt habe. das war natürlich nicht meine absicht. dies entstand wenn schon aus meiner zeitnot und "hilflosigkeit" bei dieser thematik.

zuerst thematisiert hatte ich es hier: http://www.java-forum.org/allgemein...beim-manipulieren-videostreams-jsp-seite.html

da gab es aber keine antwort. Also nochmal kurz zum aufbau. vllt kann man das ganze viel einfacher handhaben.

ich habe einen server, dort liegen videos auf dem filesystem. auf diesem server soll ein vlc-videostream erzeugt werden. mache ich derzeit mit VLCJ. Das klappt auch ganz gut.

Nun bin ich ein Anwender welcher auf einer website, hier eine JSP-Seite einen Stream ansehen möchte. dort wähle ich den namen des videos auf einen button, eine neu jsp-seite wird geladen, es wird java-code ausgeführt welcher auf einem anderen server in einem JBoss läuft. 

auf dem video-server läuft ein javaprogramm welches vom jboss den befehl bekommt starte den stream. das geschieht mittels folgendem konstrukt:


```
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,	"org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES,         "org.jboss.naming:org.jnp.interfaces");
p.put(Context.PROVIDER_URL, 		"jnp://localhost:1099");
Context ctx = new InitialContext(p);
		 
Object ref = ctx.lookup("anwendung/remote");
anwendungRemote connection = (anwendungRemote) PortableRemoteObject.narrow(ref, anwendungRemote.class);

connection.FunktionA();
```

in dem java-programm in der Methode FunktionA steht unter anderem folgendes:


```
MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
 EmbeddedMediaPlayer mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
 mediaPlayer.playMedia(mediafile,options);
```

Soweit so gut. Aber wie kann der Anwender auf seiner website in der jsp seite diesen stream nun wieder stoppen, dort spulen, ...?
hierzu müsste 


```
mediaPlayer.stop();
```

ausgeführt werden. Aber wie komme ich von der website nun an mein Objekt mediaPlayer heran. daher dachte ich an RMI, weil ich mich mit dem jnp auch nicht so auskenne, aber es müsste theoretisch ja auch damit gehen, nehme ich an.

nun ist es auch so das ein anwender mehrere streams starten können soll und hin und her switchen können. hierzu übergebe ich eine eindeutige ID womit ich den richtigen Player wiederfinden könnte. wollte dazu eine Arraylist mit Mediaplayern anlegen und eine String-Arraylist mit den IDs.

Ist die Problematik etwas klarer geworden bzw. der Aufbau?

Im moment laufen der JBoss und das javaprogramm für den Videostream auf dem gleichen Server. Daher localhost. dies soll aber dann auch auf 2 Maschinen laufen.


----------



## FArt (11. Sep 2012)

So ein Posting als erstes Posting, und wir hätten viel Zeit und Mühe gespart.

Ich bin jetzt nicht der Webprofi, aber ich würde sagen der Ansatz ist falsch. Denn wie du schon sagtest, woher soll der Client verschiedene Informationen her haben.

Warum triggert der "Server" den "JBoss"? Client-Server Architekturen (gerade mit Webschnittstellen) sind in der Regel clientgetrieben, d.h. der Client löst eine Aktion gegenüber einem (oder auch mehreren) Servern aus.

In deinem Fall würde ich das so lösen: Client verbindet sich mit "Server" und wählt die zu spielende Datei aus. Z.B. über einen Redirect meldet sich danach der Client beim JBoss, und liefert alle relevangen Informationen mit. Im Lebenszyklus der Session auf dem Server lebt dein Mediaplayer. Du benötigst dann noch Remotezugriffsmöglichkeiten auf den Player (stop, pause, ffw, ...) und das war es schon.

Noch besser: der Client kommuniziert nur mit einem Server, der dann je nach Anfrage den Call entsprechend dispatcht. Dieser Server kann dann auch Authentifizierung und Authorisierung übernehmen, sonst hast du immer das Problem, dass dies in verteilten System geschehen muss. Das kann ein dritter Server sein, aber auch einer von den beiden anderen kann diese Aufgabe mit benutzen. Hauptsache die Infrastruktur schlägt sich nicht auf die Implementierung nieder, d.h. ob und wie du im Backend skalierst, sollte für das Desgin und die Implementierung irrelevant sein.


----------



## erazor2106 (11. Sep 2012)

ich habe die Sache nochmal überdacht und bin zu dem Schluss gekommen das Sockets ausreichen.

D.h. es läuft nun ein extra Javaprogramm welches den Streamingserver darstellt und die mediaPlayer-Instanzen verwaltet.

In der JSP baue ich über den JBoss eine Socketverbindung auf und schicke ihm kurze Strings mit den Befehlen drin. Das scheint jetzt einigermaßen stabil zu laufen :toll: :applaus: :toll:

Nochmal vielen Dank für eure Geduld und Hilfe


----------

