[MGNLADMLEG-50] Generic TreeHandlerManager with @Singleton annotation causes deployment to fail on JEE7 servers using CDI Created: 07/Jan/14  Updated: 28/Jan/14  Resolved: 13/Jan/14

Status: Closed
Project: Admininterface Legacy 4.x (closed)
Component/s: None
Affects Version/s: 5.2, 5.2.1
Fix Version/s: 5.2.2

Type: Bug Priority: Major
Reporter: joshua portway Assignee: Federico Grilli
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Wildfire * / Glassfish 4


Template:
Acceptance criteria:
Empty
Date of First Response:

 Description   

As I describe in this forum posting trying to deploy on Wildfire or Glassfish 4 fails because TreeHandlerManager does not comply with the CDI specification - specifically "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."

On wildfire this is the exception thrown :

13:40:58,453 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-6) MSC000001: Failed to start service jboss.deployment.unit."rocamora2-webapp.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."rocamora2-webapp.war".WeldStartService: Failed to start service
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904) [jboss-msc-1.2.0.CR1.jar:1.2.0.CR1]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_45]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_45]
	at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_45]
Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-000071: Managed bean class info.magnolia.module.admininterface.TreeHandlerManager must be @Dependent
	at org.jboss.weld.bean.ManagedBean.checkType(ManagedBean.java:198)
	at org.jboss.weld.bean.AbstractBean.initializeAfterBeanDiscovery(AbstractBean.java:103)
	at org.jboss.weld.bean.ManagedBean.initializeAfterBeanDiscovery(ManagedBean.java:113)
	at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$AfterBeanDiscoveryInitializerFactory.doWork(ConcurrentBeanDeployer.java:129)
	at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$AfterBeanDiscoveryInitializerFactory.doWork(ConcurrentBeanDeployer.java:120)
	at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
	at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262) [rt.jar:1.7.0_45]
	... 3 more


 Comments   
Comment by joshua portway [ 08/Jan/14 ]

Having thought about this for a bit I've realised that the @Singleton annotation on this class doesn't make much sense to me - since the class is a generic type how does the container know what flavour of the class to inject (i think type erasure will get rid of that information even if the field that it was being injected into was declared with a type).
Is this class actually being injected anywhere anyway? Is that Singleton annotation really used?

Comment by Federico Grilli [ 10/Jan/14 ]

Hi Joshua, thanks for reporting the issue. As to the @Singleton annotation you're right there, and that is going to be removed. I then asked a colleague of mine regarding the @Dependent scope and here is his reply

"Haven't heard of the annotation (@Dependent) before. It appears to be part of CDI (previously WebBeans). A dependency injection container that JBoss developed and managed to get standardized and made part of Java EE. Guice is not an implementation of CDI. The @Inject annotation from javax.inject is not part of CDI. Both Guice and CDI use it though.
In other words, we're not doing anything wrong, but what we're doing violates some kind of requirement in CDI.

Maybe he can try to exclude our classes from being processed by CDI, https://access.redhat.com/site/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/Exclude_Beans_From_the_Scanning_Process.html"

Hope this helps,

Federico

Comment by joshua portway [ 10/Jan/14 ]

Hi Federico,

I'm glad to help.
From memory, the @Dependent annotation basically means that injected objects of a particular class will never be shared. If you annotate a class with @Dependent then whenever it's injected a new instance will be created - because these are basically "private" objects they are "dependent" on the object that created them and are disposed of when that object disappears. This means they don't have to be proxied by CDI, which I think is why it's necessary to declare generic types to be dependent - because CDI can't effectively proxy them. I seem to remember coming across this problem several years ago (before this error message existed) and not being able to understand why my program was failing - it turned out to be that CDI was throwing exceptions when trying to create a proxy object.

Because @Dependent objects can't be shared it makes no sense to declare one to be a Singleton - that's the error you're making here, and that's why CDI is complaining.

Please take all the above with a pinch of salt - I'm trying to remember an obscure bug from several years ago while on a train, and I may be completely wrong - but I hope this helps.

Generated at Sun Feb 11 23:09:06 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.