Java 使用清单文件ClassNotFoundException从可执行JAR启动JAR文件时出现问题

Java 使用清单文件ClassNotFoundException从可执行JAR启动JAR文件时出现问题,java,mysql,jar,rmi,Java,Mysql,Jar,Rmi,我有一个同时使用RMI和JDBC的项目,我需要使它成为一个可执行的JAR。现在我的指令是用我所有的源代码制作一个JAR文件,我包括了所有的.java文件。我的第二个JAR需要是RMI服务器.class文件,然后第三个JAR需要有我的所有RMI客户端.class文件 现在,第一个JAR和第三个JAR没有问题,但问题在于,在第二个JAR中,我需要使用JDBC,因此我需要在其中包含mysql-connector-java-5.1.31-bin.JAR文件 我的文件夹由以下布局组成,只使用默认包,所有内

我有一个同时使用RMI和JDBC的项目,我需要使它成为一个可执行的JAR。现在我的指令是用我所有的源代码制作一个JAR文件,我包括了所有的.java文件。我的第二个JAR需要是RMI服务器.class文件,然后第三个JAR需要有我的所有RMI客户端.class文件

现在,第一个JAR和第三个JAR没有问题,但问题在于,在第二个JAR中,我需要使用JDBC,因此我需要在其中包含mysql-connector-java-5.1.31-bin.JAR文件

我的文件夹由以下布局组成,只使用默认包,所有内容都在根目录中

第一个JAR-源代码JAR文件包含

A2Interface.java
A2InterfaceImpl.java
A2RmiClient.java
A2RmiServer.java
InvalidLocationException.java
DuplicatedAddressException.java
我用这个命令来震击它

jar cvf source.jar *.java
第二个JAR-包含与RMI服务器相关的类,我还需要随附mysql JDBC JAR文件

我用这个命令来震击它

jar cvfm RMIserver.jar server.txt A2RmiServer.class A2Interface.class
A2InterfaceImpl.class *Exception.class mysql-connector-java-5.1.31-bin.jar
My server.txt清单文件包含以下内容

Main-Class: A2RmiServer
Class-Path: mysql-connector-java-5.1.31-bin.jar
-empty line as per the docs-
Trouble: java.rmi.ServerException: RemoteException occurred in server thread; nested    exception is:
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: A2Interface
第三个JAR-包含与RMI客户端相关的类

jar cvfm RMIclient.jar client.txt A2RmiClient.class
A2RmiClient$EventHandler.class
任何my client.txt清单文件都包含

Main-Class: A2RmiClient
-empty line as per the docs-
现在一切都很完美,我提取了第一个JAR文件,其中包含所有.java文件,没有任何错误。然后,我尝试使用以下命令运行RMIserver.jar文件

首先,我启动注册表

start rmiregistry 5566
然后我运行可执行jar文件

java -cp mysql-connector-java-5.1.31-bin.jar -jar RMIserver.jar
这里是我得到以下例外的地方

Main-Class: A2RmiServer
Class-Path: mysql-connector-java-5.1.31-bin.jar
-empty line as per the docs-
Trouble: java.rmi.ServerException: RemoteException occurred in server thread; nested    exception is:
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: A2Interface
我根本无法确定为什么会这样做。如果我不使用任何jar文件,我的代码运行得非常好,没有异常,但只要我尝试这个,我总是会得到异常。我搜索了很多地方,有些人说你不能包括mysql JAR文件或任何类似的JAR文件,甚至根据这里的Java文档

他们还提到,它只设计用于网络上的JAR,而不在同一个目录中,但是我的教授相信这是可以做到的。我几个小时来一直想弄明白这一点,结果遇到了麻烦。我不知道如何使用必要的mysql JAR文件使其工作

哦,请不要提及使用任何其他工具来创建JAR包,因为我无法为我的任务甚至eclipse创建JAR包。我只能通过严格使用命令行工具来实现这一点。

ClassNotFoundException发生在rmiregistry中,它被包装在ServerException中返回到您的服务器应用程序

在正常使用中,RMI服务器用它们的代码库URL注释这些类,以便其他Java进程可以加载未知的类。然而,jar文件不是一个用于此目的的可用URL,我不完全确定,但我认为这是因为从文件加载通常是不安全的:从网络接收的URL

当您不使用jar文件时,它工作的原因是因为RMI注册表能够在自己的类路径中找到丢失的类,因为您在包含A2Interface.class的同一目录中运行它

你有两个选择:

从RMI服务器主机上运行的http服务器提供类文件或包含它们的jar,并使用java标志-Djava.RMI.server.codebase=http:。。。指向可以找到类的目录/jar;或 在每个类路径中插入公共类:服务器、客户端和注册表。 有关详细信息,请参见

这里是我得到以下例外的地方

Main-Class: A2RmiServer
Class-Path: mysql-connector-java-5.1.31-bin.jar
-empty line as per the docs-
Trouble: java.rmi.ServerException: RemoteException occurred in server thread; nested    exception is:
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: A2Interface
注册表的类路径上没有该类。有三种解决方案,按难度的递增顺序排列:

通过LocateRegistry.createRegistry在服务器JVM内运行注册表。执行此操作时,必须将该调用的结果存储在静态变量中,以防止它被垃圾收集。这还可以在希望JVM退出时取消导出注册表

使用相应的类路径运行RMI注册表。有几种方法可以做到这一点,包括-J-classpath和设置classpath环境变量

使用RMI代码库功能

现在我的指令是用我所有的源代码制作一个JAR文件,我包括了所有的.java文件。我的第二个JAR需要是RMI服务器.class文件,然后第三个JAR需要有我的所有RMI客户端.class文件

你的指示不正确。您需要创建四个JAR文件:

源代码为什么? .class文件,这些文件对客户端和服务器都是公用的 .class文件,这些文件仅在服务器上使用 .class文件,这些文件仅在客户端上使用。 3和4需要清单,既要命名主类,又要命名类路径上的2

服务器部署需要2和3。客户端部署需要2和4