03707: | Component.distributeObject() returns null if called by service proxy |
Category: Component Status: ClosedSeverity: HIGH Reported against release: 0.8 Fixed in release: 0.8.1 (Beta Refresh)
PROBLEM:The developer who reported this defect actually has a service object
that itself attempts to provide a service once it is downloaded into a
client program. When he calls Component.distributeObject(), null is
returned, and he gets an exception when he passes null to
Component.provideService().
Here is the stack trace:
FriendlyDbPluginImpl Exception =
net.openwings.component.InvalidServiceException: Service Object does
not implement service interface.
net.openwings.component.InvalidServiceException: Service Object does
not implement service interface.
at
com.mot.openwings.component.jini.JiniComponent.provideServiceCheck
(JiniComponent.java:666)
at com.mot.openwings.component.jini.JiniComponent.provideService
(JiniComponent.java:254)
at com.mot.dcgs.friendly.dbplugin.FriendlyDbPluginImpl.init
(FriendlyDbPluginImpl.java:64)
at com.mot.c4i.dbpluginctrl.DbPluginTree.addPlugin
(DbPluginTree.java:221)
at com.mot.c4i.dbpluginctrl.DbPluginTree.serviceProvided
(DbPluginTree.java:129)
at
com.mot.openwings.component.jini.UseServiceManager$LookupCacheHolder.ser
viceAdded(UseServiceManager.java:1009)
at
net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl.serviceNotifyDo
(ServiceDiscoveryManager.java:1156)
at
net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl.addServiceNotify
(ServiceDiscoveryManager.java:1122)
at
net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl.addService
(ServiceDiscoveryManager.java:1061)
at
net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl.access$8
(ServiceDiscoveryManager.java:1051)
at
net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl$NotifyEventTask.
exec(ServiceDiscoveryManager.java:546)
at
net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl.execTasks
(ServiceDiscoveryManager.java:987)
at net.jini.lookup.ServiceDiscoveryManager$TaskThread.run
(ServiceDiscoveryManager.java:330)ANALYSIS:ComponentServices implements Component.distributeObject() by using the
ConnectorLoader to load a connector, and then doing some setup on the
connector (connecting the provider proxy, etc.).
The ConnectorLoader class attempts to load connectors by loading the
connector class and instantiating it. However, it only attempts to load
the class by doing a "Class.forName()". This only checks the class
loader of the calling class, which is the ConnectorLoader class itself.
In most situations, this approach works, since the application,
Component Services, and the ConnectorLoader are all loaded by the same
class loader. This defect uncovers a situation where the
ConnectorLoader is loaded by the main application class loader, and the
connector interface (and in fact the actual connector as well) are in a
URLClassLoader.
The fix is to make the ConnectorLoader do more extensive checking. It
should try two additional different class loaders when searching for
connector classes:
1. The context class loader.
2. The class loader that loaded the connector interface. WORKAROUND:The jar file for the container could be added to the classpath of the
program using the service. Note that this is definitely not a long-term
solution.
|