Using a CommonJ implementation with GlassFish and

2020-06-04 11:00发布

问题:

In my quest to unify deployment among Websphere 7 and GlassFish 3 environments, I decided to try implementing a CommonJ WorkManager and TimerManager in GlassFish. But it isn't quite working as expected. I have done the following:

Use the myFOO CommonJ implementation found at: http://commonj.myfoo.de/ and include the libraries into my domain/lib folder (including the Spring libs)

Added the following to the <resources> section of the glassfish domain.xml:

<custom-resource res-type="commonj.work.WorkManager" jndi-name="wm/default" factory-class="de.myfoo.commonj.work.FooWorkManagerFactory"></custom-resource>
<custom-resource res-type="commonj.timers.TimerManager" jndi-name="tm/default" factory-class="de.myfoo.commonj.timers.FooTimerManagerFactory"></custom-resource>

Include the references in the <servers>/<server> section of the domain.xml:

  <resource-ref ref="wm/default"></resource-ref>
  <resource-ref ref="tm/default"></resource-ref>

Add the appropriate resource references in the web.xml of my test application:

<resource-ref>
    <description>WorkManager</description>
    <res-ref-name>wm/default</res-ref-name>
    <res-type>commonj.work.WorkManager</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

<resource-ref>
    <description>TimerManager</description>
    <res-ref-name>tm/default</res-ref-name>
    <res-type>commonj.timers.TimerManager</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>

Add the following beans to my applicationContext.xml:

<bean id="threadTestTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor"> 
    <property name="workManagerName" value="wm/default" />
    <property name="resourceRef" value="true"/>
</bean>

<bean id="threadTestTimerExecutor" class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler"> 
    <property name="timerManagerName" value="tm/default" />
    <property name="resourceRef" value="true" />
    <property name="shared" value="false" />
</bean>

<bean id="threadTest" class="test.ThreadTester"></bean>

<task:scheduled-tasks scheduler="threadTestTimerExecutor">
    <task:scheduled ref="threadTest" method="execute" fixed-delay="30000" />  <!-- 30 seconds -->
</task:scheduled-tasks>

After all of this set-up, everything loads find and the web application runs; however, the ThreadTester class does not run on the Timer.

I have stepped through the myFOO code and the TimerManager (FooTimerManager.java) main loop is running, it just never seems to recognize that every 30 seconds it's supposed to launch the class.

My questions:

Has anyone had experience implementing JSR 236/237 (CommonJ) with GlassFish 3 and Spring?

Is there another implementation somewhere other than myFOO that I could use and try out? Has anyone attempted to do what I've done? Would you be willing to share your results if you succeeded?

Thanks!

Edit 1:

I forgot to mention that using myFOO CommonJ implementation with GlassFish does work as far as the WorkManager is concerned. What does not work is the TimerManager. This means that I can launch threads on demand just fine but triggered scheduling doesn't work.

Edit 2:

Since updating to GlassFish 3.1.1, the myFOO CommonJ implementation of the TimerManager is working fine. So... great! This question is now more like a HOWTO Guide.

回答1:

I don't think it's a good idea to use the TimerManager of myFoo CommonJ - in addition to being dormant for about 6 years, the code is just strange at some points (referring to v1.1). E.g. the isExpired method of the FooTimer class looks like this:

public boolean isExpired() {
    return scheduledExcecutionTime >= System.currentTimeMillis();
}

So, the timer will expire when its scheduled next execution time is in the future? Nonsense - that should be the other way round!

Somewhere else (TimerExecutor#run), notifyAll is called on an object (TimerManager) that the current thread has no monitor for, constantly causing java.lang.IllegalMonitorStateExceptions.

Hands off!



回答2:

If you're working in Spring, why are you using another Timer implementation? Why not just use the Spring scheduling integration? Then you don't need to worry about in which server your app is running, as Spring doesn't care.



回答3:

Well, it looks like that since updating to GlassFish 3.1.1, I no longer have the problem with the myFOO implementation of the TimerManager. My @Scheduled beans are working just fine now.