gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 09:36:47 24 4
gpt4 key购买 nike

无论我做什么,我都无法创建类 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

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 来解决:

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 中, stub 类 (Serwer_Stub) 是在您导出(实例化)远程对象时自动生成的。但是 PortableRemoteObject 是这种情况的一个异常(exception)。您可以通过两种方式解决此问题:

  1. 按照 Kumar 的建议,将 javax.rmi.PortableRemoteObject 替换为 java.rmi.server.UnicastRemoteObject。这样就自动创建了 stub 对象,上面的代码就可以顺利运行了,我测试过了。

    public class Serwer extends UnicastRemoteObject implements MyInterface {
  2. 如果出于某种原因您必须使用 PortableRemoteObject,那么您应该使用随附的 RMI 编译器 (rmic) 工具手动生成 stub 类JDK。

    首先,编译 Serwer 类:

    javac Serwer.java

    这将生成 Serwer.class 文件。然后调用 RMIC 工具生成 stub 类:

    rmic Serwer

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

    java Serwer

    我也测试了这个,它启动没有任何异常。

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

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

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

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

关于java - 为什么在其源文件Java中看不到该类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10648026/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com