为什么在Java源文件中看不到该类

为什么在Java源文件中看不到该类,java,classnotfoundexception,Java,Classnotfoundexception,无论我做什么,我都不能创建类Serwer的新实例。请帮助,不知何故构造函数是不可见的。我不明白为什么会这样。构造函数是公共的,所有内容都编码在一个文件中 我只知道: java.rmi.StubNotFoundException: Stub class not found: Serwer_Stub; nested exception is: java.lang.ClassNotFoundException: Serwer_Stub at sun.rmi.server.Util.createStu

无论我做什么,我都不能创建类Serwer的新实例。请帮助,不知何故构造函数是不可见的。我不明白为什么会这样。构造函数是公共的,所有内容都编码在一个文件中

我只知道:

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

代码中有两个bug。第一个是
Serwer
构造函数中明显的无限递归,在这里您一次又一次地调用构造函数。这可以通过从构造函数中删除该行并在下一行中用
This
替换
ref
来解决:

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();
        }
    }
}
但是,这个bug与您得到的
ClassNotFoundException
无关。导致异常的原因是您使用了
PortableRemoteObject
作为远程实现的基类。通常在JavaRMI中,在导出(实例化)远程对象时,会自动生成存根类(
Serwer\u stub
)。但是,
PortableRemoteObject
是这种情况的一个例外。您可以通过两种方式解决此问题:

  • 正如Kumar所建议的,将
    javax.rmi.PortableRemoteObject
    替换为
    java.rmi.server.UnicastRemoteObject
    。通过这种方式,存根对象将自动创建,上面的代码将愉快地运行,我对其进行了测试

    public class Serwer extends UnicastRemoteObject implements MyInterface {
    
  • 如果出于某种原因必须使用
    PortableRemoteObject
    ,则应使用JDK附带的RMI编译器(
    rmic
    )工具手动生成存根类

    首先,编译
    Serwer
    类:

    javac Serwer.java
    
    这将生成
    Serwer.class
    文件。然后调用RMIC工具生成存根类:

    rmic Serwer
    
    这将生成
    Serwer\u Stub.class
    文件。现在,您可以运行服务器:

    java Serwer
    
    我也测试了这个,它毫无例外地启动

  • 请注意,在使用Java命名的代码中还有另一个bug,导致了另一个异常(
    NoInitialContextException
    ),但这也与问题无关,这就是我在上面的代码中注释掉它的原因。由于我不是
    javax.naming
    方面的专家,因此需要其他人来帮助您

    也许您打算使用RMI注册表,而不是错误地使用命名。RMI注册表是在JavaRMI中绑定和查找远程对象的本机方法。在这种情况下,您应该更换

    Context ctx = new InitialContext();
    ctx.rebind("myinterfaceimplementacja", ref);
    
    具有适当RMI注册表代码的行:

    Registry reg = LocateRegistry.createRegistry(1099);
    reg.rebind("myinterfaceimplementacja", ref);
    
    这将在标准端口(1099)上为您创建RMI注册表。如果您运行您的程序,将创建注册表,您的远程对象将以给定的名称导出和注册

    另一种方法是写作

    Registry reg = LocateRegistry.getRegistry();
    
    这使您的程序能够找到已在运行的现有注册表。您必须在运行程序之前启动RMI注册表,方法是调用
    remiregistry
    工具,该工具也是JDK的一部分:

    rmiregistry
    
    现在您可以编译并启动程序:

    javac Serwer.java
    java Serwer
    

    它将启动并在注册表中注册您的远程对象实现,使其可供客户端查询。

    Serwer
    构造函数中,您正在通过调用构造函数实例化另一个
    Serwer
    对象?我在这里闻到无限的递归…@buc-你的鼻子像猎犬。好眼力。嗯,ClassNotFoundDef可能与无限递归有关。如果未生成该类,则无法找到该类…听起来很可怕。如何修复它?删除
    Serwer ref=new Serwer()来自构造函数!
    
    javac Serwer.java
    java Serwer