[GLASSFISH-15119] CDI Interceptor still not working in OSGi Created: 12/Dec/10  Updated: 25/Mar/13

Status: Open
Project: glassfish
Component/s: cdi, OSGi-JavaEE
Affects Version/s: 3.1_b31
Fix Version/s: future release

Type: Bug Priority: Major
Reporter: chaoslayer Assignee: mtaube
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Tested with promoted b32


Attachments: GZip Archive interceptor-osgi-test-2-fixed.tar.gz     GZip Archive interceptor-osgi-test-2.tar.gz     File interceptor-osgi-test.tar.bz2    
Issue Links:
Dependency
depends on GLASSFISH-15249 Support vanilla OSGi bundles as bean ... Open
Tags: 3_1-exclude, 3_1-next, 3_1_1-scrubbed

 Description   

I just revisited GLASSFISH-13513 and GLASSFISH-14831 to see if it is possible to plug in interceptors the CDI way around EJBs.

Indeed when deploying a prepared package as non-OSGi the interceptor gets invoked but not when using OSGi deployment.

Therefore I made up another test case which should be sufficient for a confirmation of this issue:

  • maven reactor build with 4 modules
  • build.sh script for test:
  • "mvn clean install"
  • copy resulting artifacts into .../autodeploy/bundles/ folder of a running glassfish domain
  • wait for (re-)deployment
  • using "curl" to call the web service
  • search for a fault inside the returned XML

So basically for a test I issue a command like this:

$ GF_DOMAIN_DIR=/srv/servers/gf-3.1-b32/glassfish/domains/domain1/ ./build.sh

Well, I also can say that with the old @Interceptors(

{SecurityInterceptor.class}

) method the interceptor is being called so I suspect it is not injected at all.

This test throws a fault if the interceptor is being invoked. If no fault occurs and the response is valid there must be something wrong.



 Comments   
Comment by chaoslayer [ 12/Dec/10 ]

Thanks for reopening the issue, I was not allowed to.

Comment by Sanjeeb Sahoo [ 14/Dec/10 ]

Assigning this to cdi team after talking to Siva. It is a bug in their layer.

Comment by chaoslayer [ 14/Dec/10 ]

Fixed the project and enabled interceptor class in beans.xml for the user service [interceptor-osgi-test-2-fixed.tar.gz].

Just tested again with a completely clean b32:

INFO: Portable JNDI names for EJB UserServiceImpl : [java:global/org.glassfish.cditest.user.service_2.0.0.SNAPSHOT/UserServiceImpl!org.glassfish.cditest.user.api.UserService, java:global/org.glassfish.cditest.user.service_2.0.0.SNAPSHOT/UserServiceImpl]
INFO: WELD-000900 $

{parsedVersion (osgiVersion}

)
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
SEVERE: Exception while loading the app
INFO: Deleted /tmp/osgiapp5600363451663621402
SEVERE: Failed while deploying bundle org.glassfish.cditest.user.service [252]
WARNING: Failed to deploy bundle org.glassfish.cditest.user.service [252]
org.glassfish.osgijavaeebase.DeploymentException: Deployment of org.glassfish.cditest.user.service [252] failed because of following reason: Failed while deploying bundle org.glassfish.cditest.user.service [252] : java.lang.RuntimeException: Failed to deploy bundle [ org.glassfish.cditest.user.service [252] ], root cause: Exception while loading the app
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.deploy(AbstractOSGiDeployer.java:125)
at org.glassfish.osgijavaeebase.OSGiContainer.deploy(OSGiContainer.java:147)
at org.glassfish.osgijavaeebase.JavaEEExtender.deploy(JavaEEExtender.java:132)
at org.glassfish.osgijavaeebase.JavaEEExtender.handleEvent(JavaEEExtender.java:117)
at org.glassfish.osgijavaeebase.JavaEEExtender.access$000(JavaEEExtender.java:56)
at org.glassfish.osgijavaeebase.JavaEEExtender$1.run(JavaEEExtender.java:100)
Caused by: java.lang.RuntimeException: Failed to deploy bundle [ org.glassfish.cditest.user.service [252] ], root cause: Exception while loading the app
at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.deploy(OSGiDeploymentRequest.java:196)
at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.execute(OSGiDeploymentRequest.java:118)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.deploy(AbstractOSGiDeployer.java:121)
... 5 more
Caused by: org.glassfish.deployment.common.DeploymentException: WELD-001417 Enabled interceptor class <class>org.glassfish.cditest.security.interceptor.SecurityInterceptor</class> in bundle://252.0:1/META-INF/beans.xml@8 is neither annotated @Interceptor nor registered through a portable extension
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:187)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:302)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.deploy(OSGiDeploymentRequest.java:183)
... 7 more
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001417 Enabled interceptor class <class>org.glassfish.cditest.security.interceptor.SecurityInterceptor</class> in bundle://252.0:1/META-INF/beans.xml@8 is neither annotated @Interceptor nor registered through a portable extension
at org.jboss.weld.bootstrap.Validator.validateEnabledInterceptorClasses(Validator.java:471)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:344)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:383)
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:184)
... 12 more

So I guess it has to do with class visibility here. Although all required classes are visible for the bundle it may once again be a deployment issue:

250|Active | 1|Apache Felix Bundle Repository (1.6.2)
251|Active | 1|OSGi/JTA implementation in GlassFish (3.1.0.b32)
252|Active | 1|User Service OSGi Bundle (2.0.0.SNAPSHOT)
253|Active | 1|User Web Service OSGi Web Service (2.0.0.SNAPSHOT)
254|Active | 1|security.impl OSGi Bundle (2.0.0.SNAPSHOT)
255|Active | 1|security.api OSGi Bundle (2.0.0.SNAPSHOT)
g! inspect p c 255
org.glassfish.cditest.security.api [255] exports packages:
----------------------------------------------------------
org.glassfish.cditest.security.api; version=0.0.0 imported by:
org.glassfish.cditest.user.service [252]
org.glassfish.cditest.security.impl [254]
g! inspect p c 254
org.glassfish.cditest.security.impl [254] exports packages:
-----------------------------------------------------------
org.glassfish.cditest.security.interceptor; version=0.0.0 imported by:
org.glassfish.cditest.user.service [252]
g! inspect p r 252
org.glassfish.cditest.user.service [252] imports packages:
----------------------------------------------------------
javax.ejb; version=3.1.0 -> org.glassfish.javax.ejb [171]
org.glassfish.cditest.security.interceptor; version=0.0.0 -> org.glassfish.cditest.security.impl [254]
org.glassfish.cditest.security.api; version=0.0.0 -> org.glassfish.cditest.security.api [255]

Comment by Sanjeeb Sahoo [ 14/Dec/10 ]

I discussed with our CDI engineer (sivakumar) and he thinks there is more to it than classloading. He thinks this can be reproduced without use of OSGi as well. He is looking into it.

Comment by chaoslayer [ 14/Dec/10 ]

OK, so do you need any additional data from my side?

Comment by Sanjeeb Sahoo [ 14/Dec/10 ]

No, not at this point. We have sufficient information to proceed. Thanks.

Comment by Sanjeeb Sahoo [ 15/Dec/10 ]

Needed for 3.1

Comment by Sivakumar Thyagarajan [ 17/Dec/10 ]

Modified testcase with the following changes:
1. brought the interceptor enablement to security.impl and 2. removed the interceptor enablement in user.impl

The interceptor class is defined in security.impl and must be enabled there.

Comment by Sivakumar Thyagarajan [ 17/Dec/10 ]

While debugging this issue, we noticed that the interceptor was enabled in the user.impl bundle. The interceptor is defined in the security.impl bundle and hence has to be enabled there. Attached the modified test-case that has these changes. With these changes, the 3 bundles deploy in GF3.1 latest trunk.

However there is an issue. GF3.1 considers the first two bundles (security.api and security.impl) as plain vanilla OSGi bundles (not EE archives) and hence are not considered as CDI archives. Furthermore, since there is no "explicit" relationship (apart from the usage of the CDI interceptor binding) between the user.impl and the other two bundles, when the user.impl WAB is deployed, the user.impl WAB "alone" is considered as a CDI archive. The CDI runtime does not have access to the Beans in security.api/security.impl and hence this usecase will not work. GF3.1 CDI-OSGi support should support scenarios where the Beans used by a bundle are in a different bundle and scenarios where Beans could exist in plain vanilla osgi bundles. I have raised a RFE, GLASSFISH-15249, for this and targetted this for 3.2 as it is more involved to be considered for 3.1.

Here are two possible workarounds:

  • One bundle: Bundling all the Beans together in user.impl (ie have one bundle and not 3 bundles) would work. I don't know if this works for you, though.
  • Fragment bundle approach: I had a discussion with Sahoo and he is investigating the use of security.api and security.impl as fragment bundles as a workaround, and he will update this thread with his finding.
Comment by Sivakumar Thyagarajan [ 17/Dec/10 ]

Raised a RFE GLASSFISH-15249 to fix the underlying usecase.

Comment by chaoslayer [ 17/Dec/10 ]

Well, not quite covering our use case scenario. Let me explain what we "want":

  • we have one Security API bundle that contains the @Secure interface
  • we have one or more Security implementation bundles that contain the implementation for @Secure
  • we have around 20 EJB bundles that have to be "secured" via the CDI interceptor binding

So workaround one effectively disables OSGi here completely and pulls in a lot of work todo for our setup, from building to integration testing to deployment.

Option two could be an option, although I think only the bundle that contains the interceptor should be made available as a fragment bundle attaching to all those EJB bundles.

But what happens if not all Fragement-Hosts are available for the interceptor fragment bundle? Is it still resolved for those that are available? The spec is somewhat unclear here. The use case here is of course modularity. As our developers are working in different areas of interest they only use the bundles that they need. Security is a very basic need but should support those scenarios without modification at build time.

Thanks for the RFE, btw.

Comment by Sanjeeb Sahoo [ 17/Dec/10 ]

Yes, I just tried by converting security.impl to be a fragment of user.impl and having the <interceptors> element defined in user.impl's beans.xml. With this, I am able to see the interceptors in action. I realize this is not an optimal solution, but looks like a work around to me.

Comment by Sanjeeb Sahoo [ 17/Dec/10 ]

A fragment can't be attached to more than one host, so there is a potential issue for your use case. Let us think more.

Comment by Sivakumar Thyagarajan [ 17/Dec/10 ]

Marking as "3_1-exclude" and targetting for 3.2

Comment by Sivakumar Thyagarajan [ 06/Jul/11 ]

Marking as 3_1-next as this was targetted for 3.1+ releases

Comment by Sivakumar Thyagarajan [ 08/Jul/11 ]

Marked issue as "Major"

Comment by Sivakumar Thyagarajan [ 15/Oct/12 ]

Moving a fix for this to a "future release" as the dependent issue GLASSFISH-15249 is also moved.

There is a workaround for this issue as Sahoo points out above.

Comment by TangYong [ 15/Oct/12 ]

siva, sahoo,

Please add a osgi-javaee component for the issue.

Comment by TangYong [ 25/Mar/13 ]

Because the bug depends on GLASSFISH-15249 which will be implemented in future release, fix version is adjusted into future release.

Generated at Wed Jul 08 03:32:56 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.