12 Replies Latest reply on Sep 18, 2006 10:30 AM by ishubov

    Is it SpringLifecycleInterceptor or just me?

    arnowerr

      The other day I decided to play a little with batch processing on JBoss + Spring EJB3 and all.
      Created this stateful session bean to force the Entity manager do a batch job for me on remove

      @Stateful
      @Interceptors(SpringLifecycleInterceptor.class)
      @TransactionAttribute(NOT_SUPPORTED)
      public class StetefulBean implements Init {
       @PersistenceContext(unitName = "titan", type = EXTENDED)
       private EntityManager manager;
      
       @Spring(jndiName = "spring-pojo", bean = "statefulService")
       private TravelService service;
      
       @PostConstruct
       public void postConstruct() {
       service.setManager(manager);
       }
      
       public void initAirports(int index) {
       if (isInit(Airport.class)) {
       return;
       }
       List<Airport> lst = new ArrayList<Airport>();
      
       for (int i = 0; i < index; i++) {
       Airport port = new Airport();
       if (i % 2 == 0) {
       port.setName("Denver " + (i + 1));
       port.setAirportCode("dnvr_" + (i + 1));
       } else {
       port.setName("Hoover " + (i + 1));
       port.setAirportCode("hvr_" + (i + 1));
       }
       lst.add(port);
       }
       service.createAirports(lst);
       }
      
       @Remove
       @TransactionAttribute(REQUIRED)
       public void flush() {
       // syncrhonize with database;
       }
      
       private boolean isInit(Class clazz) {
       return service.getNumberOfObjects(clazz) == 0 ? false : true;
       }
      }
      


      I am using this SpringLifecycleInterceptor.class from the JBoss+Spring distribution. Unfortunately, that one is giving me kinda trouble throwing all kind of exceptions

      OK. Made my own interceptor a la SpringLifecycleInterceptor
      public class StatefulBeanInterceptor extends SpringPassivationInterceptor {
       private static final long serialVersionUID = 1243234L;
       @PostConstruct
       public void postConstruct(InvocationContext ctx) throws Throwable {
       inject(ctx.getBean());
       ctx.proceed();
       }
      }
      


      Wired it up. @Interceptors(StatefulBeanInterceptor.class)
      Ran JBoss.
      No problemo! Works like a charm. There might be something wrong with that SpringLifecyleInterceptor thing from the distribution, or mine might be a bit obsolete (I've downloaded sometime late June, I guess). No idea...

      Another question - how to inject EntityManager from Spring configuration. Currently I am using annotations and pushing manager to the service layer. Yet wiring it up from outside, Spring, I mean, would be kinda kool to me.

      Cheers,
      Arno

        • 1. Re: Is it SpringLifecycleInterceptor or just me?
          arnowerr

          Exception from SpringLifecycleInterceptor:

          Error message: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NoSuchMethodError: javax.interceptor.InvocationContext.getTarget()Ljava/lang/Object;
          Exception in thread "main" javax.ejb.EJBException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NoSuchMethodError: javax.interceptor.InvocationContext.getTarget()Ljava/lang/Object;
           at org.jboss.ejb3.cache.simple.SimpleStatefulCache.create(SimpleStatefulCache.java:223)
           at org.jboss.ejb3.stateful.StatefulContainer.dynamicInvoke(StatefulContainer.java:288)
           at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
           at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
           at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
           at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
           at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
           at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
           at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
          Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NoSuchMethodError: javax.interceptor.InvocationContext.getTarget()Ljava/lang/Object;
           at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.postConstruct(LifecycleInterceptorHandler.java:109)
           at org.jboss.ejb3.EJBContainer.invokePostConstruct(EJBContainer.java:582)
           at org.jboss.ejb3.AbstractPool.create(AbstractPool.java:108)
           at org.jboss.ejb3.ThreadlocalPool.get(ThreadlocalPool.java:48)
           at org.jboss.ejb3.cache.simple.SimpleStatefulCache.create(SimpleStatefulCache.java:207)
           at org.jboss.ejb3.stateful.StatefulContainer.dynamicInvoke(StatefulContainer.java:288)
           at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
           at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
           at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
           at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
           at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
           at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
           at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
           at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:190)
           at org.jboss.remoting.Client.invoke(Client.java:525)
           at org.jboss.remoting.Client.invoke(Client.java:488)
           at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:55)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:55)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:65)
           at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
           at org.jboss.ejb3.stateful.StatefulRemoteProxy.invoke(StatefulRemoteProxy.java:133)
           at $Proxy1.initAirports(Unknown Source)
           at com.ileonov.client.Client.init(Client.java:97)
           at com.ileonov.client.Client.run(Client.java:39)
           at com.ileonov.client.Client.main(Client.java:23)
          Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodError: javax.interceptor.InvocationContext.getTarget()Ljava/lang/Object;
           at org.jboss.ejb3.interceptor.LifecycleInvocationContextImpl.proceed(LifecycleInvocationContextImpl.java:141)
           at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.postConstruct(LifecycleInterceptorHandler.java:105)
           at org.jboss.ejb3.EJBContainer.invokePostConstruct(EJBContainer.java:582)
           at org.jboss.ejb3.AbstractPool.create(AbstractPool.java:108)
           at org.jboss.ejb3.ThreadlocalPool.get(ThreadlocalPool.java:48)
           at org.jboss.ejb3.cache.simple.SimpleStatefulCache.create(SimpleStatefulCache.java:207)
           at org.jboss.ejb3.stateful.StatefulContainer.dynamicInvoke(StatefulContainer.java:288)
           at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
           at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
           at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
           at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
           at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
           at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
           at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
          Caused by: java.lang.NoSuchMethodError: javax.interceptor.InvocationContext.getTarget()Ljava/lang/Object;
           at org.jboss.spring.callback.SpringLifecycleInterceptor.postConstruct(SpringLifecycleInterceptor.java:44)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
           at java.lang.reflect.Method.invoke(Method.java:585)
           at org.jboss.ejb3.interceptor.LifecycleInvocationContextImpl.proceed(LifecycleInvocationContextImpl.java:131)
           ... 13 more
          
          


          • 2. Re: Is it SpringLifecycleInterceptor or just me?
            alesj

            Looks like you are using old ejb3 impl:
            - http://jboss.org/jbossBlog/blog/bburke/2006/06/02/JBoss_EJB_3_0_Preview_RC8.txt

            >> Another question - how to inject EntityManager from Spring configuration

            This you have to look it up from Spring docs ... but why not using @PersistenceContext ... and then wire-ing it up to Spring layer?

            Rgds, Ales

            • 3. Re: Is it SpringLifecycleInterceptor or just me?
              alesj

               

              Currently I am using annotations and pushing manager to the service layer. Yet wiring it up from outside, Spring, I mean, would be kinda kool to me.


              >> but why not using @PersistenceContext ... and then wire-ing it up to Spring layer?

              Ok ... missed this one ... but what's the problem here?
              I guess you can still use JPA from Spring ... but EJB3 container will probably not be able to join into that context.
              It depends what you want to do.

              Rgds, Ales

              • 4. Re: Is it SpringLifecycleInterceptor or just me?
                arnowerr

                Thank you Ales for your comments and suggestions.

                I followed your advise and tried to update my JBoss 4.0.4 GA and run it with your Spring integration solution.
                Unfortunately, my experience in this endeavor is mainly negative.
                Firstly, I tried to install on my existing JBoss [Zion] 4.0.4.GA (build: CVSTag=JBoss_4_0_4_GA date=200605151000) jboss-EJB-3.0_RC8-FD.
                Downloaded jboss-EJB-3.0_RC8-FD.zip. Not good. The problem - according to accompanying INSTALL.html there should be client jars (fairly reasonable attitude):

                15. Copy jboss-ejb3-client.jar from the lib/ directory of the distribution to jboss-4.0.x/client
                17. Copy hibernate-client.jar from the lib/ directory of the distribution to jboss-4.0.x/client
                etc.
                

                Here's the content of the RC8-FD lib directory:
                ./ejb3-entity-cache-service.xml
                ./hibernate-entitymanager.jar
                ./ejb3-interceptors-aop.xml
                ./ejb3-persistence.jar
                ./quartz-ra.rar
                ./hibernate-annotations.jar
                ./ejb3.deployer
                ./ejb3.deployer/jboss-ejb3x.jar
                ./ejb3.deployer/jboss-ejb3.jar
                ./ejb3.deployer/META-INF
                ./ejb3.deployer/META-INF/persistence.properties
                ./ejb3.deployer/META-INF/jboss-service.xml
                ./ejb3.deployer/jboss-annotations-ejb3.jar
                ./quartz-all-1.5.2.jar
                ./jboss-remoting.jar
                ./hibernate3.jar
                ./ejb3-clustered-sfsbcache-service.xml
                ./jboss-aop-jdk50.deployer
                ./jboss-aop-jdk50.deployer/trove.jar
                ./jboss-aop-jdk50.deployer/base-aop.xml
                ./jboss-aop-jdk50.deployer/META-INF
                ./jboss-aop-jdk50.deployer/META-INF/jboss-service.xml
                ./jboss-aop-jdk50.deployer/jboss-aop-jdk50.jar
                ./jboss-aop-jdk50.deployer/jboss-aspect-library-jdk50.jar
                

                Well, I do not see any client jar here... and without proper client jars my attempts to communicate with the server using standalone client are doomed. I need client and I need RMI.

                Unable to install jboss-EJB-3.0_RC8-FD.zip (client jars problem) I decided to download the whole shebang hoping that this ejb update might be incorporated (wrong call!) with the newest version of the JBoss 4.0.4
                http://umn.dl.sourceforge.net/sourceforge/jboss/jboss-4.0.4.GA-Patch1-installer.jar

                Installed ejb3 version domain all, installed your jboss-spring-jdk5.deployer and tried with my test application.
                Yak! This patched server throws
                08:05:25,377 INFO [[/web]] Loading Spring root WebApplicationContext
                08:05:25,597 INFO [CollectionFactory] JDK 1.4+ collections available
                08:05:25,874 INFO [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/applicationContext.xml]
                08:05:26,427 INFO [DefaultNamespaceHandlerResolver] Ignoring handler [org.springframework.jndi.config.JndiNamespaceHandler]: class not found
                08:05:26,492 INFO [DefaultNamespaceHandlerResolver] Ignoring handler [org.springframework.web.servlet.config.MvcNamespaceHandler]: class not found
                08:05:26,623 INFO [XmlWebApplicationContext] Bean factory for application context [Root WebApplicationContext]: org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [facade]; root of BeanFactory hierarchy
                08:05:26,727 INFO [XmlWebApplicationContext] 1 beans defined in application context [Root WebApplicationContext]
                08:05:26,770 INFO [XmlWebApplicationContext] Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@937e20]
                08:05:26,779 INFO [XmlWebApplicationContext] Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicationEventMulticaster@e229be]
                08:05:26,824 INFO [UiApplicationContextUtils] Unable to locate ThemeSource with name 'themeSource': using default [org.springframework.ui.context.support.ResourceBundleThemeSource@10a063d]
                08:05:26,831 INFO [DefaultListableBeanFactory] Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [facade]; root of BeanFactory hierarchy]
                08:05:27,179 ERROR [ContextLoader] Context initialization failed
                org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'facade' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: jspring not bound
                javax.naming.NameNotFoundException: jspring not bound
                 at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
                 at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
                 at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
                 at org.jnp.server.NamingServer.lookup(NamingServer.java:267)
                 at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)
                 at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
                 at javax.naming.InitialContext.lookup(InitialContext.java:351)
                 at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:123)
                 at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:85)
                 at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:121)
                 at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:71)
                 at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:106)
                 at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:125)...
                
                08:05:27,197 ERROR [[/web]] Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
                org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'facade' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: jspring not bound
                javax.naming.NameNotFoundException: jspring not bound
                 at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
                 at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
                 at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
                 at org.jnp.server.NamingServer.lookup(NamingServer.java:267)
                


                Classic bad behavior of an application server towards Spring. Server loads web part of the app first and after that - is trying to load EJBs.
                I tried to rectify this. My usual declaration in applicationContext.xml
                for local facade looks like this.
                 <bean
                 id="facade"
                 class="&JndiObjectFactoryBean;">
                 <property
                 name="jndiName"
                 value="&facadeJndi;" />
                 </bean>
                

                I tried to to force the factory bean to generate a proxy object to stand in for the real JNDI object and disabled lookupOnStartup. New version:
                 <bean
                 id="facade"
                 class="&JndiObjectFactoryBean;">
                 <property
                 name="jndiName"
                 value="&facadeJndi;" />
                 <property
                 name="lookupOnStartup"
                 value="false" />
                 <property
                 name="proxyInterface"
                 value="&facadeLocal;" />
                 </bean>
                

                Rebuild, reran. Nada! The same exception. For me it's no show, so I decided to revert back to my old, original JBoss 4.0.4 which does not recognize SpringLifecycleInterceptor but works well with my version of the same thing extending SpringPassivationInterceptor. This my original installation works good with Spring - first it loads EJBs and only then - web layer.
                Yet not all that good.
                On my web layer I have two very simple jsps with JSTL - index.jsp and home.jsp.
                index -
                <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
                <c:redirect url="/home.htm"/>
                

                home.jsp has the following very simple JSTL statements:
                <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
                ...
                <ul>
                 <c:forEach items="${specials}" var="special">
                 <li>${special.departFrom.name} - ${special.arriveAt.name} from ${special.cost}</li>
                 </c:forEach>
                </ul>
                

                The problem is with jsp generation JBoss 4.0.4 on my machine generates index.jsp correctly transforming jstl into something like this
                _jspx_th_c_redirect_0.setPageContext(_jspx_page_context);
                 _jspx_th_c_redirect_0.setParent(null);
                 _jspx_th_c_redirect_0.setUrl("/home.htm");
                 int _jspx_eval_c_redirect_0 = _jspx_th_c_redirect_0.doStartTag();
                 if (_jspx_th_c_redirect_0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
                 _jspx_tagPool_c_redirect_url_nobody.reuse(_jspx_th_c_redirect_0);
                 return true;
                 }
                 _jspx_tagPool_c_redirect_url_nobody.reuse(_jspx_th_c_redirect_0);
                 return false;
                

                But in case with home.jsp it fails to process forEach.
                do {
                 out.write("\n");
                 out.write("\t\t<li>");
                 out.write("${special.departFrom.name}");
                 out.write(' ');
                 out.write('-');
                 out.write(' ');
                 out.write("${special.arriveAt.name}");
                 out.write(" from\n");
                 out.write("\t\t$");
                 out.write("${special.cost}");
                 out.write("</li>\n");
                 out.write("\t");
                 int evalDoAfterBody = _jspx_th_c_forEach_0.doAfterBody();
                 if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)
                and on generated html I am getting
                <ul> <li>${special.departFrom.name} - ${special.arriveAt.name} from ${special.cost}</li>
                
                </ul>
                

                Tried the same pages on JBoss 4.0.2 and Sun AS 8 - no problem - pages properly generated.
                I noticed that in your sample application you don't use JSTL. Why is that? Is this because
                JBoss 4.0.4x way of handling of JSTL statements kinda 'patchy'? It's also strange that 4.0.4 does not have usual web-console - only jmx, at least on my installations. Well, strange, strange...
                So, for now I have a disfunctional web layer (controllers working fine though) and properly working facade, service, dao, EJB3 persistence on my old JBoss 4.0.4 - not patched.

                Any ideas are highly appreciated ;)

                Cheers,
                Arno




                • 5. Re: Is it SpringLifecycleInterceptor or just me?
                  arnowerr

                  Ales,
                  I am reading your article 'Spring and EJB 3.0 in Harmony'
                  Quote:


                  However, one big problem with EJB 3.0 dependency injection is that there's no way of configuring, defining, and injecting plain Java beans.
                  You can only inject Java EE component types and <env-entry> only lets you inject primitive types. Sure, EJBs look a lot like POJOs and JBoss has the concept of a @Service bean, which is a singleton, but do we really have to define and inject these component objects that have to run in containers?
                  And what about beans from third-party libraries and pre-existing code.

                  Well, how about this?
                  @Stateless
                  public class OrderEntryBean implements OrderEntry {
                  
                   @PersistenceContext(unitName = "titan")
                   private EntityManager manager;
                  
                   private PersonDao personDao;
                  
                   @Resource(name = "personDaoImplName")
                   private String personDaoImplName;
                  
                   @PostConstruct
                   public void postConstruct() {
                   try {
                   personDao = (PersonDao) (Class.forName(personDaoImplName))
                   .newInstance();
                   } catch (Exception e) {
                   throw new ValidationException(e);
                   }
                   personDao.setManager(manager);
                   }
                  }
                  

                  <enterprise-beans>
                   <session>
                   <ejb-name>OrderEntryBean</ejb-name>
                   <env-entry> <env-entry-name>personDaoImplName</env-entry-name>
                   <env-entry-type>java.lang.String</env-entry-type>
                   <env-entry-value>
                   com.arno.dao.impl.PersonDaoImpl
                   </env-entry-value>
                   </env-entry>
                   </session>
                  </enterprise-beans>
                  


                  It might be heavy, it might be not-elegant the way Spring provides solution (LOC), injected object cannot be configured externally. But to all practical purposes as long as a class has an interface it can be injected into EJB and serve the purpose of injection - runtime definition of implementation. Not so? ;)

                  Cheers,
                  Arno

                  • 6. Re: Is it SpringLifecycleInterceptor or just me?
                    alesj

                    There are two almost similar versions of jboss-spring deployer.

                    One with old InvocationContext, @EJB and the other one with fixed (see http://jboss.org/jbossBlog/blog/bburke/2006/06/02/JBoss_EJB_3_0_Preview_RC8.txt).

                    Check what version 4.0.4.GA has - see jboss-ejb3x.jar in ejb3.deployer.

                    >> javax.naming.NameNotFoundException: jspring not bound

                    This is not the cause - look before this.

                    >> Classic bad behavior of an application server towards Spring. Server loads web part of the app first and after that - is trying to load EJBs.
                    I tried to rectify this.

                    Put the right order in application.xml. Or adjust deployer order.

                    >> I noticed that in your sample application you don't use JSTL. Why is that?

                    No reaseon. I use a lot of JSTL in our portal app with no problem.

                    >> Well, how about this?

                    Sorry, but yuck.
                    Still very unflexible. I like wiring a lot of small beans. And this doesn't do that.

                    Rgds, Ales

                    • 7. Re: Is it SpringLifecycleInterceptor or just me?
                      arnowerr

                      RE: There are two almost similar versions of jboss-spring deployer.
                      One with old InvocationContext, @EJB and the other one with fixed (see http://jboss.org/jbossBlog/blog/bburke/2006/06/02/JBoss_EJB_3_0_Preview_RC8.txt).
                      Right. But available zip download does not have client jars. I need them for remoting.
                      And it's not only me:
                      http://www.jboss.com/index.html?module=bb&op=viewtopic&t=84310

                      Re: Check what version 4.0.4.GA has - see jboss-ejb3x.jar in ejb3.deployer.
                      Roger! For now I am sticking with Implementation-Version: JBoss EJB 3.0 RC7 - FD
                      The same problem - I need client jars to move to RC8 and available distribution lacks them.

                      Re: This is not the cause - look before this.
                      MEA CULPA! MEA CULPA! MEA CULPA! Sorry, JBoss. That was just a bloody rogue war in deploy directory. You know - 'build', 'colddelpoy', 'run' - who check the deploy directory, right?... I should have, I should have.

                      Re: Put the right order in application.xml.
                      Looks fine to me.

                      <?xml version="1.0" encoding="UTF-8"?>
                      <application version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                       http://java.sun.com/xml/ns/j2ee/application_1_4.xsd">
                       <display-name>EJB 3 Test Application - Spring</display-name>
                       <module>
                       <java>common.jar</java>
                       </module>
                       <module>
                       <java>domain.jar</java>
                       </module>
                       <module>
                       <java>service.spring</java>
                       </module>
                       <module>
                       <ejb>facade.jar</ejb>
                       </module>
                       <module>
                       <web>
                       <web-uri>web.war</web-uri>
                       <context-root>titan</context-root>
                       </web>
                       </module>
                       <!-- library -->
                       <module>
                       <java>commons-lang.jar</java>
                       </module>
                      </application>
                      


                      Re: Or adjust deployer order.
                      How actually are you doing this?

                      Re: I use a lot of JSTL....
                      Way to go! I found the problem which killed my JSTL. My first version of web.xml had the following declaration
                      <web-app
                       xmlns="http://java.sun.com/xml/ns/j2ee"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                       http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" />
                      

                      Looks right but lacking version="2.4" As soon as I've changed to
                      <web-app
                       xmlns="http://java.sun.com/xml/ns/j2ee"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                       http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4" />
                      

                      JSTL tags are OK.

                      Re:' I use a lot of JSTL....'
                      Well, how about another wonderful Spring feature - Spring tags. I was trying to use them in my test application. Created a simple jsp with Spring tags
                      <body>
                       <h1>Search for Flights</h1>
                       <spring:nestedPath path="flightSearchCriteria">
                       <form action="" method="post">
                       <table>
                       <tr>
                       <td>Depart From:</td>
                       <td>
                       <spring:bind path="departFrom">
                       <input type="text" name="${status.expression}" value="${status.value}"/>
                       </spring:bind>
                       </td>
                       <td>Depart On:</td>
                       <td>
                       <spring:bind path="departOn">
                       <input type="text" name="${status.expression}" value="${status.value}"/>
                       </spring:bind>
                       <span style="font-size:smaller">(yyyy-MM-dd HH)</span>
                       </td>
                       </tr>
                       <tr>
                       <td>Arrive At:</td>
                       <td>
                       <spring:bind path="arriveAt">
                       <input type="text" name="${status.expression}" value="${status.value}"/>
                       </spring:bind>
                       </td>
                       <td>Return On:</td>
                       <td>
                       <spring:bind path="returnOn">
                       <input type="text" name="${status.expression}" value="${status.value}"/>
                       </spring:bind>
                       <span style="font-size:smaller">(yyyy-MM-dd HH)</span>
                       </td>
                       </tr>
                       <tr>
                       <td/>
                       <td>
                       <input type="submit" value="Search"/>
                       </td>
                       <td/>
                       <td/>
                       </tr>
                       </table>
                       </form>
                       </spring:nestedPath>
                      </body>
                      

                      and appropriate command
                      public class FlightSearchCriteria implements Serializable {
                       private static final long serialVersionUID = 145645L;
                      
                       private String departFrom;
                      
                       private Date departOn;
                      
                       private String arriveAt;
                      
                       private Date returnOn;
                       ...
                      }
                      

                      trings are working fine but any attempt to process Dates generates the following :
                      2006-08-02 09:44:25,312 DEBUG [org.springframework.beans.BeanWrapperImpl] About to invoke write method [public void com.arno.net.business.logic.FlightSearchCriteria.setDepartFrom(java.lang.String)] on object of class [com.arno.net.business.logic.FlightSearchCriteria]
                      2006-08-02 09:44:25,312 DEBUG [org.springframework.beans.BeanWrapperImpl] Invoked write method [public void com.arno.net.business.logic.FlightSearchCriteria.setDepartFrom(java.lang.String)] with value of type [java.lang.String]
                      2006-08-02 09:44:25,320 DEBUG [org.springframework.beans.PropertyTypeConverter] Converting String to [class java.util.Date] using property editor [org.jboss.util.propertyeditor.DateEditor@c017d]
                      2006-08-02 09:44:25,321 ERROR [org.springframework.web.servlet.DispatcherServlet] Could not complete request
                      java.lang.NullPointerException
                       at org.jboss.util.propertyeditor.DateEditor.setValue(DateEditor.java:97)
                       at org.springframework.beans.PropertyTypeConverter.convertValue(PropertyTypeConverter.java:254)
                       at org.springframework.beans.PropertyTypeConverter.convertIfNecessary(PropertyTypeConverter.java:176)
                       at org.springframework.beans.PropertyTypeConverter.convertIfNecessary(PropertyTypeConverter.java:106)
                       at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:713)
                       at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:565)
                       at org.springframework.beans.AbstractPropertyAccessor.setPropertyValue(AbstractPropertyAccessor.java:49)
                       at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:68)
                       at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:424)
                       at org.springframework.validation.DataBinder.doBind(DataBinder.java:331)
                       at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:111)
                       at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:108)
                       at org.springframework.web.servlet.mvc.BaseCommandController.bindAndValidate(BaseCommandController.java:305)
                       at org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:244)
                       at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:139)
                       at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:44)
                       at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:684)
                       at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:625)
                       at org.springframework.web.servlet.FrameworkServlet.serviceWrapper(FrameworkServlet.java:386)
                       at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:355)
                       at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
                       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
                       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
                       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
                       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
                       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
                       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
                       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
                       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
                       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
                       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
                       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
                       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
                       at java.lang.Thread.run(Thread.java:595)
                      2006-08-02 09:44:25,327 DEBUG [org.springframework.web.context.support.XmlWebApplicationContext] Publishing event in context [WebApplicationContext for namespace 'jboss-spring-servlet']: RequestHandledEvent: url=[/titan/search.htm]; time=[33ms]; client=[127.0.0.1]; method=[POST]; servlet=[jboss-spring]; session=[570DFBE803F76A952BA0B334F5CA4305]; user=[null]; status=[failed: java.lang.NullPointerException]
                      2006-08-02 09:44:25,327 DEBUG [org.springframework.web.context.support.XmlWebApplicationContext] Publishing event in context [Root WebApplicationContext]: RequestHandledEvent: url=[/titan/search.htm]; time=[33ms]; client=[127.0.0.1]; method=[POST]; servlet=[jboss-spring]; session=[570DFBE803F76A952BA0B334F5CA4305]; user=[null]; status=[failed: java.lang.NullPointerException]
                      2006-08-02 09:44:25,329 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/titan].[jboss-spring]] Servlet.service() for servlet jboss-spring threw exception
                      java.lang.NullPointerException
                       at org.jboss.util.propertyeditor.DateEditor.setValue(DateEditor.java:97)
                       at org.springframework.beans.PropertyTypeConverter.convertValue(PropertyTypeConverter.java:254)
                       at org.springframework.beans.PropertyTypeConverter.convertIfNecessary(PropertyTypeConverter.java:176)
                       at org.springframework.beans.PropertyTypeConverter.convertIfNecessary(PropertyTypeConverter.java:106)
                       at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:713)
                       at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:565)
                       at org.springframework.beans.AbstractPropertyAccessor.setPropertyValue(AbstractPropertyAccessor.java:49)
                       at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:68)
                       at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:424)
                       at org.springframework.validation.DataBinder.doBind(DataBinder.java:331)
                       at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:111)
                       at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:108)
                       at org.springframework.web.servlet.mvc.BaseCommandController.bindAndValidate(BaseCommandController.java:305)
                       at org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:244)
                       at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:139)
                       at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:44)
                       at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:684)
                       at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:625)
                       at org.springframework.web.servlet.FrameworkServlet.serviceWrapper(FrameworkServlet.java:386)
                       at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:355)
                       at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
                       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
                       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
                       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
                       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
                       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
                       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
                       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
                       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
                       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
                       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
                       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
                       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
                       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
                       at java.lang.Thread.run(Thread.java:595)
                      

                      JBoss property editor is not really happy :(
                      Any insight?

                      Like I said, I've read your article:

                      It would be quite annoying to have to apply this interceptor to each and every bean class or define it for each bean in XML, so there in the final draft of the EJB 3.0 specification will be a way to define default interceptors.

                      Tried it
                      <assembly-descriptor>
                       <interceptor-binding>
                       <ejb-name>*</ejb-name>
                       <interceptor-class>
                       org.jboss.tutorial.ee.service.impl.interceptor.SpringBeanLifecycleInterceptor
                       </interceptor-class>
                       </interceptor-binding>
                       </assembly-descriptor>
                      

                      Works like a charm.
                      Thanks for the tip, Ales. BTW, is EJB 3.0 specs are official by now? There was supposed to be such a declaration on Java One, wasn't it?


                      • 8. Re: Is it SpringLifecycleInterceptor or just me?
                        alesj

                        >> How actually are you doing this?

                        Look at the XMBean of MainDeployer (conf/props).

                        >> Any insight?

                        Nope.

                        >> BTW, is EJB 3.0 specs are official by now?

                        Yep. From mid May I think.

                        • 9. Re: Is it SpringLifecycleInterceptor or just me?
                          arnowerr

                          >> Any insight?
                          Found it. I just need to register my own custom editor.

                          protected void initBinder(HttpServletRequest req,
                           ServletRequestDataBinder binder) throws Exception {
                           binder.registerCustomEditor(Date.class, new CustomDateEditor(
                           new SimpleDateFormat("yyyy-MM-dd"), true));
                           }
                          

                          Now it works.
                          Like they say - there IS a wooden item in F/A-18 Hornet - pilot!

                          JBoss and Spring... I love this marriage. I really do.

                          • 10. Re: Is it SpringLifecycleInterceptor or just me?
                            arnowerr

                            Hi Ales,

                            I have a question for you.

                            Currently in my jboss-spring-jdk5.deployer directory I have the following layout
                            ./spring.jar
                            ./spring-modules-0.5-all.jar
                            ./jboss-spring-jdk5.jar

                            spring.jar is a shiny new jar
                            Manifest-Version: 1.0
                            Ant-Version: Apache Ant 1.6.5
                            Created-By: 1.5.0_06-b05 (Sun Microsystems Inc.)
                            Implementation-Title: Spring Framework
                            Implementation-Version: 2.0-m5
                            Spring-Version: 2.0-m5
                            the same with spring-modules-0.5-all.jar

                            In domain/lib directory as far as spring is concerned I have the following

                            ./spring-core.jar
                            Implementation-Title: Spring Framework
                            Implementation-Version: 2.0-m3
                            Spring-Version: 2.0-m3

                            ./spring-beans.jar
                            Implementation-Title: Spring Framework
                            Implementation-Version: 2.0-m3
                            Spring-Version: 2.0-m3

                            ./spring-context.jar
                            Implementation-Title: Spring Framework
                            Implementation-Version: 1.2.4
                            Spring-Version: 1.2.4

                            The problem is - I cannot upgrade this jars to higher releases of Spring.
                            Should I try upgrade spring-core I am getting java.lang.NoClassDefFoundError: org/springframework/core/GenericsHelper

                            spring-beans - java.lang.NoClassDefFoundError: org/springframework/beans/factory/xml/DefaultXmlBeanDefinitionParser

                            spring-context (well, it is 1.2.4! version) - java.lang.NoSuchMethodError: org.springframework.beans.factory.config.ConfigurableListableBeanFactory.setBeanClassLoader(Ljava/lang/ClassLoader;)

                            Well, I understand Spring team is currently shuffling classes from jar to jar between v.2 releases.
                            However, could you please enlighten me what should be done to make me use spring v.2 throughout your integration solution?

                            Cheers,
                            Arno

                            • 11. Re: Is it SpringLifecycleInterceptor or just me?
                              alesj

                              Yep, the Spring people rocked the thing a bit - changed a few classes. Will make it compatible as soon as I can.

                              • 12. Re: Is it SpringLifecycleInterceptor or just me?
                                ishubov

                                Just curious if this integration issue with Spring 2.0 is fixed. I didn't see any follow up posts. thanks. I really appreciate it.