为什么无法在其源文件Java中看到该类 [英] Why the Class cannot be seen in its source file Java

查看:71
本文介绍了为什么无法在其源文件Java中看到该类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

我刚刚得到这个:

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();
    }
}
}


推荐答案

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

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();
        }
    }
}

但是,此错误无关到 ClassNotFoundException 。导致异常的原因是您使用 PortableRemoteObject 作为远程实现的基类。通常,在Java RMI中,当导出(实例化)远程对象时,会自动生成存根类( Serwer_Stub )。但是 PortableRemoteObject 是这种情况的例外。您可以通过以下两种方法解决:

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. 按照Kumar的建议,替换 javax.rmi.PortableRemoteObject java.rmi.server.UnicastRemoteObject 。这样,便自动创建了存根对象,并且上面的代码将愉快地运行,我对其进行了测试。

  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 {


  • 如果出于某些原因必须使用 PortableRemoteObject ,则应该使用JDK附带的RMI编译器( rmic )工具手动生成存根类。

  • 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.

    首先,您编译 Serwer 类:

    javac Serwer.java
    

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

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

    rmic Serwer
    

    这将生成 Serwer_Stub.class 文件。现在您可以运行服务器了:

    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.

    请注意,您的代码中还有一个Java命名用法错误,导致另一个异常( NoInitialContextException ),但这与问题无关,这就是为什么我要评论在上面的代码中。由于我不是 javax.naming 的专家,因此需要其他人来帮助您。

    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.

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

    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);
    

    行以及相应的RMI注册表代码:

    lines with the appropriate RMI registry code:

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

    这将在标准端口(1099)上为您创建RMI注册表。如果运行程序,将创建注册表,并以给定名称导出和注册远程对象。

    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.

    另一种方法是编写

    Registry reg = LocateRegistry.getRegistry();
    

    这使您的程序可以找到已经运行的现有注册表。您必须在运行程序之前启动RMI注册表,方法是调用 remiregistry 工具,该工具也是JDK的一部分:

    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.

    这篇关于为什么无法在其源文件Java中看到该类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆