Why the Class cannot be seen in its source file Java

◇◆丶佛笑我妖孽 提交于 2019-12-12 17:15:49

问题


Whatever I do I cannot create new instance of class Serwer. Please help, somehow constructor is invisible. I don't understand why is it so. The constructor is public and everything is coded in one file.

I just get this:

java.rmi.StubNotFoundException: Stub class not found: Serwer_Stub; nested exception is: 
java.lang.ClassNotFoundException: Serwer_Stub
at sun.rmi.server.Util.createStub(Unknown Source)
at sun.rmi.server.Util.createProxy(Unknown Source)
at sun.rmi.server.UnicastServerRef.exportObject(Unknown Source)
at java.rmi.server.UnicastRemoteObject.exportObject(Unknown Source)
at java.rmi.server.UnicastRemoteObject.exportObject(Unknown Source)
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.exportObject(Unknown Source)
at javax.rmi.PortableRemoteObject.exportObject(Unknown Source)
at javax.rmi.PortableRemoteObject.<init>(Unknown Source)
at Serwer.<init>(Serwer.java:13)
at Serwer.main(Serwer.java:35)
Caused by: java.lang.ClassNotFoundException: Serwer_Stub
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
... 10 more

CLASS

import java.rmi.RemoteException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.rmi.PortableRemoteObject;

public class Serwer extends PortableRemoteObject implements MyInterface {



public Serwer() throws RemoteException {
    super();
    try{
        Serwer ref =
                new Serwer();
        Context ctx = new InitialContext();
        ctx.rebind("myinterfaceimplementacja", ref);

    }catch(Exception e){e.printStackTrace();}
}

@Override
public String echo(String napis) throws RemoteException {
    return "echo" + napis;
}

@Override
public int dodaj(int wrt1, int wrt2) throws RemoteException {
    return wrt1 + wrt2;
}

public static void main(String[] args){
    try {
        new Serwer();
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

回答1:


There are two bugs in your code. The first one is the obvious infinite recursion in the Serwer constructor, where you are calling the constructor again and again. This can be fixed by removing that line from the constructor and replace ref with this on the following line:

public class Serwer extends PortableRemoteObject implements MyInterface {

    public Serwer() throws RemoteException {
        super();
    }

    @Override
    public String echo(String napis) throws RemoteException {
        return "echo" + napis;
    }

    @Override
    public int dodaj(int wrt1, int wrt2) throws RemoteException {
        return wrt1 + wrt2;
    }

    public static void main(String[] args){
        try {
            Serwer ref = new Serwer();
            // Context ctx = new InitialContext();
            // ctx.rebind("myinterfaceimplementacja", ref);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

However, this bug is unrelated to the ClassNotFoundException you got. What causes the exception is that you use PortableRemoteObject as the base class of your remote implementation. Normally in Java RMI, the stub class (Serwer_Stub) is generated automatically when you export (instantiate) the remote object. But the PortableRemoteObject is an exception to this case. You can solve this two ways:

  1. As Kumar suggested, replace the javax.rmi.PortableRemoteObject with java.rmi.server.UnicastRemoteObject. This way the stub object gets created automatically, and the above code will run happily, I tested it.

    public class Serwer extends UnicastRemoteObject implements MyInterface {
    
  2. If for some reason you must use PortableRemoteObject, then you should generate the stub class manually by using the RMI compiler (rmic) tool that are shipped with the JDK.

    First, you compile the Serwer class:

    javac Serwer.java
    

    This will generate the Serwer.class file. Then you call the RMIC tool to generate the stub class:

    rmic Serwer
    

    This will generate the Serwer_Stub.class file. Now you can run your server:

    java Serwer
    

    I also tested this, it starts without any exceptions.

Note that there is another bug in your code with the usage of the Java Naming, causing another exception (NoInitialContextException), but that is also unrelated with the question, that's why I commented it out in the code above. Since I'm no expert in javax.naming, it's up to someone else to help you with that.

Maybe you intended to use RMI registry instead of using Naming by mistake. RMI registry is the native way to bind and lookup remote objects in Java RMI. In this case you should replace the

Context ctx = new InitialContext();
ctx.rebind("myinterfaceimplementacja", ref);

lines with the appropriate RMI registry code:

Registry reg = LocateRegistry.createRegistry(1099);
reg.rebind("myinterfaceimplementacja", ref);

This will create the RMI registry for you on the standard port (1099). If you run your program, the registry will be created and your remote object will be exported and registered under the given name.

The other way is to write

Registry reg = LocateRegistry.getRegistry();

This makes your program to find an existing registry that is already running. You must start the RMI registry before running your program, by calling the remiregistry tool, that is also part of the JDK:

rmiregistry

Now you can compile and you start your program:

javac Serwer.java
java Serwer

It will start and register your remote object implementation in the registry, making it available to be looked up by the clients.



来源:https://stackoverflow.com/questions/10648026/why-the-class-cannot-be-seen-in-its-source-file-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!