glassfish
  1. glassfish
  2. GLASSFISH-21125

Weld 2.2.2 glassfish integration and Infinispan 7.0 (EJB interceptors bug)

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 4.1_b08
    • Fix Version/s: None
    • Component/s: cdi
    • Labels:
      None
    • Environment:

      4.0.1 build 08 web profile, windows 8.1, JDK 1.8.0_05

      Description

      I have inifinispan (7.0 alpha 4) CDI interceptors in my application, intercepting EJB calls.

      When I upgraded weld to 2.2 I got a deployment error:

      java.lang.IllegalStateException: Interceptor Class class org.infinispan.jcache.annotation.AbstractCacheResultInterceptor has no method annotated with interface javax.interceptor.AroundInvoke
      at org.glassfish.weld.services.EjbServicesImpl.getInterceptorMethod(EjbServicesImpl.java:346)
      at org.glassfish.weld.services.EjbServicesImpl.makeInterceptorChain(EjbServicesImpl.java:282)
      at org.glassfish.weld.services.EjbServicesImpl.registerInterceptors(EjbServicesImpl.java:223)
      at org.jboss.weld.bean.SessionBean.registerInterceptors(SessionBean.java:279)
      at org.jboss.weld.bean.SessionBean.initializeAfterBeanDiscovery(SessionBean.java:273)

      My interceptor in beans.xml is declared as:
      <class>org.infinispan.jcache.annotation.CacheResultInterceptor</class>

      CacheResultInterceptor is an interceptor and has an @aroundInvoke method. It extends AbstractCacheResultInterceptor, which has nothing to do with interceptors:

      //No annotations
      public abstract class AbstractCacheResultInterceptor implements Serializable {

      private static final long serialVersionUID = 5275055951121834315L;
      ....

      So the problem is in org.glassfish.weld.services.EjbServicesImpl, which is searching a @AroundInvoke in all the class hierarchy (I guess)

        Activity

        Hide
        Hong Zhang added a comment -

        assign to CDI team for evaluation

        Show
        Hong Zhang added a comment - assign to CDI team for evaluation
        Hide
        jjsnyder83 added a comment -

        Please provide the source code and application artifact that is being deployed.

        Show
        jjsnyder83 added a comment - Please provide the source code and application artifact that is being deployed.
        Hide
        cocorossello added a comment - - edited

        I can't attach files, but the example itself is simple. 3 files:

        pom.xml:

        <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.mycompany</groupId>
        <artifactId>mavenproject1</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
        <name>mavenproject1</name>
        <dependencies>
        <dependency>
        <groupId>org.infinispan</groupId>
        <artifactId>infinispan-jcache</artifactId>
        <version>7.0.0.Alpha4</version>
        <exclusions>
        <exclusion>
        <artifactId>cdi-api</artifactId>
        <groupId>javax.enterprise</groupId>
        </exclusion>
        <exclusion>
        <artifactId>org.osgi.compendium</artifactId>
        <groupId>org.osgi</groupId>
        </exclusion>
        <exclusion>
        <artifactId>org.osgi.core</artifactId>
        <groupId>org.osgi</groupId>
        </exclusion>
        </exclusions>
        </dependency>
        </dependencies>
        </project>

        SimpleBean.java

        package com.sample;

        import com.mycompany.mavenproject1.SimpleEJB;
        import javax.ejb.EJB;
        import javax.enterprise.context.RequestScoped;
        import javax.inject.Named;

        @Named
        @RequestScoped
        public class SimpleBean {

        @EJB
        private transient SimpleEJB ejb;

        public String getHello()

        { ejb.aMethod();; return "hello"; }

        }

        SimpleEJB.java:

        package com.mycompany.mavenproject1;

        import javax.cache.annotation.CacheResult;
        import javax.ejb.Stateless;

        @Stateless
        public class SimpleEJB {

        @CacheResult(cacheName = "example")
        public void aMethod()

        { System.out.println("amethod"); }

        }

        beans.xml:
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
        version="1.1" bean-discovery-mode="all" >
        <interceptors>
        <class>org.infinispan.jcache.annotation.CacheResultInterceptor</class>
        </interceptors>
        </beans>

        If I move the @CacheResult to SimpleBean it works fine, but I intercept the EJB method it fails

        Show
        cocorossello added a comment - - edited I can't attach files, but the example itself is simple. 3 files: pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd "> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany</groupId> <artifactId>mavenproject1</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>mavenproject1</name> <dependencies> <dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-jcache</artifactId> <version>7.0.0.Alpha4</version> <exclusions> <exclusion> <artifactId>cdi-api</artifactId> <groupId>javax.enterprise</groupId> </exclusion> <exclusion> <artifactId>org.osgi.compendium</artifactId> <groupId>org.osgi</groupId> </exclusion> <exclusion> <artifactId>org.osgi.core</artifactId> <groupId>org.osgi</groupId> </exclusion> </exclusions> </dependency> </dependencies> </project> SimpleBean.java package com.sample; import com.mycompany.mavenproject1.SimpleEJB; import javax.ejb.EJB; import javax.enterprise.context.RequestScoped; import javax.inject.Named; @Named @RequestScoped public class SimpleBean { @EJB private transient SimpleEJB ejb; public String getHello() { ejb.aMethod();; return "hello"; } } SimpleEJB.java: package com.mycompany.mavenproject1; import javax.cache.annotation.CacheResult; import javax.ejb.Stateless; @Stateless public class SimpleEJB { @CacheResult(cacheName = "example") public void aMethod() { System.out.println("amethod"); } } beans.xml: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd " version="1.1" bean-discovery-mode="all" > <interceptors> <class>org.infinispan.jcache.annotation.CacheResultInterceptor</class> </interceptors> </beans> If I move the @CacheResult to SimpleBean it works fine, but I intercept the EJB method it fails
        Hide
        jjsnyder83 added a comment -

        please zip/jar example and mail to j.j.snyder@oracle.com

        Show
        jjsnyder83 added a comment - please zip/jar example and mail to j.j.snyder@oracle.com
        Hide
        jjsnyder83 added a comment -

        I tested similar interceptors in my test app and they work fine so I'd like to test with your sample app.

        After I build the app how do I run the app to trigger the failure?

        Show
        jjsnyder83 added a comment - I tested similar interceptors in my test app and they work fine so I'd like to test with your sample app. After I build the app how do I run the app to trigger the failure?
        Hide
        smillidge-c2b2 added a comment -

        Looking at the code of org.glassfish.weld.services.EjbServicesImpl.getInterceptorMethod(EjbServicesImpl.java:346) this fails because the code tries to find a method with @AroundInvoke in the base class of the interceptor and if it doesn't find it throws an IllegalStateException which I believe is incorrect.

        The error occurs during deployment.

        Modifying the while loop to ignore the exception fixed deployment of my Interceptor which has the same problem.

                    while (interceptorClass != null && !interceptorClass.equals(Object.class)) {
                        try {
                            LifecycleCallbackDescriptor lifecycleDesc = new LifecycleCallbackDescriptor();
        
                            lifecycleDesc.setLifecycleCallbackClass(interceptorClass.getName());
                            lifecycleDesc.setLifecycleCallbackMethod(getInterceptorMethod(interceptorClass,
                                    getInterceptorAnnotationType(interceptionType)));
                            switch (interceptionType) {
                                case POST_CONSTRUCT:
                                    ejbInt.addPostConstructDescriptor(lifecycleDesc);
                                    break;
                                case PRE_DESTROY:
                                    ejbInt.addPreDestroyDescriptor(lifecycleDesc);
                                    break;
                                case PRE_PASSIVATE:
                                    ejbInt.addPrePassivateDescriptor(lifecycleDesc);
                                    break;
                                case POST_ACTIVATE:
                                    ejbInt.addPostActivateDescriptor(lifecycleDesc);
                                    break;
                                case AROUND_INVOKE:
                                    ejbInt.addAroundInvokeDescriptor(lifecycleDesc);
                                    break;
                                case AROUND_TIMEOUT:
                                    ejbInt.addAroundTimeoutDescriptor(lifecycleDesc);
                                    break;
                                default:
                                    throw new IllegalArgumentException("Invalid lifecycle interception type "
                                            + interceptionType);
                            }
                        } catch (IllegalStateException iae) {
                            // this is expected for base classes with not annotations
                        }
                        interceptorClass = interceptorClass.getSuperclass();
                    }
        
        
        Show
        smillidge-c2b2 added a comment - Looking at the code of org.glassfish.weld.services.EjbServicesImpl.getInterceptorMethod(EjbServicesImpl.java:346) this fails because the code tries to find a method with @AroundInvoke in the base class of the interceptor and if it doesn't find it throws an IllegalStateException which I believe is incorrect. The error occurs during deployment. Modifying the while loop to ignore the exception fixed deployment of my Interceptor which has the same problem. while (interceptorClass != null && !interceptorClass.equals( Object .class)) { try { LifecycleCallbackDescriptor lifecycleDesc = new LifecycleCallbackDescriptor(); lifecycleDesc.setLifecycleCallbackClass(interceptorClass.getName()); lifecycleDesc.setLifecycleCallbackMethod(getInterceptorMethod(interceptorClass, getInterceptorAnnotationType(interceptionType))); switch (interceptionType) { case POST_CONSTRUCT: ejbInt.addPostConstructDescriptor(lifecycleDesc); break ; case PRE_DESTROY: ejbInt.addPreDestroyDescriptor(lifecycleDesc); break ; case PRE_PASSIVATE: ejbInt.addPrePassivateDescriptor(lifecycleDesc); break ; case POST_ACTIVATE: ejbInt.addPostActivateDescriptor(lifecycleDesc); break ; case AROUND_INVOKE: ejbInt.addAroundInvokeDescriptor(lifecycleDesc); break ; case AROUND_TIMEOUT: ejbInt.addAroundTimeoutDescriptor(lifecycleDesc); break ; default : throw new IllegalArgumentException( "Invalid lifecycle interception type " + interceptionType); } } catch (IllegalStateException iae) { // this is expected for base classes with not annotations } interceptorClass = interceptorClass.getSuperclass(); }
        Hide
        jjsnyder83 added a comment -

        Please email me a sample app that fails so I can verify the fix.

        Show
        jjsnyder83 added a comment - Please email me a sample app that fails so I can verify the fix.
        Hide
        jjsnyder83 added a comment -

        Return and check for null instead of throwing IllegalStateException.
        Committed revision 63868.

        Show
        jjsnyder83 added a comment - Return and check for null instead of throwing IllegalStateException. Committed revision 63868.

          People

          • Assignee:
            jjsnyder83
            Reporter:
            cocorossello
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: