rmi und download von klassen

Status
Nicht offen für weitere Antworten.
I

igor99

Gast
hallo

ich habe eine kleine rmi-application programmiert und möchte, wenn irgendwie möglich, die gemeinsamen klassen im paket model nicht auf beiden seiten (server- und clientseite) extra ablegen bzw. verwalten. ich hätte sowohl einen ftp- als auch einen web-server zum ablegen von gemeinsamen klassen. meine frage ist: ist das überhaupt möglich? und wenn ja, könnte ich auch mit file-protokol soche dateien downloaden (achtung: server und client laufen auf unterschiedlichen systemen).

danke
 
G

Guest

Gast
Bleiglanz hat gesagt.:

vielen dank. ich habe diesen artikel schon gelesen, bin aber nicht schlauer geworden. ausserdem habe ich auch dies hier gelesen:

http://labs.cs.utt.ro/doc/java_tutor/rmi/running.html

ich benuzte tomcat , port 8080 und habe im verzeichnis webapps/root/ das verzeichnis export/classes angelegt, in dem das paket model mit den zugehörigen klassen abgelegt wurde. tomcat läuft und es kann wohl nicht schief gehen ...

auf der serverseite habe ich folgende policy.txt angelegt:

Code:
grant 
{
    permission java.net.SocketPermission "*:1024-65535", 		
        "connect,accept";
    permission java.net.SocketPermission "*:8080", "connect";
};

und server wird wie folgt gestartet (datei run_server.bat):
Code:
@echo off

REM CLASSPATH setzen
set CLASSPATH=.;lib\log4j.jar;lib\postgresql-8.0-313.jdbc3.jar

REM Server starten
java -Djava.rmi.server.codebase=http://localhost:8080/export/classes/ -Djava.security.policy=policy.txt server.Server

pause

auf der clientseite habe ich das paket model entfernt (ansonsten funktioniert es einwandfrei).

- ich starte rmiregistry: start rmiregistry
- ich starte server: run_server.bat

alles im butter. server läuft auf der ip-adresse 137.181.183.110

ich starte client:
Code:
java client.Client 137.181.183.110

nun bekomme ich meldung, dass die klasse aus dem paket model nicht gefunden wird.

was mach ich falsch?
 
G

Guest

Gast
Wirklich

auch den Abschnitt "Starting the Client"?

ja, auch diesen abschnitt habe ich gelesen. aber wenn du schon so fragst, denke ich, dass in diesem abschnitt etwas steht, was ich übersehen habe. stimmt das?

ich habe mittlerweile weiter probiert und habe noch logging von rmiregistry eingeschaltet. nun, habe ich immer am ende eine kommische meldung:

Code:
FEINER: RMI RenewClean-[137.181.183.110:1135]: class "java.rmi.server.UID" found
via codebase, defined by null

ich gebe hier noch die logg-messages an. vielleicht sieht man da etwas, was ich nicht gesehen habe.

Code:
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEIN: RMI RenewClean-[137.181.183.110:1135]: name = "java.rmi.dgc.Lease", codebas  
e = "http://localhost:8080/export/classes/"                                       
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEINER: RMI RenewClean-[137.181.183.110:1135]: (thread context class loader: sun.  
misc.Launcher$AppClassLoader@133056f)                                             
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEINER: RMI RenewClean-[137.181.183.110:1135]: class "java.rmi.dgc.Lease" found v  
ia codebase, defined by null                                                      
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEIN: RMI RenewClean-[137.181.183.110:1135]: name = "java.rmi.dgc.VMID", codebase  
 = "http://localhost:8080/export/classes/"                                        
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEINER: RMI RenewClean-[137.181.183.110:1135]: (thread context class loader: sun.  
misc.Launcher$AppClassLoader@133056f)                                             
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEINER: RMI RenewClean-[137.181.183.110:1135]: class "java.rmi.dgc.VMID" found vi  
a codebase, defined by null                                                       
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEIN: RMI RenewClean-[137.181.183.110:1135]: name = "[B", codebase = ""            
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEINER: RMI RenewClean-[137.181.183.110:1135]: (thread context class loader: sun.  
misc.Launcher$AppClassLoader@133056f)                                             
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEINER: RMI RenewClean-[137.181.183.110:1135]: class "[B" found via codebase, def  
ined by null                                                                      
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEIN: RMI RenewClean-[137.181.183.110:1135]: name = "java.rmi.server.UID", codeba  
se = "http://localhost:8080/export/classes/"                                      
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEINER: RMI RenewClean-[137.181.183.110:1135]: (thread context class loader: sun.  
misc.Launcher$AppClassLoader@133056f)                                             
02.02.2006 12:23:32 sun.rmi.server.LoaderHandler loadClass                        
FEINER: RMI RenewClean-[137.181.183.110:1135]: class "java.rmi.server.UID" found

was bedeutet das: found via codebase, defined by null
 
G

Guest

Gast
nein, habe ich nicht. und, was soll ich im sagen? das gleiche (bzw. fast das gleiche) wie dem server:
Code:
-Djava.rmi.server.codebase=http://137.181.183.110:8080/export/classes/
du meinst, der klassenlader sollte dann selbst nach den klassen suchen gehen?

vilen dank für den tipp. ich werde es morgen probieren.
 
G

Guest

Gast
nun, jetzt habe ich es probiert, funktioniert aber nicht.

ich habe jetzt aber eine einfache, grundsätzlihce frage: wie funktioniert dynamisches downloaden von klassen in java?

dazu habe ich folgendes beispiel erstellt: klasse demo.Punkt und klasse Main.

klasse demo.Punkt:
Code:
package demo;

public class Punkt
{
    private int x;
    private int y;

    public Punkt(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    // set und get methoden ...

 
    public String toString()
    {
        return "x = " + x + ", y = " + y;
    }

}

klasse Main:
Code:
import java.rmi.RMISecurityManager;

import demo.Punkt;

public class Main
{
    public static void main(String[] args)
    {     
        if (System.getSecurityManager() == null)
        {
            System.setSecurityManager(new RMISecurityManager());
        }

        Punkt p = new Punkt(10, 20);

        System.out.println(p);
    }
}

habe die klasse demo.Punkt (bzw. das verzeichnis demo) auf dem webserver <ROOT>/export/classes/ abgelegt, policy-datei auf der clientseite definiert und probiert, die klasse Main auszuführen:


Code:
java -Djava.rmi.codebase=http://server:8080/export/classes/ -Djava.security.policy=policy.txt Main

meldung:
Code:
Exception in thread "main" java.lang.NoClassDefFoundError: demo/Punkt

der nächste versuch: paket bzw. verzeichnis demo local im verzeichnis c:\temp abgelegt und den aufruf wie folgt gemacht:
Code:
java -Djava.rmi.codebase=file:/C:\Temp\  -Djava.security.policy=policy.txt Main

und die gleiche fehlermeldung.

nun, wie macht man das? wenn ich mit diesem einfachen beispiel das nicht fertig bringe, dann habe ich wohl ein verständnisproblem, oder was? muss ich da noch mit klassenloader spielen bzw. etwas überschreiben? denn, ich habe gelesen, dass codebase eigentlich nichts anderes als ein "globaler" CLASSPATH ist? wie bringe ich den klassenloader so weit, dass er im codebase sucht?

danke für jeden tipp.
 
G

Guest

Gast
:D meine natürlich

Code:
-Djava.rmi.server.codebase ...
 
I

igor99

Gast
nun habe ich endlich die Klasse demo.Punkt von meinem Web-Server downloaden können:

Code:
public class Main
{
    public static void main(String[] args)
    {
        try
        {
            URL url = new URL("http://192.168.1.33:8080/export/classes/");
            URL[] urls = { url };
            URLClassLoader loader = new URLClassLoader(urls);

            // Klasse 'demo.Punkt' wird geladen
            Class<?> cls = Class.forName("demo.Punkt", true, loader);

            if (cls != null)
            {
                // Argumentenliste (int, int)
                Class[] argClass = new Class[] { int.class, int.class };
                // Konstruktor erzeugen
                Constructor<?> c = cls.getConstructor(argClass);
                // Eine Instanz erzeugen
                Object obj = c.newInstance(12, 18);
                // Ausgabe (toString der Klasse 'demo.Punkt')
                System.out.println(obj);

                // Methoden 'setX' und 'setY' holen
                Method setX = cls.getMethod("setX", int.class);
                Method setY = cls.getMethod("setY", int.class);

                // Falls vorhanden, aufrufen
                if (setX != null && setY != null)
                {
                    setX.invoke(obj, 52);
                    setY.invoke(obj, 62);
                }

                // Ausgabe (toString der Klasse 'demo.Punkt')
                System.out.println(obj);
            }
        }
        catch (Exception e1)
        {
            e1.printStackTrace();
        }
    }
}

macht man das etwa so? oder, kann man einfacher / eleganter / besser machen?
 
I

igor99

Gast
habe ein interessantes artikel zum dynamischen downloaden von klassen gefunden:

http://www.eli.sdsu.edu/courses/spring99/cs696/notes/ddc/ddc.html

das artikel ist zwar relativ alt, sollte aber immer noch grösstenteils "giltig" sein. leider, ist meine hoffunung, schlauer zu werden, nicht in erfüllung gegangen. meine frage bleibt weiter: wozu dient codebase???

ich habe mit einem einfachen beispiel (unabhängig von RMI) herausfinden probiert, wie das dynamische laden von klassen funktioniert. dazu habe ich folgende klassen definiert:

Code:
package hsw.fhw.calc;

public abstract class Calculator
{
    public abstract double add(double a, double b);
    public abstract double sub(double a, double b);
    public abstract double mul(double a, double b);
    public abstract double div(double a, double b);
    public abstract double getMax(double ... array);
    public abstract double getMin(double ... array);
}

Code:
package hsw.fhw.calc.model;

import java.util.Arrays;

import hsw.fhw.calc.Calculator;

public class CalculatorImpl extends Calculator
{

    @Override
    public double add(double a, double b)
    {
        Printer.print("Addition von " + a + " und " + b + ":");
        return a + b;
    }

    @Override
    public double sub(double a, double b)
    {
        Printer.print("Subtrachtion von " + a + " und " + b + ":");
        return a-b;
    }

    @Override
    public double mul(double a, double b)
    {
        Printer.print("Multiplikation von " + a + " und " + b + ":");
        return a*b;
    }

    @Override
    public double div(double a, double b)
    {
        Printer.print("Division von " + a + " und " + b + ":");
        return a/b;
    }

    @Override
    public double getMax(double... array)
    {
        Printer.print("Maximum:");
        Arrays.sort(array);
        return array[array.length-1];
    }

    @Override
    public double getMin(double... array)
    {
        Printer.print("Minimum:");
        Arrays.sort(array);
        return array[0];
    }
   
}

Code:
package hsw.fhw.calc.model;

public class Printer
{
    public static void print(String msg)
    {
        System.out.println(msg);
    }
}

Code:
package hsw.fhw.calc.test;

import hsw.fhw.calc.Calculator;

import java.net.URL;
import java.net.URLClassLoader;

public class Main
{
    public static void main(String[] args)
    {       
        try
        {
            URL url = new URL("http://192.168.1.33:8080/export/classes/");
            URL[] urls = { url };
            URLClassLoader loader = new URLClassLoader(urls);

            // Klasse 'hsw.fhw.calc.model.CalculatorImpl' wird geladen
            Class<?> cls = Class.forName("hsw.fhw.calc.model.CalculatorImpl", true, loader);

            if (cls != null)
            {
                Calculator calc = (Calculator)cls.newInstance();
                
                double a = 2.5;
                double b = 2;
                
                double summe = calc.add(a, b);
                double differenz = calc.sub(a, b);
                double produkt = calc.mul(a, b);
                double quotient = calc.div(a, b);
                
                System.out.println("Summe:    " + summe);
                System.out.println("Differnz: " + differenz);
                System.out.println("Produkt:  " + produkt);
                System.out.println("Quotient: " + quotient);                            
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }        
    }

}

auf der client-seite befindet sich nur die klasse Main und das interface Calculator. das paket model (mit CalculatorImpl und Printer) befindet sich auf dem web-server im verzeichnis <root>/export/classes. das ganze programm wird wei folgt gestartet:

Code:
java hsw.fhw.calc.test.Main

und, die ausführung funktioniert. dadurch, dass ich das interface Calculator auf der client-seite habe, kann ich das casten von Object in Calculator realisieren und damit alle methoden direkt (ohne reflection-gebrauch) einsetzten.

so weit, so gut. aber, zurück zu codebase. ich gehe davon aus, dass man codebase auch gebrauchen kann. nun wie?

ich habe jetzt die klasse Printer in das verzeichnis <root>/public auf dem web-server verschoben, mit dem ziel, diese lokation mit codebase anzugeben. der aufruf sah wie folgt aus:

Code:
java -Djava.rmi.server.codebase=http://192.168.1.33:8080/public/ hsw.fhz.calc.test.Main

ergebnis: klasse Printer kann nicht gefunden werden.

der nächste versuch: ich benutze noch useCodebaseOnly=true

Code:
java -Djava.rmi.server.useCodebaseOnly=true -Djava.rmi.server.codebase=http://192.168.1.33:8080/public/ hsw.fhz.calc.test.Main

ergebnis: klasse Printer kann nicht gefunden werden.

schlussfolgerung: mein versuch ist gescheitert!!!

im nächsten schritt habe ich die lokation der klasse Printer im code direkt angegeben:


Code:
URL[] urls = { new URL("http://192.168.1.33:8080/export/classes/"), new URL("http://192.168.1.33:8080/public/") };
            URLClassLoader loader = new URLClassLoader(urls);

das programm wird wie folgt aufgerufen:

Code:
java hsw.fhw.calc.test.Main

ergebnis: es funktioniert.

obwohl ich klasse Printer nicht explizit lade, wird das laden dynamisch realisiert, sobald die klasse benötigt wird.

auf meine frage, wozu codebase dient, habe ich keine antwort gefunden. kann mir jemand aus meinem albtraum helfen?
 
G

Guest

Gast
Müsste eigentlich funktionieren. Mit codebase sollte, nach meinem bescheidenen Wissen, der URLClassLoader automatisch erzeugt und zum Laden von Klassen von der angegebenen URL eingesetzt werden. So etwa wie mit SecurityManger, der von der Commandozeile erzeugt wird, wobei ihm die Policy-Datei mitgegeben wird.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Datei Download vom Server Netzwerkprogrammierung 8
P Jenkins Login per Java Download Manager Netzwerkprogrammierung 15
T Download überprüfung... Netzwerkprogrammierung 9
S HTTP Download von Google-URL mit Parametern Netzwerkprogrammierung 1
S download PDF Netzwerkprogrammierung 2
V Datei Download Fenster Netzwerkprogrammierung 9
R Apache HttpClient File Download? Netzwerkprogrammierung 3
K HTTP Eigener Http Response für Datei-Download Netzwerkprogrammierung 4
F HTTP HTTP-Download: Dateien in einem Verzeichnis ermitteln Netzwerkprogrammierung 8
T Download Programm - Download endet vorzeitig (bricht ab) Netzwerkprogrammierung 11
D HTTP Download - Skript im Weg Netzwerkprogrammierung 4
C Fehler bei PDF-Download Netzwerkprogrammierung 5
B FTP *.class download Netzwerkprogrammierung 2
eLogic Download eines Links Netzwerkprogrammierung 2
Dit_ FTP Download | "PassiveMode"-Socket öffnen Netzwerkprogrammierung 4
B HTTP Audio-Download per Direktlink Netzwerkprogrammierung 4
eLogic Download aus Internet Netzwerkprogrammierung 18
M Download von Webseite Netzwerkprogrammierung 4
A RMI Fortschritt bei Up/Download anzeigen Netzwerkprogrammierung 6
T Up- und Download mit https Netzwerkprogrammierung 14
A HTTP Download einer Datei mit "Statistiken" Netzwerkprogrammierung 2
B HTTP PDF Servlet download vom Server zum Client Netzwerkprogrammierung 3
Ollek Download einer Datei durch SFTP mit Java Netzwerkprogrammierung 12
P Name der Download-Datei ermitteln Netzwerkprogrammierung 8
Schandro Download von FTP Server mit maximal Geschwindigkeit Netzwerkprogrammierung 2
P HTTP Problem beim Download von einer Datei Netzwerkprogrammierung 4
ModellbahnerTT Download progress Netzwerkprogrammierung 4
D FTP Download Netzwerkprogrammierung 5
N Video download Netzwerkprogrammierung 4
hdi Webseite auf Download-Links prüfen und Download starten? Netzwerkprogrammierung 7
C Download-Fortschritt wird falsch angezeigt. Netzwerkprogrammierung 2
E Größe der Datei vor Download ermitteln Netzwerkprogrammierung 3
B FTP - Verzeichnis Download Netzwerkprogrammierung 3
A Download-Client Netzwerkprogrammierung 6
A download programm Netzwerkprogrammierung 2
K http-download Netzwerkprogrammierung 12
2 Redirect, Login und Download bei Rapidshare.com Netzwerkprogrammierung 4
L file upload / download über http Netzwerkprogrammierung 5
M Download über URL Netzwerkprogrammierung 7
B knacken bei download von mp3 datei Netzwerkprogrammierung 2
N Download HTTP .php-Seite mit Anmeldung Netzwerkprogrammierung 5
M Download-Manager in System/Browser einbinden Netzwerkprogrammierung 11
G file download über https mit p12 Zertifikat Netzwerkprogrammierung 4
P Download funtioniert nicht richtig. Netzwerkprogrammierung 2
M FTP Verbindung und download von *.txt Netzwerkprogrammierung 6
F GSON wenn das Json verschiedene Klassen enthält Netzwerkprogrammierung 1
S Server - Mehrere Klassen sollen Daten senden und empfangen Netzwerkprogrammierung 25
A Probleme beim Klassen-Import von sun.misc. ... Netzwerkprogrammierung 19
G Klassen über Netzwerk kommunizieren lassen Netzwerkprogrammierung 6
D Mit wsimport erstellte Klassen ohne WSDL nutzen Netzwerkprogrammierung 4
M Multiplayerspiel programmieren... welche Klassen sind geeignet? Netzwerkprogrammierung 10
G Klassen über JMX per URLClassloader laden? Netzwerkprogrammierung 2
M Bestimmte Klassen für Netzwerkchecks gesucht Netzwerkprogrammierung 11
R wsimport erzeugt klassen -> wie nun weiter? Netzwerkprogrammierung 2
G CORBA Klassen werden nicht erkannt. Netzwerkprogrammierung 7

Ähnliche Java Themen


Oben