简体   繁体   中英

Issues launching a JAR file from an executable JAR using Manifest file ClassNotFoundException

I have a project which uses both RMI and JDBC and I need to make it an executable JAR. Now my instructions are to make one JAR file with all my source code which ive included all my .java files. My second JAR needs to be the RMI server .class files and then the third JAR is to have all my RMI client .class files.

Now the first JAR and the third JAR I can make no problem but the issue lies with that in my second I require the use of JDBC so I need to include the mysql-connector-java-5.1.31-bin.jar file in it.

My folder consists of the following layout, only default packages are used and everything is in the root directory.

1st JAR - Source Code Jar File Contains...

A2Interface.java
A2InterfaceImpl.java
A2RmiClient.java
A2RmiServer.java
InvalidLocationException.java
DuplicatedAddressException.java

I used this command to jar it

jar cvf source.jar *.java

2nd JAR - Contains the classes related to RMI server, I also need the mysql JDBC jar file included along with it

And I used this command to JAR it

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 Manifest file contains the following

Main-Class: A2RmiServer
Class-Path: mysql-connector-java-5.1.31-bin.jar
-empty line as per the docs-

3rd JAR - Contains the classes related to the RMI client

jar cvfm RMIclient.jar client.txt A2RmiClient.class
A2RmiClient$EventHandler.class

Any my client.txt manifest file contains

Main-Class: A2RmiClient
-empty line as per the docs-

Now everything jars perfect fine and I extract my first JAR file containing all my .java files with no errors. I then attempt to run my RMIserver.jar file with the following command...

First I start the registry..

start rmiregistry 5566

Then I run the executable jar file..

java -cp mysql-connector-java-5.1.31-bin.jar -jar RMIserver.jar

AND here is where I get an Exception of the following

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

I cannot determine why this is doing this at all. If I dont use any jar files my code runs perfectly fine with ZERO exceptions but as soon as I try this I always get exceptions. I have searched many places and some people say that you cant include the mysql JAR file (or any JAR file) like this and even according to the Java doc here http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html

They also mention that its designed for use only for JAR's over the network and not in the same directory, however my professor believes this can be done. I have been trying to figure this out for hours and have come to a wall. I don't know how I can make it work with using the necessary mysql JAR file.

OH and please dont mention using any other tools to create a JAR package as I cannot do that for my assignment or even eclipse. I can only do this from using strictly command line tools.

The ClassNotFoundException is happening in the rmiregistry , and it's being returned to your server application wrapped in a ServerException .

In normal usage, the RMI server annotates the classes with their codebase URL so that other Java processes can load the unknown classes. However, the jar file isn't a usable URL for this purpose (I'm not totally sure, but I think it's because it's generally insecure to load from file: URLs received from the network).

The reason it works when you're not using jar files is because the rmiregistry is able to find the missing classes in its own classpath (because you're running it in the same directory that contains A2Interface.class).

You have two choices:

  1. Serve the class files (or a jar containing them) from an http server running on the RMI server's host, and use the java flag -Djava.rmi.server.codebase=http:... to point to the directory/jar where the classes can be found; or
  2. Insert the common classes in every classpath: server, client, and rmiregistry.

For more detail, see http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/codebase.html .

And here is where I get an Exception of the following

The Registry doesn't have that class available on its CLASSPATH. There are three solutions, in increasing order of difficulty:

  1. Run the Registry inside the server JVM, via LocateRegistry.createRegistry(). When you do this, you must store the result of that call in a static variable, to prevent it being garbage-collected. That also makes it possible to unexport the Registry when you want the JVM to exit.

  2. Run the rmiregistry with an appopriate CLASSPATH. There are several ways to do that, including -J-classpath and setting a CLASSPATH environment variable.

  3. Use the RMI codebase feature.

Now my instructions are to make one JAR file with all my source code which ive included all my .java files. My second JAR needs to be the RMI server .class files and then the third JAR is to have all my RMI client .class files.

Your instructions are incorrect. You need to make four JAR files:

  1. Source code (why?)
  2. .class files that are common to both client and server
  3. .class files that are only used on the server
  4. .class files that are only used on the client.

(3) and (4) need manifests, both to name the Main-Class and to name (2) on the Class-path.

The server deployment needs (2) and (3). The client deployment needs (2) and (4).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM