RMI call across JVM versions

HI all,

I am trying the Hello World RMI sample. My server is hosted in JVM 1.5 and my client is hosted in JVM 1.4. Technically this should work however I get the following exception

Client exception: java.rmi.UnmarshalException: error unmarshalling return; neste

d exception is:

java.lang.ClassNotFoundException: java.rmi.server.RemoteObjectInvocation

Handler (no security manager: RMI class loader disabled)

java.rmi.UnmarshalException: error unmarshalling return; nested exception is:

java.lang.ClassNotFoundException: java.rmi.server.RemoteObjectInvocation

Handler (no security manager: RMI class loader disabled)

at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)

at Client.main(Client.java:14)

Caused by: java.lang.ClassNotFoundException: java.rmi.server.RemoteObjectInvocat

ionHandler (no security manager: RMI class loader disabled)

at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:371)

at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)

at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:631)

at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:257)

Can anyone provide any inputs on the same?

Thanks in advance.

[1299 byte] By [msdnexperta] at [2007-11-26 19:00:15]
# 1
You should generate stubs for your remote object using the "rmic" compiler.
genadya at 2007-7-9 20:42:17 > top of Java-index,Core,Core APIs...
# 2
You should also add a security manager. Its not optional.
_dnoyeBa at 2007-7-9 20:42:17 > top of Java-index,Core,Core APIs...
# 3
JDK 1.5 automatically generates stub and using rmic is no longer required. Thats what the documentation states.
msdnexperta at 2007-7-9 20:42:17 > top of Java-index,Core,Core APIs...
# 4
> JDK 1.5 automatically generates stub and using rmic> is no longer required. Thats what the documentation> states.Unless you want to interop with 1.4.
genadya at 2007-7-9 20:42:17 > top of Java-index,Core,Core APIs...
# 5

Ive generated a stub via rmic -v1.2. Server stub has been created. However on running client I get the following error

Client exception: java.rmi.UnmarshalException: error unmarshalling return; neste

d exception is:

java.lang.ClassNotFoundException: Server_Stub (no security manager: RMI

class loader disabled)

java.rmi.UnmarshalException: error unmarshalling return; nested exception is:

java.lang.ClassNotFoundException: Server_Stub (no security manager: RMI

class loader disabled)

at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)

at Client.main(Client.java:14)

I have added server.policy file on the server with grant all permissions to the server codebase.

msdnexperta at 2007-7-9 20:42:17 > top of Java-index,Core,Core APIs...
# 6
Hi all,Just figured it out. You need to classpath the server stub at the client. Codebasing doesnt seem to work. Neways any suggestions on codebase options are welcome.
msdnexperta at 2007-7-9 20:42:17 > top of Java-index,Core,Core APIs...
# 7

As _dnoyeB suggested you should use a security manager in order for codebase to work.

If you're new to RMI, read the RMI tutorial at

http://java.sun.com/docs/books/tutorial/rmi/ , it will save you much time.

I've also created some ready-to-use examples (part of the RMI Plug-in for Eclipse), check:

http://www.genady.net/rmi/v20/docs/tutorials/print_server.html

Genady

genadya at 2007-7-9 20:42:17 > top of Java-index,Core,Core APIs...
# 8
Ive added the policy files at client and server end which did not work.
msdnexperta at 2007-7-9 20:42:17 > top of Java-index,Core,Core APIs...
# 9

> Ive added the policy files at client and server end

> which did not work.

Yes but did you add security managers at the client and the server. Can't you see in the stack trace the system is telling you to add a security manager?

try starting your programs with the command line option

-Djava.security.manager

_dnoyeBa at 2007-7-9 20:42:18 > top of Java-index,Core,Core APIs...
# 10

> You should also add a security manager. Its not

> optional.

You may add a security manager. It is not optional if you want to use the codebase feature.

Otherwise it is optional.

If you're not using the codebase feature, both the Registry and the client need the remote interface class and the Stub class and any application classes they depend on, recursively until closure, on their CLASSPATHs.

ejpa at 2007-7-9 20:42:18 > top of Java-index,Core,Core APIs...
# 11

> You may add a security manager. It is not

> optional if you want to use the codebase

> feature.

You are correct. Basically, you need to add a SecurityManager so that JVM will allow to download remote byte codes (stubs refered by codebase) and execute it. Otherwise, by default w/o a SecurityManager, JVM will not trust and execute any remote class files. This holds true for any netwrok-ed Java application, including Applets.

-BJ

Bimalesha at 2007-7-9 20:42:18 > top of Java-index,Core,Core APIs...
# 12

> You are correct. Basically, you need to add a SecurityManager so that JVM

> will allow to download remote byte codes (stubs refered by codebase) and

> execute it. Otherwise, by default w/o a SecurityManager, JVM will not trust

> and execute any remote class files. This holds true for any netwrok-ed

> Java application, including Applets

You are not correct. It's not the JVM, it's RMI in this instance, and the Applet framework in the case of applets. It's not true in general for 'any networked Java application' because only those two frameworks (plus RMI/IIOP, and whatever else I can't think of instantaneously) ever do any remote class loading in the first place, and it is they who make the decision not to load classes without a SecurityManager, not the JVM.

For example, you can do your own remote class loading via URLClassLoader and never encounter the need for a SecurityManager.

> I have added server.policy file on the server with grant all permissions to the server codebase.

This achieves nothing. It's the client that needs the security manager and the permissions in the policy file. The server doesn't need either of them in this case.

But unless you really really need the codebase feature for deployment reasons, don't use it. Just deploy the remote interface, stubs, &c to the clients where they can be found on the classpath.

ejpa at 2007-7-9 20:42:18 > top of Java-index,Core,Core APIs...
# 13

> You are not correct. It's not the JVM, it's RMI in

> this instance, and the Applet framework in the case

> of applets.

btw, RMI is just a "rpc protocol" specification which is implemented by JVM, well the part of JVM responsible for RMI, and even Applet Framework also needs a JVM to do anything meaningful. I meant JVM as a general term w/o being sounding pedantic.

>It's not true in general for 'any

> networked Java application' because only those two

> frameworks (plus RMI/IIOP, and whatever else I can't

> think of instantaneously) ever do any remote class

> loading in the first place, and it is they who

> make the decision not to load classes without a

> SecurityManager, not the JVM.

I invite you to read my post once again and also encourage you to refresh your knowledge of Java Security fundamentals- if you haven't done that lately. I said "by default". The way dynamic class downloading (for stubs referred by CODEBASE) works in RMI is not much different than how it works in Applets or how it should work in another networked application which wants to leverage the "DEFAULT" dynamic downlaoding of byte codes using RMI. Pls. refer here why dynamic class loading is fraught with security risk and what SecurityManagers achieve. http://www.securingjava.com/chapter-two/chapter-two-7.html

Basically, when JVM starts (even as a RMI client application), there is no security manager (by default) and any class referred outside local classpath and ext mechanims are untrusted and not allowed to execute by JVM. This is due to the way java sandbox has been designed. To by pass this default behavior you install a Security Manager (here RMISecurityManager or your own security mgr etc. whatever) and set certain policy to "program" the sandbox to allow it to execute the remote byte codes downloaded dynamically and let them access your native resource e.g. File System. AFAIK similar mechanisms are employed in EJB applications too. For applets too, the default Applet container (JVM plug-in for browsers) does such things transparently and you could also "sign" the applets to allow Applet Security Manager to "trust" your code and relax the JVM sandbox.

> For example, you can do your own remote class loading

> via URLClassLoader and never encounter the need for a

> SecurityManager.

The way java.net.URLClassLoader is implemented, it uses the AccessControlContext of the executing thread and does not load classes beyond the URL that was specified at the time of creating its instance. Actually, by impelmenting your own Class Loader you can by pass some of the security checks, but, to see whether the Class Loader is allowed to create the class being loaded, SecurityManager has to decide. In RMI, the RMISecurity Manager decides whether a class can be instantiated out of downloaded byte codes. By default, there is no SecurityMgr and it raises the security exception.

> But unless you really really need the codebase

> feature for deployment reasons, don't use it. Just

> deploy the remote interface, stubs, &c to the clients

> where they can be found on the classpath.

Such deployments defeat the very purpose of "dynamically" distributing the client. What happens if you update the server code? Your local files will remain stale unless, you go to every client and submit the updated clint codes manually.

-BJ

Bimalesha at 2007-7-9 20:42:18 > top of Java-index,Core,Core APIs...
# 14
Quoting from JavaDoc of RMISecurityManager:"RMISecurityManager provides an example security manager for use by RMI applications that use downloaded code. RMI's class loader will not download any classes from remote locations if no security manager has been set."-BJ
Bimalesha at 2007-7-9 20:42:18 > top of Java-index,Core,Core APIs...
# 15

Exactly, so we agree, there is no requirement for a security manager when downloading remote code unless you are within an RMI or other framework that enforces such a rule. I re-read your post as requested, and this is still the opposite of what you originally said, i.e. that it is true 'of any networked application'. It's not. You also said 'by default w/o a SecurityManager, JVM will not trust and execute any remote class files', which is also untrue, and you've just provided examples yourself.

> Such deployments defeat the very purpose of "dynamically" distributing the client.

Obviously and trivially true. They prevent it. However if dynamic distribution is not your purpose, don't be forced into it. The OP's original problem was the classical 'can't-find-the-stub' problem, and telling him to implement security managers and a codebase server is not the simplest solution.

You might consider a look at http://www.telekinesis.com.au/wipv3_6/java.rmi.A21 which was technically reviewed within Sun. I think you can take it there are no technical errors in there, at least I haven't heard of any in seven years. As I say in there, get it working first. Codebases are a deployment option, not something to waste development time on.

See also http://www.telekinesis.com.au/wipv3_6/FundamentalNetworkingInJava.A21.

ejpa at 2007-7-9 20:42:22 > top of Java-index,Core,Core APIs...
# 16

I am not very good at English. Pardon me for that as it is not my native tongue. I am confused with your arguments and counter arguments and precisely what point are you trying to convey :-( However, the point I am arguing for is why RMISecurityManager might be necessary in a RMI application and the internal reason for a SecurityManager. My take-aways from this discussion are as follows.

1) RMI Security Manager (RSM) is optional

2) RSM is NEEDED if you want to leverage dynamic stub downloading (through CODEBASE mechanism)

3) RSM ensures that stubs downloaded dynamically by the client can be instantiated w/o a security exception.

4) If stubs are deposited in local classpath, then RSM is not needed

5) SecurityManagers are needed to instantiate a class obtained from "non-trusted" sources

Thanks for pointing me to the resources. I will have a look at them if these titles are available in my country at an affordable price. I checked your profile and like most authors you too could not ignore the opportunity for self eulogizing:-)

Regards,

-BJ

Bimalesha at 2007-7-9 20:42:23 > top of Java-index,Core,Core APIs...
# 17

Your points 1, 2,and 4 are correct, but:

> 3) RSM ensures that stubs downloaded dynamically by the client can be instantiated w/o a security exception.

Not at all. This is a new one and it is not correct. The presence of the RSM allows the RMI class loader in the client to download stubs. Without an RSM there are no downloaded stubs, because the RMI class loader won't download them. Security exceptions don't come into it at all. What you get without an RSM on a stub that is only available dynamically is a ClassNotFoundException, quite a different thing.

> 5) SecurityManagers are needed to instantiate a class

> obtained from "non-trusted" sources

No. Only if the framework says so, e.g. RMI, Applet, ...

You said yourself that you can construct a URLClassLoader that will execute remote code, and you can, without a security manager:

((Runnable)new URLClassLoader(urls).loadClass(className)).run();

You don't need a security manager for that. I would strongly recommend you have one, and I'm sure you agree, and RMI and Applets insist that you have one. But to assert, as you did, that the JVM controls this for you 'for all networked applications' and 'by default', is untrue.

> like most authors you too could not ignore the opportunity for self eulogizing:-)

It's called advertising and it is a business necessity.

ejpa at 2007-7-9 20:42:23 > top of Java-index,Core,Core APIs...
# 18
It is lot clearer and I understand it correctly now.Thanks ejp. -BJMessage was edited by: Bimalesh
Bimalesha at 2007-7-9 20:42:23 > top of Java-index,Core,Core APIs...
# 19

> Codebases are a deployment option, not something to

> waste development time on.

I'd argue about that (please no shouting at me yet). Copying stubs and other required classes between projects is tedious and error prone. Unless you have a very formal development/build process, you will often end up with stubs that don't match the server code or missing required classes. With all the annoyances of using codebase, in the environment where the server and the client projects are being developed separately, IMHO it still has advantage over manually copying the classes.

And if somebody plans to use codebase in deployment, it's better to start using it during development, so potential problems can be discovered early.

genadya at 2007-7-9 20:42:23 > top of Java-index,Core,Core APIs...
# 20

No sweat, it's a matter of opinion. My real point is that if you don't have a deployment reason to use codebase don't be forced into using it. There are tremendous deployment reasons for using it, and in any large-scale system I wouldn't even consider not doing so. But the general trend seen here of 'start a SecurityManager' and 'add a codebase server' just to solve a minor classpath problem is not always the best advice.

ejpa at 2007-7-9 20:42:23 > top of Java-index,Core,Core APIs...
# 21

> No sweat,

Hmm...

> it's a matter of opinion. My real point is

> that if you don't have a deployment reason to use

> codebase don't be forced into using it. There are

> tremendous deployment reasons for using it, and in

> any large-scale system I wouldn't even consider not

> doing so.

So I just add my opinion - if you're going to use codebase, do it early in development so you can catch the problems earlier.

genadya at 2007-7-9 20:42:23 > top of Java-index,Core,Core APIs...