2015-07-28 4 views
0

Доброе утро. Мне нужно реализовать приложение, которое каждые x минут запускает n задач, и каждая задача записывается в таблицу MySQL. Я думал, что это исправить с помощью:Timer EJB 3.1 + Бассейн для темы

  1. EJB TIMER
  2. JPA для записи на DB
  3. Executors.newFixedThreadPool для управления задачами

Это мое решение. Следующий класс является таймер EJB:

@Singleton 
public class MyTimerService { 

    @EJB 
    private WorkerPool worker; 

    @Schedule(second="*", minute="*/3",hour="*", persistent=false) 
    public void doWork(){ 
     worker.execute(); 
    } 
} 

Это реализация Исполнитель:

public class ThreadExecutor implements Executor{ 

    @Asynchronous 
    @Override 
    public void execute(Runnable command) { 
     ExecutorService executor = Executors.newFixedThreadPool(5); 
     executor.execute(command); 
    } 
    } 

и отделка, класс для работы Тема:

@Stateless 
public class WorkerPool { 

    @EJB 
    private Executor executor; 

    @EJB(name = "Dao") 
    private IDao dao; 

    public void execute() { 

     try { 
      List<Object> info = dao.readTable(); 
      if (info.size() > 0) { 
       for (int i = 0; i < info.size(); i++) { 
        Object temp = info.get(i); 
        Runnable worker = new WorkerThread(temp, dao); 
        executor.execute(worker); 
       } 
       Thread.sleep(30000); 
      } 
     } catch (Throwable e) { 
      e.printStackTrace(); 
     } 
    } 

развернуть мое приложение сервер Glassfish. Это ошибка:

[2015-07-28T17:06:53.995+0200] [glassfish 4.1] [WARNING] [AS-EJB-00056]  [javax.enterprise.ejb.container] [tid: _ThreadID=186 _ThreadName=__ejb-thread-pool12] [timeMillis: 1438096013995] [levelValue: 900] [[ 
    A system exception occurred during an invocation on EJB BetFinderTimerService, method: public void com.surebetfinder.timer.BetFinderTimerService.doWork()]] 

[2015-07-28T17:06:53.996+0200] [glassfish 4.1] [WARNING] [] [javax.enterprise.ejb.container] [tid: _ThreadID=186 _ThreadName=__ejb-thread-pool12] [timeMillis: 1438096013996] [levelValue: 900] [[ 

javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB 
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:435) 
    at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2579) 
    at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1971) 
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210) 
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88) 
    at com.sun.proxy.$Proxy296.execute(Unknown Source) 
    at com.surebetfinder.logic.processi.__EJB31_Generated__WorkerPool__Intf____Bean__.execute(Unknown Source) 
    at com.surebetfinder.timer.BetFinderTimerService.doWork(BetFinderTimerService.java:19) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081) 
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153) 
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786) 
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656) 
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822) 
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608) 
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:55) 
    at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883) 
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822) 
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608) 
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163) 
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundTimeout(SystemInterceptorProxy.java:145) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883) 
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822) 
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369) 
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758) 
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746) 
    at com.sun.ejb.containers.BaseContainer.callEJBTimeout(BaseContainer.java:4051) 
    at com.sun.ejb.containers.EJBTimerService.deliverTimeout(EJBTimerService.java:1199) 
    at com.sun.ejb.containers.EJBTimerService.access$000(EJBTimerService.java:89) 
    at com.sun.ejb.containers.EJBTimerService$TaskExpiredWork.run(EJBTimerService.java:1919) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB 
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:700) 
    at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:246) 
    at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:430) 
    ... 46 more 
Caused by: javax.ejb.CreateException: Could not create stateless EJB 
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:514) 
    at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:97) 
    at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:698) 
    ... 48 more 
Caused by: java.lang.IllegalStateException: Exception attempting to inject Remote ejb-ref name=com.surebetfinder.logic.processi.WorkerPool/executor,Remote 3.x interface =java.util.concurrent.Executor,ejb-link=null,lookup=,mappedName=,jndi-name=java.util.concurrent.Executor,refType=Session into class com.surebetfinder.logic.processi.WorkerPool: Lookup failed for 'java:comp/env/com.surebetfinder.logic.processi.WorkerPool/executor' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} 
    at org.glassfish.weld.services.InjectionServicesImpl.aroundInject(InjectionServicesImpl.java:175) 
    at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:46) 
    at org.jboss.weld.injection.producer.DefaultInjector.inject(DefaultInjector.java:68) 
    at org.jboss.weld.injection.producer.StatelessSessionBeanInjector.inject(StatelessSessionBeanInjector.java:58) 
    at org.jboss.weld.injection.producer.ejb.SessionBeanInjectionTarget.inject(SessionBeanInjectionTarget.java:117) 
    at org.glassfish.weld.services.JCDIServiceImpl.injectEJBInstance(JCDIServiceImpl.java:257) 
    at com.sun.ejb.containers.BaseContainer.injectEjbInstance(BaseContainer.java:1748) 
    at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:475) 
    ... 50 more 
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=com.surebetfinder.logic.processi.WorkerPool/executor,Remote 3.x interface =java.util.concurrent.Executor,ejb-link=null,lookup=,mappedName=,jndi-name=java.util.concurrent.Executor,refType=Session into class com.surebetfinder.logic.processi.WorkerPool: Lookup failed for 'java:comp/env/com.surebetfinder.logic.processi.WorkerPool/executor' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} 
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:740) 
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:507) 
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:170) 
    at org.glassfish.weld.services.InjectionServicesImpl.aroundInject(InjectionServicesImpl.java:165) 
    ... 57 more 
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/com.surebetfinder.logic.processi.WorkerPool/executor' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=com.surebetfinder.logic.processi.WorkerPool/executor,Remote 3.x interface =java.util.concurrent.Executor,ejb-link=null,lookup=,mappedName=,jndi-name=java.util.concurrent.Executor,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'java.util.concurrent.Executor#java.util.concurrent.Executor' [Root exception is javax.naming.NamingException: Lookup failed for 'java.util.concurrent.Executor#java.util.concurrent.Executor' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: java.util.concurrent.Executor#java.util.concurrent.Executor not found]]] 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:491) 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:438) 
    at javax.naming.InitialContext.lookup(InitialContext.java:417) 
    at javax.naming.InitialContext.lookup(InitialContext.java:417) 
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:636) 
    ... 60 more 
Caused by: javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=com.surebetfinder.logic.processi.WorkerPool/executor,Remote 3.x interface =java.util.concurrent.Executor,ejb-link=null,lookup=,mappedName=,jndi-name=java.util.concurrent.Executor,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'java.util.concurrent.Executor#java.util.concurrent.Executor' [Root exception is javax.naming.NamingException: Lookup failed for 'java.util.concurrent.Executor#java.util.concurrent.Executor' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: java.util.concurrent.Executor#java.util.concurrent.Executor not found]] 
    at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:188) 
    at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl$EjbReferenceProxy.create(ComponentEnvManagerImpl.java:1015) 
    at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:745) 
    at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:715) 
    at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:159) 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:471) 
    ... 64 more 
Caused by: javax.naming.NamingException: Lookup failed for 'java.util.concurrent.Executor#java.util.concurrent.Executor' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: java.util.concurrent.Executor#java.util.concurrent.Executor not found] 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:491) 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:438) 
    at javax.naming.InitialContext.lookup(InitialContext.java:417) 
    at javax.naming.InitialContext.lookup(InitialContext.java:417) 
    at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:183) 
    ... 69 more 
Caused by: javax.naming.NameNotFoundException: java.util.concurrent.Executor#java.util.concurrent.Executor not found 
    at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:237) 
    at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:204) 
    at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:66) 
    at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:114) 
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:478) 
    ... 73 more 
]] 

Где я ошибаюсь?

+1

@EJB частный Исполнитель Исполнителя; (Исполнитель не входит в EJB) –

ответ

0

Как Гавриил говорит, когда вы пишете

@EJB 
    private Executor executor; 

вы рассказываете контейнер чем Executor является EJB локальный или удаленный интерфейс, а контейнер не удается смотреть этот интерфейс в JNDI.

Попробуйте это:

@EJB 
    private ThreadExecutor executor; 

Это просит "не интерфейс" вид компонента вместо этого. Кроме того, вы можете написать свой собственный интерфейс до ThreadExecutor.

(Помимо этого, строго говоря, это поведение регулируется разделом 4.9.7-4.9.8 спецификации EJB 3.1, и я не думаю, что вы нарушили какие-либо правила, которые он излагает, поэтому это может быть неправильным поведением от Glassfish?)

Это, я думаю, ваша реализация ThreadExecutor асинхронно создает пул потоков и откручивает поток для выполнения работы, которая, как я считаю, является излишней. Почему бы просто не сделать WorkerThread в EJB с помощью метода @Asynchronous?

Смежные вопросы