在Weblogic中使用Spring在服务器启动时启动线程

3
我想开始一个有关服务器启动的线程。我的线程从数据库中提取数据并将其放入JMS队列中。所有的bean都在Spring配置文件中定义。JMS队列和DB连接工厂(CONNECTION-FACTORY)在weblogic上进行配置。
我试图将我的线程启动代码放在ContextLoaderListener的contextInitialized方法或servlet的init方法中。但是,在启动服务器时,我遇到了以下异常:
nested exception is javax.naming.NoPermissionException: User anonymous does not have permission on CONNECTION-FACTORY to perform lookup operation.
如果我将代码放在Servlet的doGet方法中,并在服务器启动后访问URL,则我的代码可以完美地运行。然而,我不想手动启动线程。
我认为我之所以会出现这个错误是因为所有的bean没有被正确地初始化。
我应该在哪里放置我的代码,以便线程在服务器启动后自动启动?
2个回答

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关于计时器和工作管理器的文档,可以获取更多关于该特定应用服务器的作业调度相关信息。


它仍然失败了...在服务器启动时就失败了。我的代码不是在运行时失败,而是在初始化时的bean创建时失败。 - Pranalee
已在查询中附加了堆栈跟踪。 - Pranalee

-1
找到了解决方案。对于异常javax.naming.NoPermissionException,我们应该在weblogic.xml中添加以下行。它使用用户初始化Web应用程序并在部署时启用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> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接