Probleme bei Verbindung mit RMI

Boemm

Grünschnabel
Hallo,

ich entwickle gerade eine kleine Anwendung mit J2EE, habe jedoch Probleme bei Remoteverbindungen (und auch lokal) zum RMI-Server von jBoss.

Irgendwie komme ich nicht weiter und werde auch aus Tutorials und Dokus nicht schlauer, weshalb ich hier mal frage, ob mir wer Hilfestellung leisten kann ...

Als erstes erstmal mein Plan:

Ich möchte auf Basis von MBeans einen (oder eigentlich zwei) Dienste schreiben, welche es ermöglichen, J2EE-Komponenten automatisch von einem J2EE-Server zu einem anderen J2EE-Server zu übertragen und auf dem Ziel-Server auch automatisch deployen zu lassen.

Dazu habe ich mir erstmal eine MBean geschrieben, welche "lokal" ein oder mehrere Verzeichnisse überwacht, um neue oder aktualisierte Komponenten zu finden und zu cachen und diese zur Übertragung bereit zu stellen.

Nun wollte ich erstmal von einem einfachen Java-Programm, später dann von einer zweiten MBean von Remote auf diese MBean zugreifen, um Informationen von dieser Bean abzufragen und gegebenenfalls auch Komponenten anzufordern ...

Erstmal soweit, allerdings trete ich gerade auf der Stelle, weil es mir nicht gelingen will, eine Verbindung zum RMI-Server des JBoss herzustellen.

Der JBoss (4.0.4) ist gestartet und in der JMX-Console kriege ich auch meine Bean und die JBoss-Beans angezeigt, versuche ich nun aber mit:

Code:
        Hashtable<String, String> hashtable = new Hashtable<String, String>(2);
        hashtable.put (Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.rmi.registry.RegistryContextFactory");
        hashtable.put (Context.PROVIDER_URL,
                       "rmi://localhost:1098");
        InitialContext ictx = new InitialContext(hashtable);
        RMIAdaptor server = (RMIAdaptor) ictx.lookup("jmx/invoker/RMIAdaptor");

auf den Server zuzugreifen, bekomme ich folgende Exception:

Exception in thread "main" javax.naming.CommunicationException [Root exception is java.rmi.NoSuchObjectException: no such object in table]
at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:97)
at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:103)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at prototyp.livedeployment.clients.JMXClient.main(JMXClient.java:34)
Caused by: java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:343)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:93)
... 3 more

Kann mir vielleicht irgendwer sagen, was ich anders machen muss, um eine Verbindung hinzubekommen?

Mein System ist wie gesagt ein JBoss 4.0.4, Java 1.5, SuSE 10.1.

Eine weitere Frage noch:
Ist für das beschriebene Problem der Lösungsansatz mit Verbindung über RMI generell günstig, oder gibt es da bessere Ansätze ... ich weiss beispielsweise gar nicht so richtig, wie das mit Authentifizierung und so was ist, am liebsten möchte ich, dass alles komplett ohne User/Passwort abgehandelt werden soll.
Ausserdem würde mich interessieren, ob solch eine Lösung abgesehen von Deploymentdescriptoren um die Beans in der Server zu kriegen, generell Hersteller- (bzw. Applikation-Server) -unabhängig implementierbar ist?

Ich habe beim JBoss schon mitbekommen, dass es viele Erweiterungen gibt, welche das Entwickeln spezieller "JBoss-Komponenten" wesentlich vereinfachen, sie damit jedoch inkompatibel mit anderen J2EE-konformen Servern machen.

Viele viele Fragen ... wäre super, wenn sich jemand die zeit nehmen würde, ein paar (oder alle ;-) ) davon zu beantworten.

Vielen Dank!
Steffen
 
Hallo!

Also prinzipiell würde ich mal sagen, dass du dir dazu kein eigenes Deployment System schreiben musst...
ist doch schon alles da ;-)
Du kannst den URL Deployment Scanner so konfigurieren, dass er "beliebige" URLs nach deployment-units überprüft:
E:\jboss\4.0.5GA\jboss-4.0.5.GA\server\default\conf\jboss-service.xml
->
XML:
   <!-- ==================================================================== -->
   <!-- Deployment Scanning                                                  -->
   <!-- ==================================================================== -->

   <!-- An mbean for hot deployment/undeployment of archives.
   -->
   <mbean code="org.jboss.deployment.scanner.URLDeploymentScanner"
      name="jboss.deployment:type=DeploymentScanner,flavor=URL">
...

  <!-- URLs are comma separated and resolve relative to the server home URL
         unless the given path is absolute. If the URL ends in "/" it is
         considered a collection and scanned, otherwise it is simply deployed;
         this follows RFC2518 convention and allows discrimination between
         collections and directories that are simply unpacked archives.

         URLs may be local (file:) or remote (http:). Scanning is supported
         for remote URLs but unpacked deployment units are not.

         Example URLs:
            deploy/
                 scans ${jboss.server.url}/deploy/, which is local or remote
                 depending on the URL used to boot the server
            ${jboss.server.home}/deploy/
                 scans ${jboss.server.home)/deploy, which is always local
            file:/var/opt/myapp.ear
                 deploy myapp.ear from a local location
            file:/var/opt/apps/
                 scans the specified directory
            http://www.test.com/netboot/myapp.ear
                 deploys myapp.ear from a remote location
            http://www.test.com/netboot/apps/
                 scans the specified WebDAV location
       -->
      <attribute name="URLs">
         deploy/
      </attribute>

Eine weitere Alternative wäre auch deine JBoss-Instanzen in einem Cluster Laufen zu lassen bzw. über den Farm-Service
deployen zu lassen.
http://wiki.jboss.org/wiki/Wiki.jsp?page=ClusteringFAQ

...

Wenn du JBoss per JMX Fernsteuern willst:
(Du mußt ein entsprechendes jnid.properties) File im Classpath haben:
Code:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099

Java:
/**
 * 
 */
package de.tutorials;

import java.util.concurrent.TimeUnit;

import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.naming.InitialContext;

/**
 * @author Tom
 * 
 */
public class JBossRMIConnectorExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        InitialContext initialContext = new InitialContext();

        MBeanServerConnection mBeanServerConnection = (MBeanServerConnection) initialContext
                .lookup("jmx/invoker/RMIAdaptor");
        ObjectName objectName = new ObjectName("jboss.system:type=Server");
        MBeanInfo mBeanInfo = mBeanServerConnection.getMBeanInfo(objectName);
        // Alle Operationen dieses MBeans anzeigen
        MBeanOperationInfo[] mBeanOperations = mBeanInfo.getOperations();
        for (int i = 0; i < mBeanOperations.length; i++) {
            MBeanOperationInfo info = mBeanOperations[i];
            System.out.println(info.getName());
        }
        
        TimeUnit.SECONDS.sleep(5);

        // JBoss herunterfahren...
        mBeanServerConnection.invoke(
                objectName,
                "shutdown",
                new Object[0],
                new String[0]);

        initialContext.close();
    }

}

(Ausprobiert mit JBoss 4.0.5GA)

Gruß Tom
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

danke erstmal für deine schnelle Antwort.
Ich habe deinen Code gleich mal getestet und siehe da, gleich ging es ...

Die Sache mit dem eigenen Deployment-System basiert weniger daraus, ein direkt praktisch nutzbares System zu entwickeln, sondern dieses Thema ist zum Teil Inhalt einer Diplomarbeit ... daher setze ich mich momentan ausgiebiger damit auseinander.

In Sachen Deployment-Scanner ist man ja auf die (Url-)Möglichkeiten angewiesen, auf die einen die Implementierung einschränkt ... das heisst ich müsste auf jeden Fall immer für Remote-Zugriff die entsprechenden Deploy-Verzeichnisse auf dem Server freigeben ... und könnte lediglich einen Server als Quelle benutzen ...
Ziel ist es aber (zumindest in meinem Kopf), die ganze Verteilung von Komponenten möglichst dynamisch zu halten ...
Also ich packe bei irgendeinem AS etwas in ein überwachtes Verzeichniss und dieser verteilt es an alle AS in seiner Umgebung, welche es anfordern.

Von diesen jetzt aktualisierten Servern sollen sich dann auch wieder andere Server bedienen können ... etc. ... also so in Richtung Peer2Peer ...

Dazu nötig ist eine integrierte Versionsverwaltung und evtl. auch eine Verwaltung für Abhängigkeiten zwischen einzelnen Komponenten.

Die fehlende Versionsverwaltung und auch die Begrenzung auf AS eines Typs (also zb. nur JBoss) lässt auch das Clustering an dieser Stelle ausscheiden ...
Ich habe halt immer noch die Idee, ein recht einfach gehaltenes System Serverunabhängig umzusetzen um auch Komponenten zwischen verschiedenen Servern (Herstellern) austauschen zu können ...

--> Utopie!? :)

Ich schreibe erstmal weiter ...

Steffen
 
Hi,

ich habe da noch eine Frage bezüglich der Übertragung von Dateien zwischen zwei MBeans ...

Ich stehe jetzt an dem Punkt, von einer MBean eine Datei zur anderen übertragen zu wollen ... allerdings ist es ja bei großen Dateien recht unperformant (denke ich) diese erst komplett einzulesen und dann als ganzes Objekt zur anderen Bean (als Rückgabewert einer Methode) zurück zu geben.

Gibt es da irgendwelche Möglichkeiten, das über einen InputStream oder so zu machen!?

Oder welche Methoden kann man für sowas sonst benutzen?
Muss ich dafür irgendwelche Sockets bemühen oder so?

Ich versuche mich da grade etwas zu belesen drüber, aber das ist wieder so ein sehr spezieller Fall ... wo man schwer was zu findet ...

Gruß
Steffen
 
Hallo!

Die Sache mit dem eigenen Deployment-System basiert weniger daraus, ein direkt praktisch nutzbares System zu entwickeln, sondern dieses Thema ist zum Teil Inhalt einer Diplomarbeit ... daher setze ich mich momentan ausgiebiger damit auseinander.
... wieso willst du unbedingt etwas machen was "praktisch" nicht benutzt wird...?

In Sachen Deployment-Scanner ist man ja auf die (Url-)Möglichkeiten angewiesen, auf die einen die Implementierung einschränkt ... das heisst ich müsste auf jeden Fall immer für Remote-Zugriff die entsprechenden Deploy-Verzeichnisse auf dem Server freigeben ... und könnte lediglich einen Server als Quelle benutzen ...
Also, wie man in den Kommentaren sehen kann, kann man bei diesem URLDeploymentScanner
verschiedene URLs angeben wo der Scanner in regelmäßigen Abständen nach neuen Deployment-Units suchen soll. Das file:// protocol ist dabei ja nur eine Möglichkeit... auch das Deployment von einem HTTP / Webdav Verzeichnis ist möglich ;-)
Auf dem Server musst du kein Verzeichnis freigeben... wenn der URLDeploymentScanner in den Konfigurierten Locations eine neue Deployment-Unit findet, zieht er sich diese automatisch und deployed sie dann lokal.

Weiterhin gibt es über den Farmservice bzw. das deployment in einen Cluster schon ausreichende Verteilungsdienste (in homogenen Systemlandschaften).

Die fehlende Versionsverwaltung und auch die Begrenzung auf AS eines Typs (also zb. nur JBoss) lässt auch das Clustering an dieser Stelle ausscheiden ...
Die Frage ist ob das wirklich notwendig ist. In der Regel versucht man ja die Systemlandschaft weitestgehend homogen zu halten um den Verwaltungs- und insbesondere den Wartungsaufwand möglichst gering zu halten.

Darüber hinaus gibt es auch schon Open Source Projekte die sich dieser Deployment-Problematik angenommen haben und über gewisse Container-Abstraktionen (teilweise) unabhängiges Deployment bieten. (http://cargo.codehaus.org/)

Ich habe halt immer noch die Idee, ein recht einfach gehaltenes System Serverunabhängig umzusetzen um auch Komponenten zwischen verschiedenen Servern (Herstellern) austauschen zu können ...
Ich hatte auch mal das Vergnügen eine klassische J2EE Anwendung auf mehreren Applikationsservern deployen zu müssen... durch die vielen ApplikationsServer spezifischen Konfigurationsdateien ist das wirklich ein Alptraum.

Gibt es da irgendwelche Möglichkeiten, das über einen InputStream oder so zu machen!?
Szenario:
Server A hat lokal DeplyomentUnit.jar vorliegen. Diese soll zu Server B bewegt werden.

Ich würde hier einen Mechanismus bauen der das DeploymentUnit.jar über HTTP/FTP verfügbar macht. Anschließend würde ich dem Server B nur noch mitteilen, wo er diese DeploymentUnit findet und diesen dazu veranlassen die Datei downzuloaden. Fertig.

Gruß Tom
 

Neue Beiträge

Zurück