Java RMI - java.lang.ClassNotFoundException:

0

Cześć, próbuję odpalić dwie aplikacje - serwer i klienta. Aplikacje te mają komunikować się przez RMI.

Zancznę od kodów:

com.example.server.Server.java

package com.example.server;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class Server implements TextService {

    private static final String NAME = "rmi-server";

    public static void main(String[] args) {
        
        try {

            TextService service = new Server();
            TextService stub = (TextService) UnicastRemoteObject.exportObject(service, 0);
            Registry registry = LocateRegistry.getRegistry();
            registry.rebind(Server.NAME, stub);

            System.out.println("Server started..");

        } catch (Exception e) {
            System.err.println("Server side exception:");
            e.printStackTrace();
        }
    }

    public String getUpperCase(String text) { return text.toUpperCase(); }
    public String getLowerCase(String text) { return text.toLowerCase(); }
    public String trim(String text) { return text.trim(); }
}

com.example.server.TextService.java

package com.example.server;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface TextService extends Remote {
    String getUpperCase(String text) throws RemoteException;
    String getLowerCase(String text) throws RemoteException;
    String trim(String text) throws RemoteException;
}

server.policy

grant codeBase "file:/g/java-rmi/-" {
    permission java.security.AllPermission;
};

Kompilacja:

javac com/example/server/*.java

Zapokowanie do jar:

jar cfe server.jar com.example.server.Server com/example/server/Server.class com/example/server/TextService.class

Uruchomienie rmiregistry:

start rmiregistry 1099 

Próba uruchomienia:

java -jar server.jar -Djava.rmi.server.codebase=file:/g/java-rmi/server.jar -Djava.rmi.server.hostname=rmi.localhost -Djava.security.policy=/g/java-rmi/server.policy

Powoduje:

Server side exception:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
        java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
        java.lang.ClassNotFoundException: com.example.server.TextService
        at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:420)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(TCPTransport.java:683)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
        at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
        at sun.rmi.server.UnicastRef.invoke(Unknown Source)
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
        at com.example.server.Server.main(Server.java:22)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
        java.lang.ClassNotFoundException: com.example.server.TextService
        at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
        at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:410)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(TCPTransport.java:683)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.example.server.TextService
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.rmi.server.LoaderHandler$Loader.loadClass(LoaderHandler.java:1207)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at sun.rmi.server.LoaderHandler.loadClassForName(LoaderHandler.java:1221)
        at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:731)
        at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:674)
        at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:611)
        at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
        at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
        at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:255)
        at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1559)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
        ... 15 more

Oczywiście sprawdzałem i plik server.jar zawiera plik TextService.class w ścieżce pakietu.

0

Czy na forum zamieściłeś kod, który spowodował błąd? Błąd jest w wierszu 22, a wiersz 22 wygląda tak:
} catch (Exception e) {

Pytam, bo u mnie program działa, można go uruchamiać na wiele sposobów:

java -jar server.jar
java -jar server.jar -Djava.security.policy=all.policy
java -jar server.jar -Djava.rmi.server.hostname=rmi.localhost -Djava.security.policy=all.policy
java -jar server.jar -Djava.rmi.server.codebase=file:/g/java-rmi/server.jar -Djava.rmi.server.hostname=rmi.localhost -Djava.security.policy=all.policy
...

Mój plik *all.policy* trochę się różni od Twojego:

grant codebase "file:."{
permission java.security.AllPermission;
};

0

Coś kręcisz, w wierszu 22 nie może być takiego błędu:

java.lang.ClassNotFoundException: com.example.server.TextService
.
Plik all.policy mam tam gdzie jest jar, ale to nie ma znaczenia: polecenie java -jar server.jar też uruchamia program.

0

Obecnie klasa Server wygląda tak:

package com.example.server;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class Server implements TextService {

    public static void main(String[] args) {

        try {

            TextService service = new Server();
            TextService stub = (TextService) UnicastRemoteObject.exportObject(service, 0);
            Registry registry = LocateRegistry.getRegistry();
            registry.rebind("rmi-server", stub);

            System.out.println("Server started..");

        } catch (Exception e) {
            System.err.println("Server side exception:");
            e.printStackTrace();
        }
    }

    public String getUpperCase(String text) { return text.toUpperCase(); }
    public String getLowerCase(String text) { return text.toLowerCase(); }
    public String trim(String text) { return text.trim(); }
}

Stack Trace:

Server side exception:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
	java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: com.example.server.TextService
	at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:420)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268)
	at sun.rmi.transport.Transport$1.run(Transport.java:200)
	at sun.rmi.transport.Transport$1.run(Transport.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(TCPTransport.java:683)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
	at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
	at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
	at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:379)
	at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
	at com.example.server.Server.main(Server.java:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: com.example.server.TextService
	at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:410)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268)
	at sun.rmi.transport.Transport$1.run(Transport.java:200)
	at sun.rmi.transport.Transport$1.run(Transport.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(TCPTransport.java:683)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.example.server.TextService
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.rmi.server.LoaderHandler$Loader.loadClass(LoaderHandler.java:1207)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at sun.rmi.server.LoaderHandler.loadClassForName(LoaderHandler.java:1221)
	at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:731)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:674)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:611)
	at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
	at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
	at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:255)
	at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1559)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
	... 15 more

Wyjątek wskazuje na linię 16:

registry.rebind("rmi-server", stub);
0

A w jakim folderze wpisujesz polecenie start rmiregistry 1099? powinieneś w folderze z plikiem server.jar?

0

rmiregistry uruchamiam z poziomu folderu gdzie znajduje się plik server.jar. Próbowałem również uruchamiać rmiregistry z flagami:

start rmiregistry 1099 -J-Djava.rmi.server.useCodebaseOnly=false -J-Djava.rmi.server.codebase=file:/g/java-rmi/server.jar

ale niczego to nie zmienia.

Po dodaniu w klasie Server linijek (na samym początku main):

        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }

Dostaję wyjątek:

Server side exception:
java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkConnect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at java.net.Socket.<init>(Unknown Source)
        at java.net.Socket.<init>(Unknown Source)
        at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)
        at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
        at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
        at sun.rmi.server.UnicastRef.newCall(Unknown Source)
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
        at com.example.server.Server.main(Server.java:20)

Dodatkowo próbowałem też zmienić plik java.policy w JDK na:

// Standard extensions get all permissions by default

grant codeBase "file:${{java.ext.dirs}}/*" {
        permission java.security.AllPermission;
};

// default permissions granted to all domains

grant {
	permission java.security.AllPermission;
};

ale również nie przyniosło to oczekiwanych rezultatów.

0

@bogdans odpaliłem kody na wirtualnej maszynie i wszystko elegancko działa. Na 99% mam coś pomieszane z wersjami javy albo przez te wszystkie próby zrobił się mały bałagan. Dziękuję za pomoc i zainteresowanie :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1