RMI 服务器接口(调度程序)方法抛出 java.lang.NoClassDefFoundError



我正在尝试使用 RMI 实现一个 2 人网络问答游戏。我有一个尊重RMI架构的DispatcherInterface(接口)和Dispatcher(实现前者)。 服务器模型具有UserThemeQuiz在特定主题中的位置,我的想法是,当User连接到Theme时,它们将被添加到Map<User,Theme> waitingList中,直到另一个User出现与他们对战。

我的问题在于实现,在尝试实现一个简单的 setter 方法以将用户添加到等待列表时,我收到以下错误:

Error occurred in server thread; nested exception is: 
java.lang.NoClassDefFoundError: java/sql/SQLException

这对我来说没有意义,因为我的类路径是为 RMI 注册表和编译/运行命令很好地定义的。

public interface DispatcherInterface extends Remote {
public User login(ReceiverInterface client, String email, String password) throws RemoteException;
public void addToWaitingList(int userID, Theme theme) throws RemoteException;
public void addToWaitingList(User user, Theme theme) throws RemoteException;
}

第一种方法完美运行,没有问题,而另一种方法则不考虑其实现(尝试了一个简单的System.out.print("test")),但是我发现这很不方便,因为我必须遍历连接的用户列表才能获得我需要添加到我的waitingListUser实例。因此,从理想上讲,我希望能够将User实例传递给该方法。

public class User implements Serializable {
public ReceiverInterface client;
public int id;
public String pseudo;
...
}

我不明白为什么我不能将 aUser对象传递给该方法,特别是因为它是可序列化的。

为了完整起见,对于客户端部分,我已经实现了类似的ReceiverInterfaceReceiver,通过代理(DispatcherInterface)与服务器通信。

public class Receiver implements ReceiverInterface {
private DispatcherInterface = proxy;
private User user;
private String serverIP;
public Receiver(String serverIP) throws RemoteException, NotBoundException {
this.serverIP = serverIP;
Registry registry = LocateRegistry.getRegistry(serverIP);
this.proxy = (DispatcherInterface) registry.lookup("QuizApp");
}
...
}

任何帮助,不胜感激。

编辑:我使用IDE(IntelliJ)来运行我的代码,它使用以下命令:

/usr/lib/jvm/java-10-openjdk/bin/java -javaagent:/opt/intellij-idea-ultimate-edition/lib/idea_rt.jar=41683:/opt/intellij-idea-ultimate-edition/bin -Dfile.encoding=UTF-8 -classpath /home/rand/gm4/JAVA/QuizApp/out/production/QuizApp:/home/rand/gm4/JAVA/QuizApp/lib/miglayout-swing-5.2.jar:/home/rand/gm4/JAVA/QuizApp/lib/miglayout-core-5.2.jar:/home/rand/gm4/JAVA/QuizApp/lib/sqlite-jdbc-3.23.1.jar server.Run

用更好的术语(没有.jar依赖项),从项目路径运行是:

javac -d out/production/[project_name] src/server/Run.java
javac -d out/production/[project_name] src/client/Run.java
rmiregistry -J-Djava.class.path=out/production/[project_name]/
java -cp out/production/[project_name] server.Run
java -cp out/production/[project_name] client.Run

您正在使用 jdk 10 来执行代码。在 jdk 9 中,一些代码库被移动到模块中,默认情况下不再可用,java.sql 位于这些非根模块之一中。您需要将"--add-modules java.sql"与java命令一起使用,以使java.sql包在运行时可用。

由于您使用的是 Intellij 来运行代码,因此以下文档可能有助于解释如何在从 IDE 运行时设置 Intellij 以包含此模块。 https://www.jetbrains.com/help/idea/getting-started-with-java-9-module-system.html

相关内容

最新更新