我有一个使用RMI和JDBC的项目,我需要使它成为可执行的JAR。现在我的指示是制作一个包含所有源代码的JAR文件,其中包含了我所有的.java文件。我的第二个JAR需要是RMI服务器.class文件,然后第三个JAR将拥有我所有的RMI客户端.class文件。
现在第一个JAR和第三个JAR我没有问题,但问题在于,在我的第二个我需要使用JDBC,所以我需要在其中包含mysql-connector-java-5.1.31-bin.jar
文件。
我的文件夹包含以下布局,仅使用默认包,所有内容都在根目录中。
1st JAR - 源代码Jar文件包含...
A2Interface.java
A2InterfaceImpl.java
A2RmiClient.java
A2RmiServer.java
InvalidLocationException.java
DuplicatedAddressException.java
我用这个命令来刺激它
jar cvf source.jar *.java
2nd JAR - 包含与RMI服务器相关的类,我还需要包含mysql JDBC jar文件
我用这个命令来JAR吧
jar cvfm RMIserver.jar server.txt A2RmiServer.class A2Interface.class
A2InterfaceImpl.class *Exception.class mysql-connector-java-5.1.31-bin.jar
我的server.txt清单文件包含以下内容
Main-Class: A2RmiServer
Class-Path: mysql-connector-java-5.1.31-bin.jar
-empty line as per the docs-
3rd JAR - 包含与RMI客户端相关的类
jar cvfm RMIclient.jar client.txt A2RmiClient.class
A2RmiClient$EventHandler.class
任何我的client.txt清单文件都包含
Main-Class: A2RmiClient
-empty line as per the docs-
现在所有的jar都完美无缺,我提取了我的第一个包含所有.java文件的JAR文件,没有任何错误。然后我尝试使用以下命令运行我的RMIserver.jar文件...
首先我启动注册表..
start rmiregistry 5566
然后我运行可执行jar文件..
java -cp mysql-connector-java-5.1.31-bin.jar -jar RMIserver.jar
以下是我得到以下
的例外情况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文件,我的代码运行完全没有ZERO异常,但一旦我尝试这个,我总是得到例外。我搜索了很多地方,有些人说你不能包含像这样的mysql JAR文件(或任何JAR文件),甚至根据这里的Java文档http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
他们还提到它的设计仅用于网络上的JAR,而不是在同一目录中,但是我的教授相信这可以做到。我一直试图弄清楚这几个小时并且已经到了墙上。我不知道如何使用必要的mysql JAR文件使其工作。
OH,请不要提及使用任何其他工具来创建JAR包,因为我无法为我的任务甚至是日食做到这一点。我只能通过严格使用命令行工具来实现这一点。
答案 0 :(得分:0)
ClassNotFoundException
正在 rmiregistry 中发生,并且会以#{1}}的形式返回到您的服务器应用程序。
在正常使用中,RMI服务器使用其代码库URL注释类,以便其他Java进程可以加载未知类。但是,jar文件不是用于此目的的可用URL(我不完全确定,但我认为这是因为从文件中加载它通常是不安全的:从网络)。
当你不使用jar文件时它工作的原因是因为rmiregistry能够在自己的类路径中找到缺少的类(因为你在包含A2Interface.class的同一目录中运行它) )。
您有两种选择:
ServerException
指向类所在的目录/ jar被发现;或有关详细信息,请参阅http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/codebase.html。
答案 1 :(得分:0)
这是我得到以下
的例外情况
注册表在其CLASSPATH上没有该类可用。有三种解决方案,难度逐渐增加:
通过LocateRegistry.createRegistry().
在服务器JVM中运行注册表。执行此操作时,必须将该调用的结果存储在静态变量中,以防止对其进行垃圾回收。这也可以在您希望JVM退出时取消导出注册表。
使用适当的CLASSPATH运行rmiregistry
。有几种方法可以做到这一点,包括-J-classpath
和设置CLASSPATH
环境变量。
使用RMI代码库功能。
现在我的指示是制作一个包含我所有.java文件的源代码的JAR文件。我的第二个JAR需要是RMI服务器.class文件,然后第三个JAR将拥有我所有的RMI客户端.class文件。
您的说明不正确。您需要制作四个 JAR文件:
(3)和(4)需要清单,既可以命名Main-Class,也可以命名(2)类路径。
服务器部署需要(2)和(3)。客户端部署需要(2)和(4)。