Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 442764 - [RemoteService] CNFE Class cannot be found when using DI and remote services
Summary: [RemoteService] CNFE Class cannot be found when using DI and remote services
Status: CLOSED DUPLICATE of bug 442811
Alias: None
Product: ECF
Classification: RT
Component: ecf.remoteservices (show other bugs)
Version: 3.9.0   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: ecf.core-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-08-28 04:01 EDT by Wim Jongman CLA
Modified: 2014-08-28 11:26 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wim Jongman CLA 2014-08-28 04:01:57 EDT
An error occures when the provider (ECF) creates tries to create a proxy service of a class then the consumer does not know. The consumer is Eclipse DI.

With Eclipse E4, the following construct is possible:

class MyView {
  @Inject @Optional
  IRunControllerService service
}

In the above annotation you tell the Eclipse DI framework to inject the instance of the IRCS service into instances of MyView.

If an instance of the specific service is found by the DI framework, it is placed in the "context" (DI goodybag hashmap.) From this context the requesting classes are visited and the service is injected into MyView.

I Think this is what happens.

1. The above MyView instance is created by the DI framework.
2. DI sees that MyView wants the IRCS service and tracks this service
3. ECF creates a proxy for this service when a remote service appears
4. ECF sees that the Eclipse DI bundle wants the service and uses its bundle
   to instantiate the object.
5. The IRCS is not in the dependencies of the DI framework so the class 
   cannot be found

Stack trace:

java.version=1.7.0_60
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=en_US
Framework arguments:  -product ln.ont.sdaorj.gui.product -clearPersistedState
Command-line arguments:  -product ln.ont.sdaorj.gui.product -data O:\/../runtime-ln.ont.sdaorj.client.product -dev file:O:/.metadata/.plugins/org.eclipse.pde.core/ln.ont.sdaorj.client.product/dev.properties -os win32 -ws win32 -arch x86 -consoleLog -clearPersistedState -console

!ENTRY org.eclipse.e4.ui.workbench 1 0 2014-08-27 14:38:17.122
!MESSAGE LifeCycleManager - Eclipse context registered @lifecyclemanager
INFO - RemoteBroker - Remote Broker constructed
INFO - RemoteBroker - Remote broker: service trackers active
INFO - HostConfigurationManager - Creating host configuration manager
INFO - Class - Service ln.ont.sdaorj.services.IHostConnectionService.proxy@org.eclipse.ecf.remoteservice.RemoteServiceID[containerID=StringID[ecftcp://192.168.192.85:3787/server];containerRelativeID=1] from Name arrived at remote broker

!ENTRY org.eclipse.ecf.osgi.services.remoteserviceadmin 4 0 2014-08-27 14:38:39.746
!MESSAGE org.eclipse.core.runtime.Status[plugin=org.eclipse.ecf.osgi.services.remoteserviceadmin;code=4;message=org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin:loadInterfacesViaBundle:interface=ln.ont.sdaorj.services.simulation.IRunControllerService cannot be loaded by clientBundle=org.eclipse.e4.ui.workbench;severity4;exception=java.lang.ClassNotFoundException: ln.ont.sdaorj.services.simulation.IRunControllerService cannot be found by osgi.identity; osgi.identity="org.eclipse.e4.ui.workbench"; type="osgi.bundle"; version:Version="1.1.0.v20140228-1539"; singleton:="true";children=[]]
!STACK 0
java.lang.ClassNotFoundException: ln.ont.sdaorj.services.simulation.IRunControllerService cannot be found by osgi.identity; osgi.identity="org.eclipse.e4.ui.workbench"; type="osgi.bundle"; version:Version="1.1.0.v20140228-1539"; singleton:="true"
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:416)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:336)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:328)
    at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:160)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:568)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.loadServiceInterfacesViaBundle(RemoteServiceAdmin.java:1635)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.createProxy(RemoteServiceAdmin.java:1694)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.access$5(RemoteServiceAdmin.java:1685)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin$ProxyServiceFactory.getService(RemoteServiceAdmin.java:1670)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse$1.run(ServiceFactoryUse.java:212)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.factoryGetService(ServiceFactoryUse.java:210)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.getService(ServiceFactoryUse.java:111)
    at org.eclipse.osgi.internal.serviceregistry.ServiceConsumer$2.getService(ServiceConsumer.java:45)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:489)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.getService(ServiceRegistry.java:461)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:619)
    at org.eclipse.e4.core.internal.contexts.osgi.EclipseContextOSGi.serviceChanged(EclipseContextOSGi.java:120)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:109)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:914)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:862)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:801)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:127)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:225)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.registerService(BundleContextImpl.java:464)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin$10.run(RemoteServiceAdmin.java:1569)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin$10.run(RemoteServiceAdmin.java:1)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.createAndRegisterProxy(RemoteServiceAdmin.java:1567)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.importService(RemoteServiceAdmin.java:2134)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.importService(RemoteServiceAdmin.java:423)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.AbstractTopologyManager.handleECFEndpointAdded(AbstractTopologyManager.java:244)
    at org.eclipse.ecf.internal.osgi.services.distribution.BasicTopologyManagerImpl.endpointAdded(BasicTopologyManagerImpl.java:123)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.EndpointDescriptionLocator$1.dispatchEvent(EndpointDescriptionLocator.java:156)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
DEBUG - StartScenarioHandler - Run controller service registered @ StartScenarioHandler
DEBUG - AsFastAsPossibleHandler - Run controller service registered @ AsFastAsPossibleHandler
DEBUG - PauseScenarioHandler - Run controller service registered @ PauseScenarioHandler
DEBUG - StopScenarioHandler - Run controller service registered @ StopScenarioHandler
DEBUG - ScenarioTimeVisualizer - Run controller service registered @ ScenarioTimeVisualizer

!ENTRY org.eclipse.ecf.osgi.services.remoteserviceadmin.proxyDEBUG - ScenarioSpeedSlider - Run controller service registered @ ScenarioSpeedSlider
 4 0 2014-08-27 14:38:39.752
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.ServiceException: Exception in org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin$ProxyServiceFactory.getService()
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.factoryGetService(ServiceFactoryUse.java:222)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.getService(ServiceFactoryUse.java:111)
    at org.eclipse.osgi.internal.serviceregistry.ServiceConsumer$2.getService(ServiceConsumer.java:45)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:489)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.getService(ServiceRegistry.java:461)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.getService(BundleContextImpl.java:619)
    at org.eclipse.e4.core.internal.contexts.osgi.EclipseContextOSGi.serviceChanged(EclipseContextOSGi.java:120)
    at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:109)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:914)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:862)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:801)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:127)
    at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:225)
    at org.eclipse.osgi.internal.framework.BundleContextImpl.registerService(BundleContextImpl.java:464)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin$10.run(RemoteServiceAdmin.java:1569)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin$10.run(RemoteServiceAdmin.java:1)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.createAndRegisterProxy(RemoteServiceAdmin.java:1567)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.importService(RemoteServiceAdmin.java:2134)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.importService(RemoteServiceAdmin.java:423)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.AbstractTopologyManager.handleECFEndpointAdded(AbstractTopologyManager.java:244)
    at org.eclipse.ecf.internal.osgi.services.distribution.BasicTopologyManagerImpl.endpointAdded(BasicTopologyManagerImpl.java:123)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.EndpointDescriptionLocator$1.dispatchEvent(EndpointDescriptionLocator.java:156)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
Caused by: java.lang.RuntimeException: ProxyServiceFactory cannot load any serviceInterfaces=[] for serviceReference={ln.ont.sdaorj.services.simulation.IRunControllerService}={endpoint.service.id=208, HOST_NAME=Name, service.scope=bundle, HOST_PORT=3787, service.bundleid=7, endpoint.id=5f790ac2-681b-4fe6-9fd8-b9359e2b70dd, service.imported=org.eclipse.ecf.provider.remoteservice.generic.RemoteServiceImpl@c7ed08, service.imported.configs=[ecf.generic.client], HOST_IP=192.168.192.85, service.id=211} via clientBundle=org.eclipse.e4.ui.workbench
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.createProxy(RemoteServiceAdmin.java:1700)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.access$5(RemoteServiceAdmin.java:1685)
    at org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin$ProxyServiceFactory.getService(RemoteServiceAdmin.java:1670)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse$1.run(ServiceFactoryUse.java:212)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.osgi.internal.serviceregistry.ServiceFactoryUse.factoryGetService(ServiceFactoryUse.java:210)
    ... 26 more
INFO - Class - Service ln.ont.sdaorj.services.simulation.IRunControllerService.proxy@org.eclipse.ecf.remoteservice.RemoteServiceID[containerID=StringID[ecftcp://192.168.192.85:3787/server];containerRelativeID=2] from Name arrived at remote broker
INFO - Class - Service ln.ont.sdaorj.services.simulation.IPlatformDataService$IExtendedPlatformDataService.proxy@org.eclipse.ecf.remoteservice.RemoteServiceID[containerID=StringID[ecftcp://192.168.192.85:3787/server];containerRelativeID=3] from Name arrived at remote broker
INFO - Class - Service ln.ont.sdaorj.services.simulation.ISystemTrackDataService$IExtendedSystemTrackDataService.proxy@org.eclipse.ecf.remoteservice.RemoteServiceID[containerID=StringID[ecftcp://192.168.192.85:3787/server];containerRelativeID=4] from Name arrived at remote broker
INFO - Class - Service ln.ont.sdaorj.services.simulation.IEngagementDataService$IExtendedEngagementDataService.proxy@org.eclipse.ecf.remoteservice.RemoteServiceID[containerID=StringID[ecftcp://192.168.192.85:3787/server];containerRelativeID=5] from Name arrived at remote broker

osgi> ss sdaorj
"Framework is launched."


id    State       Bundle
4    ACTIVE      ln.ont.sdaorj.gui_1.0.0.qualifier
12    ACTIVE      ln.ont.sdaorj.scenario.runcontroller_1.0.0.qualifier
30    ACTIVE      ln.ont.sdaorj.remotebroker_3.0.0.qualifier
33    RESOLVED    ln.ont.sdaorj.libraries_1.0.0
46    STARTING    ln.ont.sdaorj.messaging_4.0.0.qualifier
47    RESOLVED    ln.ont.sdaorj.services_1.0.0.qualifier
58    RESOLVED    ln.ont.sdaorj.common_1.0.0.qualifier
76    RESOLVED    ln.ont.sdaorj.data_1.0.0.qualifier
84    ACTIVE      ln.ont.sdaorj.connection.controls_1.0.0.qualifier
Comment 1 Wim Jongman CLA 2014-08-28 04:05:00 EDT
Workaround
In order to solve this they have found the following workaround.

Make a new interface ILocalRemoteControllerService extends IRemoteControllerService

1. Let MyView use ILRCS for its DI
2. Track IRCS yourself
3. Wrap it in an ILRCS instance
4. Put ILRCS in the context
5. Let DI give it to MyView
Comment 2 Wim Jongman CLA 2014-08-28 04:06:18 EDT
t is an interesting problem and I wonder how it could be solved. ECF fails to load the class because it is using the classloader of the request bundle (Eclipse DI). If ECF fails to load the class at this point it should fall back to some alternative methods of loading the class.

There are two solutions that spring to mind:

1. When the class cannot be loaded, ECF looks inside OSGi to fiind who is _importing_ the package of this class and use that bundle to load the class.

2. Let the consumer register a special factory that can provide instances of this class
Comment 3 Scott Lewis CLA 2014-08-28 10:27:00 EDT
(In reply to Wim Jongman from comment #2)
> t is an interesting problem and I wonder how it could be solved. ECF fails
> to load the class because it is using the classloader of the request bundle
> (Eclipse DI). If ECF fails to load the class at this point it should fall
> back to some alternative methods of loading the class.
> 
> There are two solutions that spring to mind:
> 
> 1. When the class cannot be loaded, ECF looks inside OSGi to fiind who is
> _importing_ the package of this class and use that bundle to load the class.


This is going to be very tricky to get right, however.   The reason I say this is that there are 

a) potentially many other importers of a given service type...how to know the right/compatible one?

b) service type versions - i.e. there can be multiple versions of a given service type...and it will be difficult to figure out which of several versions is the 'right' one.

c) security/permissions.  The non-requester importers may have fewer/different permissions for accessing packages...and either way they may be incorrect for the actual target.

In any event, this strategy has got some hard questions associated with it.
Comment 4 Wim Jongman CLA 2014-08-28 10:31:43 EDT
(In reply to Scott Lewis from comment #3)
> In any event, this strategy has got some hard questions associated with it.

I agree. What do you think about the second option to let the user supply a service that can create instances of the specified type?
Comment 5 Scott Lewis CLA 2014-08-28 10:50:13 EDT
(In reply to Wim Jongman from comment #4)
> (In reply to Scott Lewis from comment #3)
> > In any event, this strategy has got some hard questions associated with it.
> 
> I agree. What do you think about the second option to let the user supply a
> service that can create instances of the specified type?

I don't understand what you are suggesting.   Do you mean an ECF RSA-specific whiteboard service to load classes of certain name (+version)?   If that's right, wouldn't E4 have to then add code specifically to use it?

Given Alex's email about E4 internals, it would seem easier to me to just have E4 use the originating bundle's BundleContext for doing the OSGi service lookup via ServiceTracker.   Then it would work with any spec-compliant RSA implementation also (not that I'm that concerned about that for E4 :).
Comment 6 Wim Jongman CLA 2014-08-28 10:56:26 EDT
(In reply to Scott Lewis from comment #5)

> 
> Given Alex's email about E4 internals, it would seem easier to me to just
> have E4 use the originating bundle's BundleContext for doing the OSGi
> service lookup via ServiceTracker. 

Yes you are totally right.
Comment 7 Wim Jongman CLA 2014-08-28 11:26:52 EDT

*** This bug has been marked as a duplicate of bug 442811 ***