Hello there,
I've seen two phenomena with regard to
a) how Tuscany registers services exposing an RMI binding
and b) how exceptions thrown from these services are handled.
I'm asking for advice if these phenomena are bugs, and whether to file a bug
report at JIRA.
The background is that I have experimented with the currency converter
examples from the turorial to create a service interface and implementation
that can be accessed through web services, RMI and JMS in a uniform manner.
I'm using Tuscany 1.6 and JDK 1.6.0_18 on Windows XP.
-----
ad a) My component definitions says I want to access the service
CurrencyConverterRMI
at the local registry on the default port. Note also that the SCA service name
is different
from the name used in the RMI-binding.
<component name="CurrencyConverter">
<implementation.java
class="com.tuscanyscatours.currencyconverter.impl.CurrencyConverterImpl" />
<service name="CurrencyConverter">
<interface.java
interface="com.tuscanyscatours.currencyconverter.CurrencyConverter" />
<tuscany:binding.rmi host="localhost" port="1099"
serviceName="CurrencyConverterRMI"/>
</service>
</component>
I start the registry server externally (calling rmiregistry.exe in Windows),
and also register the
service through a utility class like this:
Naming.rebind( "//localhost:1099/CurrencyConverterRMI", new
CurrencyConverterImpl() );
Then running the SCA launcher will throw an AlreadyBoundException at
node.start():
SCANode node = SCANodeFactory.newInstance().createSCANode(
"currency-converter-rmi.composite",
currencyContribution, currencyRMIContribution );
node.start();
Is there a reason for this behaviour? Why should an existing service that I
want to wrap in an SCA
composite not be previously registered in the RMI registry? I know that I'm not
talking here about a
binding on a service reference that I use to access an existing RMI service,
but I'm still not sure this
is not a bug. Why should I not be able to execute this launcher multiple times,
or construct multiple nodes
exposing the same services inside the same launcher?
Of course, I can first issue an explicit
Naming.unbind( "//localhost:1099/CurrencyConverterRMI" );
to make the exception go away. However, this is bad because suddenly the RMI
name pops up in my SCA code.
-----
ad b) Having started the registry and registered the service through the Naming
class as described
above, everything works when I access the service through a pure Java RMI
client, even when the
service throws an exception (the exception is a web fault, containing a fault
bean which I have
made serializable so as to be able to pass the whole thing over RMI as well).
Registry registry = LocateRegistry.getRegistry( "localhost" );
CurrencyConverter converter = (CurrencyConverter) registry.lookup(
"CurrencyConverterRMI" );
try
{
System.out.println( "ExchangeRate = " + converter.getExchangeRate( "XYZ",
"GBP" ) );
}
catch( CurrencyConverterFault_Exception e ) // expected exception
{
System.out.println( e.getFaultInfo().getMessage() );
}
The error occurs when I start the service using the SCA launcher. I construct
and start a node, and
obtain the service interface through the following line:
CurrencyConverter converter =
((SCAClient) node).getService( CurrencyConverter.class,
"CurrencyConverter" );
Now the call to converter.getExchangeRate() will give an UnexpectedException.
Interestingly, having the started and registered the service this way, also the
pure Java RMI
client will get the same exception, so I suspect the cause may have something
to do with
how the service is registered.
Or maybe it has to do with how classes are loaded, because the underlying cause
for the UnexpectedException
is an InvocationtargetException that occurs because the
java.rmi.server.RemoteObjectInvocationHandler thinks
that no declared exception type is assignable from the thrown exception type.
Adding -Djava.rmi.server.codebase
to the JVM arguments and pointing it to the directory where the service
implementation classes reside did not
help.
There seems to be a related bug
https://issues.apache.org/jira/browse/TUSCANY-2406
which was fixed by Raymond Feng in 24/Jun/08 12:31 PM.
-- Sebastian
PS: Due to lack of experience, I have not been able to construct a JUnit test
case, but I could provide the
zipped Eclipse projects (57KB) if someone is interested.