3 Replies Latest reply on Mar 22, 2012 2:22 PM by Roger Mori

    EntityManagerFactory not found in JNDI when injected in Quartz JobListener

    Shane Sarver Newbie

      Description:
      When Quartz tries to lookup the entityManager in the job listener, the following exception occurs:



      java.lang.IllegalArgumentException: EntityManagerFactory not found in JNDI : java:comp/env/test/pu





      Also, the modification to the remoteJob entity next date is not being persisted in the database, despite calling merge:



      9:23:07,113 INFO  [RemoteJobHome] ***BEFORE: remoteJobManager.scheduleJob(remoteJob): remoteJob: com.test.model.RemoteJob[id=31, host=com.test.model.Host@1830e49, enabled=true, active=false, failed=false, min=0, max=0, next=Mon Feb 09 12:00:00 PST 2009, start=Thu Apr 01 02:00:00 PST 2010, stop=Fri Apr 30 12:00:00 PDT 2010]
      09:23:07,204 INFO  [RemoteJobHome] *** AFTER: remoteJobManager.scheduleJob(remoteJob): remoteJob: com.test.model.RemoteJob[id=31, host=com.test.model.Host@1830e49, enabled=true, active=false, failed=false, min=0, max=0, next=Thu Apr 01 02:00:00 PST 2010, start=Thu Apr 01 02:00:00 PST 2010, stop=Fri Apr 30 12:00:00 PDT 2010]
      




      Is there a better place to call merge than in the manager?



      Flow:



      RemoteJobHome.scheduleJob --> RemoteJobManager.scheduleJob(remoteJob) --> RemoteJobListener.jobWasExecuted(...)




      Log:


      09:23:07,108 INFO  [STDOUT] Hibernate: 
          insert 
          into
              RemoteJob
              (active, enabled, failed, host_id, max, min, next, start, stop) 
          values
              (?, ?, ?, ?, ?, ?, ?, ?, ?)
      09:23:07,110 INFO  [STDOUT] ***PASSWORD HASH: Ss/jICpf9c9GeJj8WKqx1hUClEE=
      09:23:07,110 INFO  [STDOUT] ***PASSWORD HASH: Ss/jICpf9c9GeJj8WKqx1hUClEE=
      09:23:07,113 INFO  [RemoteJobHome] ***BEFORE: remoteJobManager.scheduleJob(remoteJob): remoteJob: com.test.model.RemoteJob[id=31, host=com.test.model.Host@1830e49, enabled=true, active=false, failed=false, min=0, max=0, next=Mon Feb 09 12:00:00 PST 2009, start=Thu Apr 01 02:00:00 PST 2010, stop=Fri Apr 30 12:00:00 PDT 2010]
      09:23:07,204 INFO  [RemoteJobHome] *** AFTER: remoteJobManager.scheduleJob(remoteJob): remoteJob: com.test.model.RemoteJob[id=31, host=com.test.model.Host@1830e49, enabled=true, active=false, failed=false, min=0, max=0, next=Thu Apr 01 02:00:00 PST 2010, start=Thu Apr 01 02:00:00 PST 2010, stop=Fri Apr 30 12:00:00 PDT 2010]
      09:23:17,028 INFO  [JobStoreCMT] Handling 1 trigger(s) that missed their scheduled fire-time.
      09:23:17,246 ERROR [SimpleThreadPool] Error while executing the Runnable: 
      java.lang.IllegalArgumentException: EntityManagerFactory not found in JNDI : java:comp/env/test/pu
              at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManagerFactoryFromJndiOrValueBinding(ManagedPersistenceContext.java:245)
              at org.jboss.seam.persistence.ManagedPersistenceContext.initEntityManager(ManagedPersistenceContext.java:78)
              at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManager(ManagedPersistenceContext.java:107)
              at sun.reflect.GeneratedMethodAccessor924.invoke(Unknown Source)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
              at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144)
              at org.jboss.seam.Component.callComponentMethod(Component.java:2249)
              at org.jboss.seam.Component.unwrap(Component.java:2275)
              at org.jboss.seam.Component.getInstance(Component.java:2041)
              at org.jboss.seam.Component.getInstance(Component.java:1983)
              at org.jboss.seam.Component.getInstance(Component.java:1977)
              at org.jboss.seam.Component.getInstanceInAllNamespaces(Component.java:2349)
              at org.jboss.seam.Component.getValueToInject(Component.java:2301)
              at org.jboss.seam.Component.injectAttributes(Component.java:1736)
              at org.jboss.seam.Component.inject(Component.java:1554)
              at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:61)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:118)
              at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
              at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
              at com.test.action.RemoteJobListener_$$_javassist_seam_10.getName(RemoteJobListener_$$_javassist_seam_10.java)
              at org.quartz.core.QuartzScheduler.notifyJobListenersToBeExecuted(QuartzScheduler.java:1849)
              at org.quartz.core.JobRunShell.notifyListenersBeginning(JobRunShell.java:335)
              at org.quartz.core.JobRunShell.run(JobRunShell.java:173)
              at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:546)
      Caused by: javax.naming.NameNotFoundException: env not bound
              at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
              at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
              at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
              at org.jnp.server.NamingServer.lookup(NamingServer.java:396)
              at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:726)
              at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:833)
              at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:686)
              at javax.naming.InitialContext.lookup(InitialContext.java:392)
              at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManagerFactoryFromJndiOrValueBinding(ManagedPersistenceContext.java:241)
              ... 28 more
      
      



      File: RemoteJobHome.java


      package com.test.action;
      
      import com.test.model.Host;
      import com.test.model.RemoteJob;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Transactional;
      import org.jboss.seam.annotations.web.RequestParameter;
      import org.jboss.seam.faces.FacesMessages;
      import org.jboss.seam.framework.EntityHome;
      import org.jboss.seam.log.Log;
      
      @Name("remoteJobHome")
      public class RemoteJobHome extends EntityHome<RemoteJob> {
        @Logger 
        private Log log;
        @RequestParameter 
        private Long remoteJobId;
        @In 
        private RemoteJobManager remoteJobManager;
      
        @In(create = true)
        HostHome hostHome;
      
        public void setRemoteJobId(Long id) {
          setId(id);
        }
      
        public Long getRemoteJobId() {
          return (Long) getId();
        }
      
        @Override
        protected RemoteJob createInstance() {
          RemoteJob remoteJob = new RemoteJob();
          return remoteJob;
        }
      
        public void load() {
          if (isIdDefined()) {
            wire();
          }
        }
      
        public void wire() {
          getInstance();
          Host host = hostHome.getDefinedInstance();
          if (host != null) {
            getInstance().setHost(host);
          }
        }
      
        public boolean isWired() {
          return true;
        }
      
        public RemoteJob getDefinedInstance() {
          return isIdDefined() ? getInstance() : null;
        }
      
        @Override
        public Object getId() {
          return remoteJobId;
        }
      
        @Transactional
        public String scheduleJob() throws Exception {
          String result = persist();
          RemoteJob remoteJob = getInstance();
          log.info("***BEFORE: remoteJobManager.scheduleJob(remoteJob): remoteJob: #0", remoteJob);
          remoteJobManager.scheduleJob(remoteJob);
          log.info("*** AFTER: remoteJobManager.scheduleJob(remoteJob): remoteJob: #0", remoteJob);
          return result;
        }
      
        @Transactional
        public void cancel() throws Exception {
          RemoteJob remoteJob = getInstance();
          remoteJobManager.cancel(remoteJob);
          FacesMessages.instance().add("Deleted job: RemoteJob(" + remoteJob.getId() + ")");
        }
      }
      
      



      File: RemoteJobManager.java


      package com.test.action;
      
      import com.test.model.RemoteJob;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.persistence.EntityManager;
      import org.jboss.seam.annotations.AutoCreate;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Transactional;
      import org.jboss.seam.log.Log;
      import org.quartz.impl.StdScheduler;
      import org.quartz.JobDetail;
      import org.quartz.jobs.NoOpJob;
      import org.quartz.Scheduler;
      import org.quartz.SimpleTrigger;
      
      @Name("remoteJobManager")
      @AutoCreate
      public class RemoteJobManager {
        @Logger 
        private Log log;
        @In
        private EntityManager entityManager;
        @In(create=true) 
        private RemoteJobListener remoteJobListener;
      
        public void cancel(RemoteJob remoteJob) throws Exception {
          remoteJob.setActive(false);
          // Explicitly remove job
          InitialContext ctx = new InitialContext();
          StdScheduler scheduler = (StdScheduler) ctx.lookup("Quartz");
          scheduler.deleteJob(remoteJob.getId().toString(), Scheduler.DEFAULT_GROUP);
          remoteJob.setActive(false);
          entityManager.merge(remoteJob);
        }
      
        public void scheduleJob(RemoteJob remoteJob) { 
          try {
            // Update remote job entity
            remoteJob.setNext(remoteJob.getStart());
            // Lookup quartz scheduler
            Context ctx = new InitialContext();
            StdScheduler scheduler = (StdScheduler) ctx.lookup("Quartz");
            //  Create quartz job 
            JobDetail jobDetail = new JobDetail(
              remoteJob.getId().toString(),  
              Scheduler.DEFAULT_GROUP,
              NoOpJob.class
            );
            SimpleTrigger trigger = new SimpleTrigger(
              "trigger" + remoteJob.getId().toString(), 
              Scheduler.DEFAULT_GROUP, 
              remoteJob.getStart(),
              null, 
              0, 
              0);
            // Set up the quartz job listener
            scheduler.addJobListener(remoteJobListener);
            // Associate listener with the job
            jobDetail.addJobListener(remoteJobListener.getName());        
            // Schedule the job to run
            scheduler.scheduleJob(jobDetail, trigger);
            entityManager.merge(remoteJob);
          }
          catch (Exception e) {
            log.error("***e: #0", e);
            e.printStackTrace();
          }
        }
      }
      
      



      File: RemoteJobListener.java


      package com.test.action;
      
      import com.test.model.RemoteJob;
      import java.util.Date;
      import javax.persistence.EntityManager;
      import org.jboss.seam.annotations.AutoCreate;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.log.Log;
      import org.quartz.JobDetail;
      import org.quartz.JobExecutionContext;
      import org.quartz.JobExecutionException;
      import org.quartz.JobListener;
      import org.quartz.SchedulerException;
      import org.quartz.Scheduler;
      import org.quartz.SimpleTrigger;
      
      @Name("remoteJobListener")
      @AutoCreate
      public class RemoteJobListener implements JobListener {
        @In(create=true)
        private EntityManager entityManager;
        @Logger
        private Log log;
      
        public String getName() {
          return getClass().getName();
        }
      
        public void jobToBeExecuted(JobExecutionContext jec) {
          try {
            log.info("***jobToBeExecuted");
          }
          catch (Exception e) {
            e.printStackTrace(); 
          }
        }
      
        public void jobExecutionVetoed(JobExecutionContext jec) {
          try {
            log.info("***jobExecutionVetoed");
          }
          catch (Exception e) {
            e.printStackTrace(); 
          }
        }
      
        public void jobWasExecuted(JobExecutionContext jec, JobExecutionException jee) {
          log.info("***jobWasExecuted");
          try {
            // Lookup job
            JobDetail jobDetail = jec.getJobDetail();
            log.info("***entityManager: #0", entityManager);
            RemoteJob remoteJob = entityManager.find(RemoteJob.class, new Long(jobDetail.getName()));    
            log.info("***remoteJob: #0", remoteJob);
            // Compute random delay
            RandomIntervalDuration random = new RandomIntervalDuration(remoteJob.getMin(), remoteJob.getMax());
            Long delay = random.nextLongMillis();
            Date date = new Date(System.currentTimeMillis() + delay);
            // Only shedule new quartz job if before end date.
            log.info("***date: " + date + ", stop: " + remoteJob.getStop());
            if (date.before(remoteJob.getStop())) {   
              // Update remote job entity
              remoteJob.setNext(date);
              entityManager.merge(remoteJob);
              log.info("***true == date.before(stop): Updating remoteJobote job w/ next start time: #)", remoteJob);
              // Create trigger
              SimpleTrigger trigger = new SimpleTrigger(
                "trigger" + jobDetail.getName().toString(),
                Scheduler.DEFAULT_GROUP,
                date,
                null,
                0,
                0
              );
              // schedule the job to run!
              try { 
                jec.getScheduler().scheduleJob(jobDetail, trigger);
              } 
              catch (SchedulerException e) {
                log.warn("***Unable to schedule " + jobDetail.getName());
                e.printStackTrace();
              }
            }
            else {
              // Deactivate job
              remoteJob.setActive(false);
              entityManager.merge(remoteJob);
              log.info("***Job completed: #0", jobDetail.getName());
            }
          }
          catch (Exception e) {
            log.error("***e: #0", e);
            e.printStackTrace(); 
          }
        }
      }
      
      


        • 1. Re: EntityManagerFactory not found in JNDI when injected in Quartz JobListener
          Shane Sarver Newbie

          SOLVED: entityManager lookup error by using the following configuration:
          Using: jboss-5.1.0.GA patched with jboss-ejb3-plugin-1.0.19-installer.jar



          File: persistence.xml


          <?xml version="1.0" encoding="UTF-8"?>
          <!-- Persistence deployment descriptor for dev profile -->
          <persistence xmlns="http://java.sun.com/xml/ns/persistence" 
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
                       version="1.0">
             <persistence-unit name="test">
                <provider>org.hibernate.ejb.HibernatePersistence</provider>
                <jta-data-source>testDS</jta-data-source>
                <!-- The <jar-file> element is necessary if you put the persistence.xml in the WAR and the classes in the JAR -->
                <!--
                <jar-file>../../vehicles.jar</jar-file>
                -->
                <properties>
                   <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
                   <property name="hibernate.hbm2ddl.auto" value="update"/>
                   <property name="hibernate.show_sql" value="true"/>
                   <property name="hibernate.format_sql" value="true"/>
                   <property name="jboss.entity.manager.factory.jndi.name" value="java:/testEntityManagerFactory"/>
                </properties>
             </persistence-unit>
          </persistence>
          



          File: components.xml


          <?xml version="1.0" encoding="UTF-8"?>
          <components xmlns="http://jboss.com/products/seam/components"
                      xmlns:async="http://jboss.com/products/seam/async"
                      xmlns:core="http://jboss.com/products/seam/core"
                      xmlns:persistence="http://jboss.com/products/seam/persistence"
                      xmlns:drools="http://jboss.com/products/seam/drools"
                      xmlns:bpm="http://jboss.com/products/seam/bpm"
                      xmlns:framework="http://jboss.com/products/seam/framework"
                      xmlns:security="http://jboss.com/products/seam/security"
                      xmlns:mail="http://jboss.com/products/seam/mail"
                      xmlns:web="http://jboss.com/products/seam/web"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xsi:schemaLocation=
                          "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                           http://jboss.com/products/seam/async http://jboss.com/products/seam/async-2.2.xsd
                           http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.2.xsd
                           http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.2.xsd
                           http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.2.xsd
                           http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.2.xsd
                           http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.2.xsd
                           http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.2.xsd
                           http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">
          
             <core:init debug="@debug@" jndi-pattern="@jndiPattern@"/>
             <core:manager concurrent-request-timeout="500"
                           conversation-timeout="120000"
                           conversation-id-parameter="cid"
                           parent-conversation-id-parameter="pid"/>
             <web:hot-deploy-filter url-pattern="*.seam"/>
             <persistence:managed-persistence-context name="entityManager"
                                               auto-create="true"
                                persistence-unit-jndi-name="java:/testEntityManagerFactory" />
             <drools:rule-base name="securityRules">
                <drools:rule-files>
                   <value>/security.drl</value>
                </drools:rule-files>
             </drools:rule-base>
             <security:rule-based-permission-resolver security-rules="#{securityRules}"/>
          
          
             <event type="org.jboss.seam.security.notLoggedIn">
                <action execute="#{redirect.captureCurrentView}"/>
             </event>
             <event type="org.jboss.seam.security.loginSuccessful">
                <action execute="#{redirect.returnToCapturedView}"/>
             </event>
          
             <mail:mail-session host="localhost" port="25"/>
             <security:jpa-identity-store user-class="com.test.model.UserAccount" role-class="com.test.model.UserRole"/>
             <security:jpa-permission-store user-permission-class="com.test.model.UserPermission"/>
             <security:remember-me enabled="true"/>
             <async:quartz-dispatcher/>
          </components>
          
          



          Still trying to solve entity update problem.

          • 2. Re: EntityManagerFactory not found in JNDI when injected in Quartz JobListener
            吉 刘 Newbie

            hello!

                     I have the same problem with you,did you solve it ?can you share the solutions ?   my environment:seam2.2.2  jboss6.0 final

            please contacts me,thank you !  liuji_jlu@sina.com

            • 3. Re: EntityManagerFactory not found in JNDI when injected in Quartz JobListener
              Roger Mori Newbie

              Hi Shane:

               

              What is the update problem?

               

              Try adding  @Transactional to your listener, and flushing the entity manager instead of merging an already managed instance.

               

              Also you can obtain a reference of the quartz Scheduler by injecting the component "org.jboss.seam.async.dispatcher" and calling its getScheduler method.

               

              Hope it helps.

               

              Roger.