Hello there,

it seems that service invocation over an RMI binding in Tuscany 1.6 does not go
with the best practice of loading contributions through a dedicated ClassLoader,
and not putting them on the local application classpath.

This is a severe problem that I am afraid could make the RMI binding almost 
useless.

Here’s the background. The symptom of the problem is a stack trace like this 
when
calling a remote service method over an RMI binding:

org.apache.tuscany.sca.host.rmi.RMIHostRuntimeException: error unmarshalling 
return; nested exception is:
      java.lang.ClassNotFoundException: 
com.softwareag.ps.platform.dascomponent.api.DASService (no security manager: 
RMI class loader disabled)
      at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) 
~[na:1.6.0_29]
      at 
org.apache.tuscany.sca.host.rmi.DefaultRMIHost.findService(DefaultRMIHost.java:113)
 ~[tuscany-sca-all-1.7-SNAPSHOT.jar:1.7-SNAPSHOT]
      at 
org.apache.tuscany.sca.host.rmi.ExtensibleRMIHost.findService(ExtensibleRMIHost.java:49)
 ~[tuscany-sca-all-1.7-SNAPSHOT.jar:1.7-SNAPSHOT]
      at 
org.apache.tuscany.sca.binding.rmi.provider.RMIReferenceInvoker.invokeTarget(RMIReferenceInvoker.java:80)
 ~[tuscany-sca-all-1.7-SNAPSHOT.jar:1.7-SNAPSHOT]

The cause of this error is that the stub class must be an instance of a Service 
interface that is part of a contribution.
However, classes loaded as part of a contribution (loaded by the 
ContributionClassLoader) are by definition not
not on the local application classpath and therefore not available to the 
built-in Java implementation of the

RMI sun.rmi.registry.RegistryImpl.

I have tried remedying the situation using the Java remote class loading 
mechanism, with partial success.
I store the contribution with the service interface (DASService in above 
example) in a jar file that is accessible
to the client. I have the remote component set the java.rmi.server.codebase 
property to the URL of that
jar (which couples the launcher code to the binding in the composite, but so be 
it.) On the client side I load the
contribution from the same jar. In addition, I set an RMISecurityManager and a 
user policy that grants all permissions.


So far so good – I now have a remote proxy. However, the attempt does not quite 
work, because methods that have

parameter types which are not on the application classpath cannot be invoked on 
that proxy:

When Tuscany instantiates the stub from the RMI registry it reloads the method 
parameter types NOT using the

ContributionClassLoader for the contribution that contains the remote service. 
So they do not match the parameter types

that are stored in the RMIReferenceInvoker (in the member variable 
“remoteMethod”).

Thus,  RMIReferenceInvoker# invokeTarget() will throw a NoSuchMethodException!



As discussed in another thread, the aforementioned best practice is necessary 
to make contribution exports/imports

work. The problem presented in this post may imply that one is severely limited 
in the method signatures that can be

used over the RMI Binding, to the extent to render the RMI binding almost 
useless.



I guess a way to make this work correctly would be for Tuscany to use its own 
RMI registry implementation, instead of

sun.rmi.registry.RegistryImpl. But that seems pretty radical. Another approach 
might be to change the RMIReferenceInvoker

so that it does not use Class.getMethod() directly but implements a modified 
sort of reflection where the

parameter types are compared by name and not by identity.



Any comments or ideas?



n  Sebastian

IDS Scheer Consulting GmbH
Geschäftsführer/Managing Directors: Kamyar Niroumand, Ivo Totev
Sitz/Registered office: Altenkesseler Straße 17, 66115 Saarbrücken, Germany - 
Registergericht/Commercial register: Saarbrücken HRB 19681
http://www.softwareag.com

Reply via email to