Problems
Summary
- Spring creates a separate threads to handle schedulers , but most of J2EE container vendors like websphere , weblogic ..etc doesn't support the threads created outside of containers. (These are threads called unmanaged threads)
- Following exception was thrown when we try to lookup the objects directly using javax.naming.initialContext . (We have JAX-RPC webservices client code that is generated by RAD using WSDL , which is auto generated code has the direct initial context lookups)
Exception
Occured
javax.naming.ConfigurationException: A JNDI
operation on a "java:" name cannot be completed because the server
runtime is not able to associate the operation's thread with any J2EE
application component. This condition
can occur when the JNDI client using the "java:" name is not executed
on the thread of a server application request.
Make sure that a J2EE application does not execute JNDI operations on
"java:" names within static code blocks or in threads created by that
J2EE application. Such code does not
necessarily run on the thread of a server application request and therefore is
not supported by JNDI operations on "java:" names. [Root exception is
javax.naming.NameNotFoundException: Name "com/env/url/testrouce"
Explanation
and solution
IBM clearly states
that don't create unmanaged threads (this is true with most of J2EE container
vendors), for the following reasons:
- The application server does not recognize unmanaged threads.
- Unmanaged threads do not have access to Java EE contextual information.
- Unmanaged threads can use resources without being monitored by the application server.
- Unmanaged threads can adversely affect application server functions such as shutting down gracefully or recovering resources from failure.
- An administrator cannot control the number of unmanaged threads or their use of resources.
Spring
Framework Support
Spring framework
does provide a package with scheduling classes based on CommonJ
WorkManager/TimerManager that supported by IBM Websphere 6.0+ and BEA weblogic
9.0+. Spring Commonj classes link is
provided in references section.
Steps
to create websphere compliant task scheduler
- Create a task (That implements the runnable interface)
- Add the Websphere timer Manager reference in the web.xml and ibm-web-bnd.xmi
- Configure task at specific intervals in the SpringContext.xml
Step1:
Create task
public
class TestTask implements Runnable {
public
void run() {
//your
work to be executed
}
}
Step
2: add websphere timer manager references in project
In Web.xml
<resource-ref>
<description>TimerManager</description
>
<res-ref-name>timerManager</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 ibm-web-bnd.xml
<resource-ref
name="timerManager" binding-name="tm/default"
></resource-ref>
Step
3: configure scheduler
<bean
id="testTask"
class="com.sivavaka.test.spring.scheduler.TestTask">
</bean>
<bean id=
"timerScheduler"
class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler"
>
<property name="resourceRef"
value="true"/>
<property
name="timerManagerName" value="timerManager"/>
</bean>
<!-- To schedule
job for every one hour then cron will be "0 0 0/1 * * ?" -->
<!-- Websphere
Compliant Thread :: Runs for every 5 mins -->
<task:scheduled-tasks
scheduler="timerScheduler" >
<task:scheduled
ref="testTask" method="run" cron="0 0/5 * * * ?"
/>
</task:scheduled-tasks
>
If you create the
scheduler like above , you can see the WebSphere Runtime available to thread
that executes this task , basically it is WebSphere managed thread
But if you use the
Spring's task scheduler directly (I mean without using the websphere
timemanager), thread that executes this task doesn't have access the Websphere
Runtime causing the J2EE container services are not available.
References
- http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.nd.multiplatform.doc/info/ae/ae/cspr_design.html
- Workmanagers (http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/com.ibm.websphere.nd.multiplatform.doc/info/ae/asyncbns/concepts/casb_workmgr.html)
- http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/scheduling/commonj/package-summary.html
Download/Browse
the Sample Code
- To download sample code war file (https://sourceforge.net/projects/blog-sivavaka-com-code-samples/files/WebSphere%20Compliant%20Spring%20Task%20Scheduler/)
- To browser the sample code (https://code.google.com/p/blog-sivavaka-com-code-samples/source/browse/#svn%2Ftrunk%2FSivaTestSpringScheduler)