users@glassfish.java.net

Re: Standalone client, remote class loading issue (FVDCodeBaseImpl.implementation)

From: Ken Cavanaugh <ken.cavanaugh_at_oracle.com>
Date: Tue, 19 Apr 2011 11:14:19 -0700

On Apr 19, 2011, at 10:26 AM, Martin Weber wrote:

> Hi all,
>
> I am experiencing a weird problem while unmarshalling an object that is returned
> from a remote session bean to a standalone client. Both client and EJB code is the
> code from the 'duke´s bank' sample tutorial, with a tiny modification: The returned
> type is declared to be an interface, and the EJB´s method is implemented to return
> a concrete class (CustomerDetailsImpl) that is Serializable and implements the interface.
>
> CustomerDetailsImpl.class is not available on the client´s class path, I expect it to be
> downloaded to the client similar the way RMI handles this case.
>
> When I invoke CustomerController#getDetails() and step through the CORBA layer, I can see
> the method is invoked on the remote bean, and the returned data are going to be
> unmarshalled. The CORBA layer then issues a call to retrieve the class for the returned object (FVDCodeBaseImpl.implementation("RMI:com.sun.tutorial.javaee.dukesbank.server.request.CustomerDetailsImpl:C075DCD787A59291:503990CCF040CEAE"))
> but that call fails on the server side with a ClassNotFoundException.
> This fails with Glassfish V2.1, 3.0.1 and v 3.1.
>
> What am I doing wrong here? Do the EJB specs disallow remote class loading or is it a
> bug in Glassfish ORB?

It's not a bug: the GF ORB as configured in the app server has never supported code downloading.
This was a deliberate decision made many years ago, but I'm not familiar with the EJB specs so
I don't know what the specs say about this.

The problem is that in order for this to work, there must be a codebase (string of URLs) associated with
the valuetype that points to an HTTP server that can provide the class on request. We don't supply this.
The ORB actually supports code downloading (just as RMI does), but we don't enable this in GF.

Ken.

>
> Thanks for any advice,
> Martin
>
>
> # Java Code ######################################################
> --- EJB API as seen by client code (truncated)
> CustomerController.java
>
> public interface CustomerController {
> CustomerDetails getDetails(Long customerId) throws CustomerNotFoundException, InvalidParameterException;
> }
>
> CustomerDetails.java
>
> public interface CustomerDetails {
> ... lots of getters and setters
> }
>
> --- EJB implementation (truncated)
> @Stateless
> @Remote(value = { CustomerController.class })
> public class CustomerControllerBean implements CustomerController {
> public CustomerDetails getDetails(Long customerId){
> return new new CustomerDetailsImpl(...);
>
> /*package*/ class CustomerDetailsImpl implements java.io.Serializable, CustomerDetails {
> ... lots of getters and setters
> }
>
> # Stack trace ######################################################
> Exception in thread "AWT-EventQueue-0" javax.ejb.EJBException: java.rmi.RemoteException: CORBA NO_IMPLEMENT 1398079489 Maybe; nested exception is:
> org.omg.CORBA.NO_IMPLEMENT: ----------BEGIN server-side stack trace----------
> org.omg.CORBA.NO_IMPLEMENT: WARNUNG: IOP01000001: Missing local value implementation vmcid: SUN minor code: 1 completed: Maybe
> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
> at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
> at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
> at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
> at com.sun.corba.ee.spi.orbutil.logex.corba.CorbaExtension.makeException(CorbaExtension.java:248)
> at com.sun.corba.ee.spi.orbutil.logex.corba.CorbaExtension.makeException(CorbaExtension.java:95)
> at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator.handleFullLogging(WrapperGenerator.java:387)
> at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator.access$400(WrapperGenerator.java:107)
> at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator$2.invoke(WrapperGenerator.java:511)
> at com.sun.corba.ee.spi.orbutil.proxy.CompositeInvocationHandlerImpl.invoke(CompositeInvocationHandlerImpl.java:99)
> at $Proxy130.missingLocalValueImpl(Unknown Source)
> at com.sun.corba.ee.impl.io.FVDCodeBaseImpl.implementation(FVDCodeBaseImpl.java:113)
> at com.sun.org.omg.SendingContext._CodeBaseImplBase._invoke(_CodeBaseImplBase.java:99)
> at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:528)
> at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:199)
> at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1624)
> at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1486)
> at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:990)
> at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:214)
> at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:742)
> at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:539)
> at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2324)
> at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
> at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
> Caused by: java.lang.ClassNotFoundException: com.sun.tutorial.javaee.dukesbank.server.request.CustomerDetailsImpl
> at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
> at java.security.AccessController.doPrivileged(Native Method)
> at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
> at java.lang.Class.forName0(Native Method)
> at java.lang.Class.forName(Class.java:247)
> at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:434)
> at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
> at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
> at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:202)
> at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:135)
> at com.sun.corba.ee.impl.util.JDKBridge.loadClassM(JDKBridge.java:319)
> at com.sun.corba.ee.impl.util.JDKBridge.loadClass(JDKBridge.java:228)
> at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.loadClass(Util.java:640)
> at com.sun.corba.ee.impl.util.RepositoryId.getClassFromType(RepositoryId.java:577)
> at com.sun.corba.ee.impl.io.ValueHandlerImpl.getClassFromType(ValueHandlerImpl.java:373)
> at com.sun.corba.ee.impl.io.FVDCodeBaseImpl.implementation(FVDCodeBaseImpl.java:105)
> ... 12 more
>
> ----------END server-side stack trace---------- vmcid: SUN minor code: 1 completed: Maybe
> at com.sun.tutorial.javaee.dukesbank.api._CustomerController_Wrapper.getDetails(com/sun/tutorial/javaee/dukesbank/api/_CustomerController_Wrapper.java)
> at com.sun.tutorial.javaee.dukesbank.client.BankAdmin.customerOpenButtonMouseReleased(BankAdmin.java:1308)
>
>
> --
> E-Mails sollten Text sein, Text und nur Text.
> Wenn Gott gewollt hätte, dass E-Mails in HTML geschrieben würden,
> endeten Gebete traditionell mit </amen>.