我想在服务器启动时启动一个线程。我的线程从db中提取数据并将其放入JMS队列中。所有bean都在Spring配置文件中定义。在weblogic上配置JMS队列和数据库连接工厂(CONNECTION-FACTORY)。
我正在尝试将我的线程启动代码放在contextInitialized
ContextLoaderListener
方法或init
servlet
方法中。但是,我在启动服务器时遇到异常 :
嵌套异常是 javax.naming.NoPermissionException: 用户匿名没有 CONNECTION-FACTORY的许可 执行查找操作。
如果我将它放在Servlet的doGet方法中并在服务器启动后点击url,我的代码就可以正常工作。但是我不想手动启动线程。
我认为我收到此错误是因为所有bean都没有正确初始化。
我在哪里放置代码,以便线程在服务器启动后自动启动?
答案 0 :(得分:4)
如果您正在创建自己的线程,则很可能是问题所在。在任何应用程序服务器中,您应该让容器管理线程池,并且只安排您可能想要运行的任何作业。
将此添加到您的web.xml:
<resource-ref>
<res-ref-name>timer/MyTimer/res-ref-name>
<res-type>commonj.timers.TimerManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
在applicationContext.xml中(需要spring-context-support JAR):
<bean id="scheduler" class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler" scope="singleton">
<property name="timerManagerName" value="java:comp/env/timer/MyTimer"/>
</bean>
然后在你的contextInitialized(...)中执行:
scheduledFuture = scheduler.schedule(new MyJob());
在你的contextDestroyed(...)中;
scheduledFuture.cancel(true);
在我的项目中,我找不到任何关于在应用程序服务器级别配置计时器的信息,所以我猜它“正常”。
如果要异步生成作业(通过java.lang.concurrent.Executor
接口),过程类似,但需要在Weblogic中配置线程池:
在web.xml中;
<resource-ref>
<res-ref-name>wm/MyWorkManager</res-ref-name>
<res-type>commonj.work.WorkManager</res-type>
<res-auth>Container</res-auth>
</resource-ref>
在applicationContext.xml中:
<bean id="executor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor" scope="singleton">
<property name="workManagerName" value="java:comp/env/wm/MyWorkManager"/>
</bean>
在您的weblogic.xml(或EAR的等效文件)中,类似于:
<work-manager>
<name>wm/MyWorkManager</name>
<min-threads-constraint>
<name>minThreads</name>
<count>1</count>
</min-threads-constraint>
<max-threads-constraint>
<name>maxThreads</name>
<count>20</count>
</max-threads-constraint>
</work-manager>
在您的代码中:
executor.execute(new MyRunnable());
阅读Weblogic docs on timers and work managers以获取有关此特定应用服务器的更多作业调度相关信息。
答案 1 :(得分:-1)
为此找到解决方案。对于例外javax.naming.NoPermissionException
,我们应该向weblogic.xml
添加以下行。它使用用户初始化webapp并在部署中启用JNDI查找
<weblogic-web-app>
<context-root>testApp</context-root>
<servlet-descriptor>
<servlet-name>SchedulerServlet</servlet-name>
<init-as-principal-name>tour_weblogic_user_name</init-as-principal-name>
</servlet-descriptor>
</weblogic-web-app>