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

时间:2012-11-30 07:23:39

标签: java multithreading spring weblogic

我想在服务器启动时启动一个线程。我的线程从db中提取数据并将其放入JMS队列中。所有bean都在Spring配置文件中定义。在weblogic上配置JMS队列和数据库连接工厂(CONNECTION-FACTORY)。 我正在尝试将我的线程启动代码放在contextInitialized ContextLoaderListener方法或init servlet方法中。但是,我在启动服务器时遇到异常

  

嵌套异常是   javax.naming.NoPermissionException:   用户匿名没有   CONNECTION-FACTORY的许可   执行查找操作。

如果我将它放在Servlet的doGet方法中并在服务器启动后点击url,我的代码就可以正常工作。但是我不想手动启动线程。

我认为我收到此错误是因为所有bean都没有正确初始化。

我在哪里放置代码,以便线程在服务器启动后自动启动?

2 个答案:

答案 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>