Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@OsgiServiceProvider: ClassCastException with parameterized service types [PAXCDI-164] #123

Open
ops4j-issues opened this issue Apr 7, 2015 · 7 comments
Labels
Milestone

Comments

@ops4j-issues
Copy link

Florian Brunner created PAXCDI-164

@OsgiServiceProvider should support services implementing parameterized interfaces:

@OsgiServiceProvider
public class SomeServiceImpl implements SomeService<SomeType> {

The current exception is:

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class
	at org.ops4j.pax.cdi.extension.impl.component.ComponentLifecycleManager.getTypeNamesForBeanTypes(ComponentLifecycleManager.java:215)
	at org.ops4j.pax.cdi.extension.impl.component.ComponentLifecycleManager.registerService(ComponentLifecycleManager.java:184)
	at org.ops4j.pax.cdi.extension.impl.component.ComponentLifecycleManager.start(ComponentLifecycleManager.java:107)
	at org.ops4j.pax.cdi.extension.impl.component.ComponentLifecycleManager$Proxy$_$$_WeldClientProxy.start(Unknown Source)
	at org.ops4j.pax.cdi.extension.impl.BeanBundleImpl.onInitialized(BeanBundleImpl.java:60)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:89)
	at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:79)
	at org.jboss.weld.injection.ObserverMethodInvocationStrategy$2.notify(ObserverMethodInvocationStrategy.java:89)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:299)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:284)
	at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:262)
	at org.jboss.weld.event.ObserverNotifier.notifySyncObservers(ObserverNotifier.java:217)
	at org.jboss.weld.event.ObserverNotifier.notify(ObserverNotifier.java:204)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:120)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:110)
	at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:675)
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer$1.call(AbstractCdiContainer.java:155)
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer$1.call(AbstractCdiContainer.java:147)
	at org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer.finishStartup(AbstractCdiContainer.java:146)
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer.start(AbstractCdiContainer.java:91)
	at org.ops4j.pax.cdi.extender.impl.CdiExtender.createContainer(CdiExtender.java:152)
	at org.ops4j.pax.cdi.extender.impl.CdiExtender.addingBundle(CdiExtender.java:106)
	at org.ops4j.pax.cdi.extender.impl.CdiExtender.addingBundle(CdiExtender.java:53)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:469)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:415)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
	at org.osgi.util.tracker.BundleTracker.open(BundleTracker.java:156)
	at org.ops4j.pax.cdi.extender.impl.CdiExtender.activate(CdiExtender.java:79)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.apache.felix.scr.impl.helper.BaseMethod.invokeMethod(BaseMethod.java:231)
	at org.apache.felix.scr.impl.helper.BaseMethod.access$500(BaseMethod.java:39)
	at org.apache.felix.scr.impl.helper.BaseMethod$Resolved.invoke(BaseMethod.java:624)
	at org.apache.felix.scr.impl.helper.BaseMethod.invoke(BaseMethod.java:508)
	at org.apache.felix.scr.impl.helper.ActivateMethod.invoke(ActivateMethod.java:149)
	at org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:315)
	at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:127)
	at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:871)
	at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:838)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:850)
	at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.addedService(DependencyManager.java:931)
	at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.addedService(DependencyManager.java:895)
	at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.customizerAdded(ServiceTracker.java:1480)
	at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.customizerAdded(ServiceTracker.java:1401)
	at org.apache.felix.scr.impl.manager.ServiceTracker$AbstractTracked.trackAdding(ServiceTracker.java:1210)
	at org.apache.felix.scr.impl.manager.ServiceTracker$AbstractTracked.track(ServiceTracker.java:1148)
	at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.serviceChanged(ServiceTracker.java:1432)
	at org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:987)
	at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:838)
	at org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:545)
	at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4547)
	at org.apache.felix.framework.Felix.registerService(Felix.java:3521)
	at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:350)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:1003)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:992)
	at org.apache.felix.scr.impl.manager.RegistrationManager.changeRegistration(RegistrationManager.java:134)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.registerService(AbstractComponentManager.java:1044)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:841)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:419)
	at org.apache.felix.scr.impl.config.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:376)
	at org.apache.felix.scr.impl.BundleComponentActivator.initialize(BundleComponentActivator.java:172)
	at org.apache.felix.scr.impl.BundleComponentActivator.<init>(BundleComponentActivator.java:120)
	at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:258)
	at org.apache.felix.scr.impl.Activator.access$000(Activator.java:45)
	at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:185)
	at org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:259)
	at org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:232)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:479)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:414)
	at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232)
	at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:443)
	at org.apache.felix.framework.util.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:913)
	at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:834)
	at org.apache.felix.framework.util.EventDispatcher.fireBundleEvent(EventDispatcher.java:516)
	at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4531)
	at org.apache.felix.framework.Felix.startBundle(Felix.java:2169)
	at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1368)
	at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:308)
	at java.lang.Thread.run(Thread.java:745)

ERROR: org.ops4j.pax.cdi.extender (39): [org.ops4j.pax.cdi.extender.impl.CdiExtender(33)] The activate method has thrown an exception
org.ops4j.lang.Ops4jException: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer.finishStartup(AbstractCdiContainer.java:178)
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer.start(AbstractCdiContainer.java:91)
	at org.ops4j.pax.cdi.extender.impl.CdiExtender.createContainer(CdiExtender.java:152)
	at org.ops4j.pax.cdi.extender.impl.CdiExtender.addingBundle(CdiExtender.java:106)
	at org.ops4j.pax.cdi.extender.impl.CdiExtender.addingBundle(CdiExtender.java:53)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:469)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:415)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
	at org.osgi.util.tracker.BundleTracker.open(BundleTracker.java:156)
	at org.ops4j.pax.cdi.extender.impl.CdiExtender.activate(CdiExtender.java:79)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.apache.felix.scr.impl.helper.BaseMethod.invokeMethod(BaseMethod.java:231)
	at org.apache.felix.scr.impl.helper.BaseMethod.access$500(BaseMethod.java:39)
	at org.apache.felix.scr.impl.helper.BaseMethod$Resolved.invoke(BaseMethod.java:624)
	at org.apache.felix.scr.impl.helper.BaseMethod.invoke(BaseMethod.java:508)
	at org.apache.felix.scr.impl.helper.ActivateMethod.invoke(ActivateMethod.java:149)
	at org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:315)
	at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:127)
	at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:871)
	at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:838)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:850)
	at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.addedService(DependencyManager.java:931)
	at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.addedService(DependencyManager.java:895)
	at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.customizerAdded(ServiceTracker.java:1480)
	at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.customizerAdded(ServiceTracker.java:1401)
	at org.apache.felix.scr.impl.manager.ServiceTracker$AbstractTracked.trackAdding(ServiceTracker.java:1210)
	at org.apache.felix.scr.impl.manager.ServiceTracker$AbstractTracked.track(ServiceTracker.java:1148)
	at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.serviceChanged(ServiceTracker.java:1432)
	at org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:987)
	at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:838)
	at org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:545)
	at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4547)
	at org.apache.felix.framework.Felix.registerService(Felix.java:3521)
	at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:350)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:1003)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:992)
	at org.apache.felix.scr.impl.manager.RegistrationManager.changeRegistration(RegistrationManager.java:134)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.registerService(AbstractComponentManager.java:1044)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:841)
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:419)
	at org.apache.felix.scr.impl.config.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:376)
	at org.apache.felix.scr.impl.BundleComponentActivator.initialize(BundleComponentActivator.java:172)
	at org.apache.felix.scr.impl.BundleComponentActivator.<init>(BundleComponentActivator.java:120)
	at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:258)
	at org.apache.felix.scr.impl.Activator.access$000(Activator.java:45)
	at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:185)
	at org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:259)
	at org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:232)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:479)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:414)
	at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232)
	at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:443)
	at org.apache.felix.framework.util.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:913)
	at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:834)
	at org.apache.felix.framework.util.EventDispatcher.fireBundleEvent(EventDispatcher.java:516)
	at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4531)
	at org.apache.felix.framework.Felix.startBundle(Felix.java:2169)
	at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1368)
	at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:308)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class
	at org.ops4j.pax.cdi.extension.impl.component.ComponentLifecycleManager.getTypeNamesForBeanTypes(ComponentLifecycleManager.java:215)
	at org.ops4j.pax.cdi.extension.impl.component.ComponentLifecycleManager.registerService(ComponentLifecycleManager.java:184)
	at org.ops4j.pax.cdi.extension.impl.component.ComponentLifecycleManager.start(ComponentLifecycleManager.java:107)
	at org.ops4j.pax.cdi.extension.impl.component.ComponentLifecycleManager$Proxy$_$$_WeldClientProxy.start(Unknown Source)
	at org.ops4j.pax.cdi.extension.impl.BeanBundleImpl.onInitialized(BeanBundleImpl.java:60)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:89)
	at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:79)
	at org.jboss.weld.injection.ObserverMethodInvocationStrategy$2.notify(ObserverMethodInvocationStrategy.java:89)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:299)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:284)
	at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:262)
	at org.jboss.weld.event.ObserverNotifier.notifySyncObservers(ObserverNotifier.java:217)
	at org.jboss.weld.event.ObserverNotifier.notify(ObserverNotifier.java:204)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:120)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:110)
	at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:675)
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer$1.call(AbstractCdiContainer.java:155)
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer$1.call(AbstractCdiContainer.java:147)
	at org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
	at org.ops4j.pax.cdi.spi.AbstractCdiContainer.finishStartup(AbstractCdiContainer.java:146)
	... 63 more

Affects: 0.11.0
Fixed in: 1.1.4
Votes: 0, Watches: 2

@ops4j-issues
Copy link
Author

@ops4j-issues
Copy link
Author

Florian Brunner commented

A pull request fixing this issue is available here: #16

@ops4j-issues
Copy link
Author

Harald Wellmann commented

I can't merge the pull request without tests.

Besides, it seems you only addressed the producer side which is easy. The consumer side is a bit harder, i.e. making sure that this works:

@Inject
@OsgiService
private SomeService<SomeType> myService;

@ops4j-issues
Copy link
Author

Florian Brunner commented

I've provided the tests (including consumer side): https://github.com/ops4j/org.ops4j.pax.cdi/pull/16/files

@ops4j-issues
Copy link
Author

Harald Wellmann commented

Yes, there is a test, but this is nowhere near the required coverage.

Take a look at
http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#assignable_parameters

How would you deal with this:

@OsgiServiceProvider
public class MyServiceImpl<Foo> implements MyService<Foo> {...}

@OsgiServiceProvider
public class MyServiceImpl<Foo> implements MyService<Bar> {...}


@Inject
@OsgiService
private MyService ip1;

@Inject
@OsgiService
private MyService<Object> ip2;

@Inject
@OsgiService
private MyService<Foo> ip3;

@Inject
@OsgiService
private MyService<Bar> ip4;

What about parameterized parameters, e.g. MyService<Map<Foo, List<String>>>?

Moreover, according to http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#managed_beans

If the managed bean class is a generic type, it must have scope @Dependent. If a managed bean with a parameterized bean class declares any scope other than @Dependent, the container automatically detects the problem and treats it as a definition error.

Since OSGi service beans have one of the OSGi scopes @SingletonScope, @BundleScoped or @PrototypeScope, parameterized OSGi service beans would be a logical contradiction.

@ops4j-issues
Copy link
Author

Florian Brunner commented

This issue addresses one concrete ClassCastException. There might be a need for follow-up issues to reach full CDI conformity, but the current behavior (ClassCastException) is surely wrong and this patch solves this issue.

I have a concrete need for this: https://github.com/Drombler/drombler-fx/blob/%2337-cdi/drombler-fx-core-docking/src/main/java/org/drombler/fx/core/docking/impl/FXDockableFactory.java

Applying this patch solves the issue without having to fall back to raw types and thus improves the current state of PAX-CDI.

The test and the sample prove this.

@ops4j-issues
Copy link
Author

Florian Brunner commented

I've changed the title of this issue to make it more clear.

@ops4j-issues ops4j-issues added this to the 1.1.4 milestone Feb 24, 2021
@jbonofre jbonofre modified the milestones: 1.1.4, 1.1.5 Mar 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants