Announcement Announcement Module
Collapse
No announcement yet.
WebSphere: unmanaged thread spawned by <si-jdbc:inbound-channel-adapte> Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • WebSphere: unmanaged thread spawned by <si-jdbc:inbound-channel-adapte>

    Environment:
    WAS 8.0.0.2
    Spring 3.1.1
    Spring Integration 2.1.2
    Hibernate: 4.1.4

    We have a simple requirement that records from a staging table are polled using <si-jdbc:inbound-channel-adapter>, and after going through some SI endpoints through "direct channels", they will be persisted to DB2 tables using Hibernate.

    Some relevant codes are posted here:
    Code:
    <bean id="txManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
    
    <si-jdbc:inbound-channel-adapter query="select records" update="delete records" channel="stagingChannel" data-source="stagingDataSource">
      <si:poller task-executor="wmTaskExecutor" max-messages-per-poll="1" fixed-delay="60000">
        <si:transactional transaction-manager="txManager" propagation="REQUIRED" read-only="false" />
      </si:poller>
    </si-jdbc:inbound-channel-adapter>
    
    <bean id="wmTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
      <property name="workManagerName" value="wm/default" />
      <property name="resourceRef" value="true" />
    </bean>
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
      <property name="hibernateProperties">
        <props>
          ...
          <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform</prop>
          <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
        </props>			
      </property>
    </bean>
    When the persistent code reaches Hibernate, we are getting following errors:
    Code:
    Caused by: org.hibernate.service.jndi.JndiException: Unable to lookup JNDI name [java:comp/websphere/ExtendedJTATransaction]
    	at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:68)
    	at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJtaPlatform.java:156)
    	at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.<init>(WebSphereExtendedJtaPlatform.java:152)
    	at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getTransaction(WebSphereExtendedJtaPlatform.java:124)
    	at org.hibernate.context.internal.JTASessionContext.currentSession(JTASessionContext.java:86)
    	at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:90)
    	at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1041)
    
    Caused by: 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 comp/websphere not found in context "java:".]
    We are thinking the reason is that the inbound-channel-adapter thread is spawned by Spring, even though it is using WAS WorkManager to poll the database record. The WAS worker thread, therefore, doesn't have many JEE container context propogated, thus the JNDI look up fails.

    We were thinking to change the Hibernate to 3.6.10, which then we can use LocalSessionFactoryBean.setJtaTransactionManager() to inject the UOW transactionManager to bypass the JNDI lookup, but it turns out that WebSphereUowTransactionManager.getTransactionManag er() always return NULL. Thus, Hibernate will use JDBC transaction.

    Is there any workaround? Is it true that SI inbound-channel-adapter will most likely spawn application server unmanaged thread?

    Thanks.
    Last edited by jav01_2000; Jul 10th, 2012, 08:50 AM.

  • #2
    Using a WMTE should avoid this; can you run with DEBUG logging, and be sure to include the thread name (%t in Log4J) in the pattern?

    Comment


    • #3
      Gary, what WMTE stands for? BTW, we are already using WorkManager provided by WAS.

      In the log:
      Code:
      2012-07-04 10:55:33,946 ERROR [WorkManager.wmWorkManager : 0] o.s.integration.handler.LoggingHandler [LoggingHandler.java:126] org.springframework.integration.MessageHandlingException: org.hibernate.service.jndi.JndiException: Unable to lookup JNDI name [java:comp/websphere/ExtendedJTATransaction]
      	at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:76)
      	at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:67)
      	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:97)
      	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
      	at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:120)
      ...
      Last edited by jav01_2000; Jul 6th, 2012, 03:00 PM.

      Comment


      • #4
        WMTE is just my shorthand for WorkManagerTaskExecutor, which you are using in your poller.

        I'd like to see DEBUG logs leading up to the error, but it does look like the exception is occurring on an WMTE thread ...

        Code:
        2012-07-04 10:55:33,946 ERROR  [WorkManager.wmWorkManager : 0] ...
        ... in which case, I have no idea why WAS is complaining.

        Comment


        • #5
          Do you agree SI spawn unmanaged threads for some cases? These threads have no JEE container context, so maybe that is why the context is not propogated to the WorkManager threads, which is managed by WAS.

          Comment


          • #6
            No; it shouldn't. There is a global task scheduler, but once you provide a TE to your poller, the scheduler thread hands off to that container-managed TE and shouldn't interact with the container at all.

            That's why I need to see a log.

            You can replace that scheduler with a TimerManagerTaskScheduler (just give it a bean name of 'taskScheduler' and Spring Integration won't create the default one).

            But, as I said, with your configuration, I would not expect it to interact with the container at all.

            Comment


            • #7
              Gary,
              do you have example of how to configure TimerManagerTaskScheduler as the starting thread of SI?

              Again, we are facing the problem of not able to do JNDI lookup for "java:comp/websphere/ExtendedJTATransaction" in the WAS worker thread. We think it is because the starting thread of the "poller" is not WAS thread, so the context is not propogated to WAS worker thread - even the worker thread is managed by WAS.

              Comment


              • #8
                It's similar to your WMTE http://static.springsource.org/sprin...Scheduler.html

                Just set the timerManaagerName and resourceRef as before; just give it an id="taskScheduler"; then S.I. will use it instead of the default.

                Comment


                • #9
                  Thank you so much, Gary!
                  This resolved the problem. Worker thread is able to lookup "java:comp/websphere/ExtendedJTATransaction".

                  Code:
                  <bean id="taskScheduler" class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler">
                    <property name="timerManagerName" value="tm/default" />
                    <property name="resourceRef" value="true" />
                  </bean>
                  On the other hand, I feel http://static.springsource.org/sprin...-taskscheduler needs to be refined to add some reasons for overwriting the default "taskScheduler" provided by SI, for example, to avoid spawning unmanaged threads.

                  Comment


                  • #10
                    I agree; please go ahead and open an Improvement JIRA here https://jira.springsource.org/browse/INT

                    Please set the component to 'Documentation' and add a reference to this forum post.

                    Thanks.

                    Comment

                    Working...
                    X