Java RMI and ClassNotFoundException - java

I am just starting to learn how to use RMI, and I have a question. I have the following directory structure:
compute.jar
client
|
org\examples\rmi\client
|--> ComputePi // client main
|--> Pi // implements Task
org\examples\rmi\compute
|--> Compute // interface
|--> Task // interface
server
|
org\examples\rmi\engine
|--> ComputeEngine // server main, implements Compute
org\examples\rmi\compute
|--> Compute // interface
|--> Task // interface
Here's the main method in the ComputePi class:
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Compute";
// args[0] = 127.0.0.1, args[1] is irrelevant
Registry registry = LocateRegistry.getRegistry(args[0], 0);
Compute comp = (Compute) registry.lookup(name);
Pi task = new Pi(Integer.parseInt(args[1]));
BigDecimal pi = comp.executeTask(task);
System.out.println(pi);
}
catch (Exception e) {
System.err.println("ComputePi exception:");
e.printStackTrace();
}
Here's the main method in the ComputeEngine class:
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Compute";
Compute engine = new ComputeEngine();
Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0);
Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, stub);
System.out.println("ComputeEngine bound.");
}
catch (Exception e) {
System.err.println("ComputeEngine exception: ");
e.printStackTrace();
}
Here's the executeTask method, also in the ComputeEngine class:
public <T> T executeTask(Task<T> task) throws RemoteException {
if (task == null) {
throw new IllegalArgumentException("task is null");
}
return task.execute();
}
The RMI registry and server start up just fine. Here are the params for the server:
C:\Users\Public\RMI\server>set CLASSPATH=
C:\Users\Public\RMI\server>start rmiregistry
C:\Users\Public\RMI\server>java -Djava.rmi.server.codebase="file:/C:/Users/Public/RMI/compute.jar" -Djava.rmi.server.hostname=127.0.0.1 -Djava.security.policy=server.policy org.examples.rmi.engine.ComputeEngine
Here are the params for the client:
C:\Users\Public\RMI\client>java -Djava.rmi.server.codebase="file:/C:/Users/Public/RMI/compute.jar" -Djava.security.policy=client.policy org.examples.rmi.client.ComputePi 127.0.0.1 45
However, I get the following exception when I try to run the client:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: org.examples.rmi.client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.executeTask(Unknown Source)
at org.examples.rmi.client.ComputePi.main(ComputePi.java:38)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: org.examples.rmi.client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.examples.rmi.client.Pi
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader.loadClass(Unknown Source)
at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
... 11 more
But if I add the Pi.class file to the server directory:
server
|
org\examples\rmi\engine
|--> ComputeEngine // server main, implements Compute
org\examples\rmi\compute
|--> Compute // interface
|--> Task // interface
org\examples\rmi\client
|--> Pi // same as Pi for client
The program works. My question is, does Pi.class really need to be on the server for my program to work? My understanding is (and please correct me if I'm wrong) that I send an instance of that class to the server, and the server would know what to do with it, i.e. it doesn't care about the implementation. Can someone explain how RMI is working in my case? I really appreciate it. Thanks!

I tried this example with two PC in same network. One with Java 1.7.0_40 working as server, another with Java 1.7.0_45 as client. Both PCs are Windows based. I met the same problem raised by denshaotoko.
The solution is:
Server side:
C:\>start rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false
The -J-Djava.rmi.server.useCodebaseOnly option is needed for Java 7 since the default value is true, which means the RMI Registry will not look for other code base except the directory it is started from. Then the next step starting the server will fail. Details see here: http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/enhancements-7.html
C:\>java -cp c:\rmi;c:\rmi\compute.jar -Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.codebase=file:/c:/rmi/compute.jar -Djava.rmi.server.hostname=192.168.1.124 -Djava.security.policy=c:\rmi\server.policy engine.ComputeEngine
Again the java.rmi.server.useCodebaseOnly should be set to false. Otherwise the server won't use the codebase provided by the client. Then client side will get the class not found exception. The hostname of 192.168.1.124 is the server's IP address
You should get "ComputeEngine bound"
Client side:
C:\>java -cp c:\rmi;c:\rmi\compute.jar -Djava.rmi.server.codebase=http://54.200.126.244/rmi/ -Djava.security.policy=c:\rmi\client.policy client.ComputePi 192.168.1.124 45
I trid the file:/ URL but not successful. I think the reason is simple. There're so many security limits that make the server not possible to access a file on the client PC. So I put the Pi.class file on my web server which is at http://54.200.126.244 under rmi directory. My web server use Apache. Any PC can access http://54.200.126.244/rmi/ so the problem is solved cleanly.
Finally, you should be able to start the rmiregistry, the server and the client from any directory using the same commands. Otherwise, some settings may still not be correct even if you can succeed. For example, if you start rmiregistry from the directory contain the "compute" directory (in my case is C:\rmi), the rmiregistry will directly load Compute.class and Task.class from it's starting directory, so the setting of -Djava.rmi.server.codebase=file:/c:/rmi/compute.jar become useless.

You are trying to send a serialized object of a class that is unknown to the server.
When you execute:
Pi task = new Pi(Integer.parseInt(args[1]));
BigDecimal pi = comp.executeTask(task);
The server doesn't really know what is Pi. And since the Pi class is a part of your API, it should be loaded on server, too.
When I have an application that needs to execute something remotely, using for example RMI, Spring Remoting or similar, I divide my project in 3 projects: API, Server and Client. The API project will have all interfaces and model classes relevant to the functionality (this project will result in a jar, and is more or less like your computer JAR). The server will import the API JAR, will implement the interfaces and make the service available through an Remote layer (like you did with your server), and the client as you did with your client.
When you work with serialization, the class itself must be known by both sides. What is then transferred is the state of the objects in order to rebuild it on the other side.
Serialization is the mechanism used by RMI to pass objects between
JVMs, either as arguments in a method invocation from a client to a
server or as return values from a method invocation.
A bit of Serialization on RMI By William Grosso (October 2001). And here a bit more info.

My question is, does Pi.class really need to be on the server for my program to work? My understanding is (and please correct me if I'm wrong) that I send an instance of that class to the server, and the server would know what to do with it, i.e. it doesn't care about the implementation.
You understood correctly. Pi.class doesn't need to be on server when you compile it, but the server does need to download it at runtime! (Pi must be serializable)
The question is: How does a server know where to download the Pi.class when does he need it?
And the answer is: by the value of java.rmi.server.codebase setting provided by the client. The client must set the java.rmi.server.codebase option. You have to say where the Pi.class is. It is a common habit to put a copy of Pi.class in a public directory for deployment. Therefore the complete solution is:
The Structure:
compute.jar
client\
|-org\
| |-examples\
| |-rmi\
| |client\
| |--> ComputePi // client main
| |--> Pi // implements Task
|-deploy\
| |-org\
| |-examples\
| |-rmi\
| |-client\ // directory that will contain the deployment copy of Pi.class
|--> client.policy
server\
|-org\
| |-examples\
| |-rmi\
| |-engine\
| |--> ComputeEngine // server main, implements Compute
|--> server.policy
where compute.jar is a jar file previously created
cd C:\Users\Public\RMI\
javac compute\Compute.java compute\Task.java
jar cvf compute.jar compute\*.class
Did you set correctly the package and import commands in your java files? Because you modified the original structure of the tutorial...
Compile the Server:
C:\Users\Public\RMI\> cd server
C:\Users\Public\RMI\server> javac -cp ..\compute.jar org\examples\rmi\engine\ComputeEngine.java
Compile the Client:
C:\Users\Public\RMI\> cd client
C:\Users\Public\RMI\client> javac -cp ..\compute.jar org\examples\rmi\client\ComputePi.java org\examples\rmi\client\Pi.java
Move the Pi.class into the deploy directory
C:\Users\Public\RMI\> cp client\org\examples\rmi\client\Pi.class client\deploy
Run the rmi registry. If you are using java 7 set the option -J-Djava.rmi.server.useCodebaseOnly=false, as suggested by muyong
C:\Users\Public\RMI\> start rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false
Run the server. If you are using java 7 set the option -J-Djava.rmi.server.useCodebaseOnly=false, as suggested by muyong
C:\Users\Public\RMI\> cd server
C:\Users\Public\RMI\server> java -cp .;..\compute.jar
-Djava.rmi.server.useCodebaseOnly=false
-Djava.rmi.server.codebase=file:/c:/Users/Public/RMI/compute.jar
-Djava.rmi.server.hostname=127.0.0.1
-Djava.security.policy=server.policy
org.examples.rmi.engine.ComputeEngine
Run the Client. NOTE: watch out the java.rmi.server.codebase setting (REMEMBER the conclusive /)
C:\Users\Public\RMI\> cd client
C:\Users\Public\RMI\client> java -cp .;..\compute.jar
-Djava.rmi.server.codebase=file:/c:/Users/Public/RMI/client/deploy/
-Djava.security.policy=client.policy
org.examples.rmi.client.Compute.Pi 127.0.0.1 45
Let me know if it works!
P.s. I don't use Windows OS but Linux, I could have made confusion between '\' and '/'

from jdk 1.7 the default value of useCodebaseOnly is true, that mean it wont look for other codebase unless it is in the same directory.
Set this vm argument -Djava.rmi.server.useCodebaseOnly=false for running both server and client and also provide the path to codebase and hostname as well. See below below examples.
Below is my implementation and it's according to my directory structure. For running in windows replace : (colon) with ; (semi-colon).
java -cp classes:classes/compute.jar
-Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.codebase=url:http://localhost:4800/ -Djava.rmi.server.hostname=localhost -Djava.security.policy=client.policy client.ComputePi localhost 45

I think the codebase that you specify for the client is not correct:
-Djava.rmi.server.codebase="file:/C:/Users/Public/RMI/compute.jar"
This will not help the server to find client.Pi .
The "Java Tutorial RMI" specifies
-Djava.rmi.server.codebase=file:/c:/home/jones/public_html/classes/
and that's the dir under which there is client/Pi.class (i.e. if one follows the tutorial, where "jones" wrote the client).
Unfortunately, even when following my own advice, meaning in my situation specifying
-Djava.rmi.server.codebase=file:/h:/rmi-example/jones/src/
when I start the client, I get the same exception as you do.
Haven't solved it yet. I'm hoping java option -verbose:class will shed some light on the problem.

Press Win + R shortcut keys together on your keyboard. This will open the Run dialog. ...
Type the following command in the Run box: rundll32.exe sysdm.cpl,EditEnvironmentVariables
then give you current directory

Related

Windows Server 2003 JDBC driver

I wrote a simple multiplayer JAVA app that can connect to MySQL using JDBC driver.
I ended up packing it up in .jar file. When I was testing on my local machine MacOS, it was fine. (I don't exactly remember all the steps to set up JDBC driver, because it was year ago when I wrote this app). The app at this time connects to an external database on another server (I didn't change that because it had no problems). It would be another error if it was a problem with the remote database.
Now, when I need to put it on production on Windows Server 2003, I keep getting the standard error :
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
And I don't get it, because I think I've done the steps right:
0. Installed Java
1. downloaded this: http://dev.mysql.com/downloads/connector/j/
2. added it to the same folder where the app.jar is
3. wrote in cmd: set CLASSPATH =.;C:\Documents and Settings\Administrator\Desktop\tvplan_exchange\mysql-connector-java-5.1.28-bin.jar
4. tested the variable: echo %CLASSPATH% and it showed the same path
5. runned the app: java -jar app.jar
6. got the error:
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at svagers.Db.connect(Db.java:21)
at svagers.Server.main(Server.java:58)
MYSQL ERRORcom.mysql.jdbc.Driver
Well, for those who think that using app like this is a security error - no worries, that is not a problem, I just need it to be running not to consider risks :)
This is the environment:
OS: Windows Server 2003 (Standard Edition, Service Pack 2)
Java: 1.7.0_45 (SE Runtime Environment
I was going to say "run the app with java -cp %CLASSPATH% -jar app.jar" but then remembered you can't have both: you use either -jar or -cp. See this answer.

Java RMI: Server and Client work well in the same folder, Not work when in different folders in the same PC?

I am new to RMI
I tried this example. This works as expected.
Calculator.class
CalculatorImpl.class + CalculatorImpl_Stub.class
CalculatorServer.class
+
CalculatorClient.class
Actually I am planning to test it in two different PCs. But instead of that, I started trying it in the same PC in two different folders.
One folder conatins the Server:
Calculator.class :interface
CalculatorImpl.class + CalculatorImpl_Stub.class
CalculatorServer.class
The other folder contains the Client:
Calculator.class :this is just a copy of the Calculator interface of the Server above
CalculatorClient.class
When I try to run things
The server is running well
Now when I run the client this error printed:
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: CalculatorImpl_Stub (no security manag
er: RMI class loader disabled)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at java.rmi.Naming.lookup(Unknown Source)
at CalculatorClient.main(CalculatorClient.java:12)
Caused by: java.lang.ClassNotFoundException: CalculatorImpl_Stub (no security ma
nager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader.loadClass(Unknown Source)
at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
... 3 more
They work well in the same folder.
error when they are in two different folders.
Why?
How to work around this error?
The class named in the exception isn't available on the clients CLASSPATH. So fix that. The remote stub and interface and everything they depend on must be distributed to the client.
You primary problem is following an RMI example which is very out of date. here's a hint, if the RMI example includes the use of rmic (or stubs and skeletons), don't use it. I would suggest starting from the sun/oracle tutorial.
The most common reason of this problem is calling the UnicastRemoteObject.exportObject(Remote obj). From the documentation you will see it returns an instance of RemoteStub so that stub class must be available, this is only possible if you have generated with rmic.
Use UnicastRemoteObject.exportObject(Remote obj, int port) instead. It returns an interface (Remote) and would work without generated classes with recent releases.

Connecting client (on VirtualBox) and server (on localhost) using CORBA - org.omg.CORBA.BAD_PARAM:

Im working now on simple gui appllication in Java/C++ and CORBA. I want my client on VirtualBox connect to server on localhost. When I have a simple app, like a calc I wrote about earlier its just fine. But when it comes to run client which needs some args witch javas -cp option, Im getting errors. (Theres no such problem when I have both client and server on localhost!) Im using Win XP on VirtualBox and Ubuntu on localhost.
My errors:
WARNING: "IOP00100007: (BAD_PARAM) string_to_object conversion failed due to bad
scheme name"
org.omg.CORBA.BAD_PARAM: vmcid: OMG minor code: 7 completed: No
at com.sun.corba.se.impl.logging.OMGSystemException.soBadSchemeName(Unkn
own Source)
at com.sun.corba.se.impl.logging.OMGSystemException.soBadSchemeName(Unkn
own Source)
at com.sun.corba.se.impl.resolver.INSURLOperationImpl.operate(Unknown So
urce)
at com.sun.corba.se.impl.resolver.ORBInitRefResolverImpl.resolve(Unknown
Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown
Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown
Source)
at com.sun.corba.se.impl.orb.ORBImpl.resolve_initial_references(Unknown
Source)
at ClientConnection.connect(ClientConnection.java:57)
at Client.main(Client.java:295)
Exception in thread "main" org.omg.CORBA.BAD_PARAM: vmcid: OMG minor code: 7
completed: No
at com.sun.corba.se.impl.logging.OMGSystemException.soBadSchemeName(Unkn
own Source)
at com.sun.corba.se.impl.logging.OMGSystemException.soBadSchemeName(Unkn
own Source)
at com.sun.corba.se.impl.resolver.INSURLOperationImpl.operate(Unknown So
urce)
at com.sun.corba.se.impl.resolver.ORBInitRefResolverImpl.resolve(Unknown
Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown
Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown
Source)
at com.sun.corba.se.impl.orb.ORBImpl.resolve_initial_references(Unknown
Source)
at ClientConnection.connect(ClientConnection.java:57)
at Client.main(Client.java:295)
make[1]: *** [run] Error 1
ClientConnection.java:57 is a line objRef = clientORB.resolve_initial_references("NameService");
Client.java:295 is a line: ClientConnection.connect(args);
A connect method is just an ordinary client-connection corba code.
I ran my example:
1)
C:\Temp\Client>java -cp .:../Dir1:../Dir2 Client -ORBInitRef NameService
=corbaloc::192.168.56.1:2809/NameService
Error: Could not find or load main class Client so its even didnt run at all ..
2) with the help of a Makefile:
HOST = 192.168.56.1
PORT = 2809
NAMESERVICE = NameService
run:
java -cp .:../Dir1:../Dir2 Client -ORBInitRef NameService=corbaloc::$(HOST):$(PORT)/$(NAMESERVICE)
by typing make run and then I got those error I posted earlier. Whats wrong? I mean, a simple code works fine but gui version doesnt want to ... is there a problem with -cp option? I cant change my apps' dir tree.
I personally see two problems you have.
the classpath thing. Do you hava a file named Client.class in . or Dir1 or Dir2. If not, look for it and add it's dir to the classpath. If it is in, please provide more information
The CORBA thing; I would like to see your Orb.init(); call. Everything else looks good.

Applet class loader cannot find one of the classes in the jar

I get the ff. error in Java Console occassionally:
Exception in thread "thread applet-my.package.MyApplet-10" java.lang.NoClassDefFoundError: another/package/SomeClass
at my.package.MyApplet.init(MyApplet.java:95)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: another.package.SomeClass
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
... 3 more
Caused by: java.io.IOException: open HTTP connection failed:https://myserver/mycontext/applets/another/package/SomeClass.class
at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
... 7 more
My applet tag is as follows:
<applet codebase="../../applets" code="my.package.MyApplet" class="invisible" id="myApplet">
<param value="value0" name="param0"/>
...
<param value="valueN" name="paramN" />
<param value="folder/myApplet__0.0.1177.jar,folder/commons-io-1.3.2__0.0.1177.jar,..." name="cache_archive"/>
<param value="0.0.1177.0,0.0.1177.0,...," name="cache_version"/>
</applet>
It is important I stress the word "occasionally". Sometimes the applet is initialized without a hitch. This also means that, often, when the browser is restarted, the problem goes away.
I am aware of applet fails to load class from jar and Applet class loader cannot find a class in the applet's jar but I think they are not applicable to my case. SomeClass and MyApplet are in the same jar and the page is being accessed locally.
Caused by: java.io.IOException: open HTTP connection failed:https://myserver/mycontext/applets/another/package/SomeClass.class
This looks like there is a connection issue with retrieving the jar file from the HTTPS server.
I don't know exactly what version of Java are you running, but you can check the reason of the defect pertaining to your problem here.
If this is not the problem, then make sure that there's enough caching for your JAR file when downloaded else it fails to launch. It's not code issue unfortunately.
UPDATE Is your class SomeClass accessing any remote server or database by any chance?
The exception clearly shows that there is an AccessControl privilege that has been denied.
at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
Bear in mind, that applets are like Flash Objects:
They are both downloaded and run from the client side.
Only difference is that Applets were designed with lots of access control rules such as, it must not connect to servers hidden behind company DMZ (De-Militarized Zone), etc.
If that's the case, I suggest you find a way to retrieve your data outside applets (try servlet?)
UPDATE 2 It seems the JVM can't find the trusted certificate to match with your signed jar.
Since your jar file is signed make sure that the jar file can point your trusted certificate (remember, it must be trusted).
More information, check: http://faq.javaranch.com/java/HowCanAnAppletReadFilesOnTheLocalFileSystem AND http://www.developer.com/article.php/3303561
Probably has something to do with http://download.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html. I.e., one or more of the jars defines/expects a provider. Investigate when there is time.

Java RMI (Server: TCP Connection Idle/Client: Unmarshalexception (EOFException))

I'm trying to implement Sun Tutorials RMI application that calculates Pi. I'm having some serious problems and I cant find the solution eventhough I've been searching the entire web and several javaskilled people.
I'm hoping you can put an end to my frustrations.
The crazy thing is that I can run the application from the cmd on my desktop computer. Trying the exact same thing with the exact same code in the exact same directories on my laptop produces the following errors. The problem occures when I try to connect the client to the server.
I don't believe that the error is due to my policyfile as I can run it on the desktop. It must be elsewhere. Have anyone tried the same and can you give me a hint as to where my problem is, please?
POLICYFILE SERVER:
grant
{
permission java.security.AllPermissions;
permission java.net.SocketPermission"*", "connect, resolve";
};
POLICYFILE CLIENT:
grant
{
permission java.security.AllPermissions;
permission java.net.SocketPermission"*", "connect, resolve";
};
______________________________________________
SERVERSIDE ERRORS:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\STUDENT>cd\
C:\>start rmiregistry
C:\>java -cp c:\java;c:\java\compute.jar -Djava.rmi.server.codebase=file:/c:/jav
a/compute.jar -Djava.rmi.server.hostname=localhost -Djava.security.policy=c:/jav
a/servertest.policy engine.ComputeEngine
ComputeEngine bound
Exception in thread "RMI TCP Connection(idle)" java.security.AccessControlExcept
ion: access denied (java.net.SocketPermission 127.0.0.1:1440 accept,resolve)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkAccept(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.checkAcceptPermi
ssion(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.checkAcceptPermission(Unknown Sour
ce)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Sou
rce)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Sour
ce)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source
)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
_______________________________
CLIENTSIDE ERRORS:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\STUDENT>cd\
C:\>java -cp c:\java;c:\java\compute.jar -Djava.rmi.server.codebase=file:\C:\jav
a\files\ -Djava.security.policy=c:/java/clienttest.policy client.ComputePi local
host 45
ComputePi exception:
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception
is:
java.io.EOFException
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unkn
own Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.executeTask(Unknown Source)
at client.ComputePi.main(ComputePi.java:18)
Caused by: java.io.EOFException
at java.io.DataInputStream.readByte(Unknown Source)
... 6 more
C:\>
Thanks in advance
Perry
Your server didn't have permission to accept a connection from that client.
Ergo your policy file wasn't where you said it was, or wasn't loaded for some other reason.
Run it with -Djava.security.debug=access,failure and you will see what protection domain you were in when the security exception occurred, and what permissions it had.
java -cp c:\java;c:\java\compute.jar -Djava.rmi.server.codebase=file:/c:/java/compute.jar -Djava.rmi.server.hostname=localhost -Djava.security.policy=c:/java/servertest.policy engine.ComputeEngine
NB a file: codebase cannot work if it refers to a local filesystem, unless the client is also in the same machine, which makes RMI fairly pointless. Codebase URLs need to refer to locations that are accessible by the client. You can use shared file systems but you must provide a URL that is usable by the client. The server doesn't use its own codebase URL at all.
I tried the same and I found that Java simply ignored the policy file, no matter where I put it or what I put into it or which option I used to make the VM pick it up.
In the end, I create my own SecurityManager in the code and did everything manually.

Categories

Resources