Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

start thread on server startup in weblogic using Spring

I want to start a thread on server startup. My thread pulls data from db and put it in JMS queue. all the beans are defined in Spring config files. JMS queues and DB connection factory (CONNECTION-FACTORY)are configured on weblogic. I'm trying to put my thread starting code in contextInitialized method of ContextLoaderListener or init method of servlet. However I'm getting following exception while starting server:

nested exception is javax.naming.NoPermissionException: User anonymous does not have permission on CONNECTION-FACTORY to perform lookup operation.

My code works perfectly if i put it in doGet method of Servlet and hit the url after server startup. However I dont want to start thread manually.

I think that I'm getting this error because all the beans are not initialized properly.

Where do i put my code so that thread starts automatically after server startup?

like image 759
Pranalee Avatar asked Dec 01 '25 15:12

Pranalee


1 Answers

If you are creating your own thread that is most likely the problem. Inside any application server, you should let the container manage the thread pools and just schedule whatever jobs you may want to run.

Add this to your 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>

In your applicationContext.xml (needs 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>    

Then in your contextInitialized(...) do:

scheduledFuture = scheduler.schedule(new MyJob());

And in your contextDestroyed(...) do;

scheduledFuture.cancel(true);

In my projects I cannot find anything about configuring the timer at the application server level so I guess it "just works".

If you want to spawn jobs asynchronously (via java.lang.concurrent.Executor interface), the procedure is similar, but you need to configure a thread pool in Weblogic:

In 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>

In applicationContext.xml:

<bean id="executor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor" scope="singleton">
    <property name="workManagerName" value="java:comp/env/wm/MyWorkManager"/>
</bean>

In your weblogic.xml (or equivalent for EARs), something like:

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

And in your code:

executor.execute(new MyRunnable());

Read Weblogic docs on timers and work managers for more job scheduling related information on this particular app server.

like image 189
gpeche Avatar answered Dec 04 '25 06:12

gpeche



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!