3

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

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

如果我把它放在 Servlet 的 doGet 方法中并在服务器启动后点击 url,我的代码就可以完美运行。但是我不想手动启动线程。

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

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

4

2 回答 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());

在你的上下文中Destroyed(...) 做;

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 文档,了解有关此特定应用服务器的更多作业调度相关信息。

于 2012-11-30T09:01:13.757 回答
-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> 
于 2012-12-04T09:57:24.493 回答