抛出java.lang.NoClassDefFoundError

时间:2018-12-20 02:04:12

标签: java rmi

我正在尝试使用RMI实施2人网络问答游戏。我有一个DispatcherInterface(接口)和Dispatcher(为前者实现),它们尊重RMI体系结构。 服务器模型具有UserTheme,其中Quiz将处于特定主题,我的想法是,当User连接到Theme时,它们d被添加到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")),但是我发现它很不方便,因为我必须遍历连接的用户列表。为了获得User实例,我需要添加到waitingList中。因此,理想情况下,我希望能够将User的实例传递给该方法。

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

我不明白为什么不能将User对象传递给方法,尤其是因为它是可序列化的。

出于完整性考虑,对于客户端部分,我类似地实现了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

1 个答案:

答案 0 :(得分:0)

您正在使用jdk 10执行代码。在jdk 9中,某些代码库已移入模块,并且默认情况下不再可用,java.sql在这些非根模块之一中。您需要在Java命令中使用“ --add-modules java.sql”,以使java.sql包在运行时可用。

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