Announcement Announcement Module
Collapse
No announcement yet.
Spring + Quartz + JNDI in WebSphere - problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring + Quartz + JNDI in WebSphere - problem

    In my project we have created a separate scheduler web application (single WAR) to execute asynchronous jobs. It is based on Spring+Quartz integration. We are using org.springframework.scheduling.quartz.SchedulerFac toryBean with CommonJ TaskExecutor. The relevant configuration is listed below:

    Code:
    <bean id="adssSchedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    				<property name="dataSource">
    					<ref bean="(data source bean)"/>
    				</property>
    		
    				<property name="configLocation">
    					(...)
    				</property>
    				
    				<property name="triggers">
    					<list>
    						(list of triggers)
    					</list>
    				</property>
    				
    			   <property name="taskExecutor" ref="commonJTaskExecutor"></property>
    	</bean>
    	<bean id="commonJTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
       		<property name="workManagerName" value="wm/default"/>
       		<property name="resourceRef" value="false"/>
    	</bean>
    The environment is WebSphere Application Server 6.1. One of the scheduled jobs makes use of JNDI WebService resource defined in the deployment descriptor:

    Code:
    <service-ref>
        <description>WSDL Service DETValidAddQuoteAutoGFB</description>
        <service-ref-name>service/DETValidAddQuoteAutoGFBService</service-ref-name>
        <service-interface>hu.ahbrt.hws.services.DETValidAddQuoteAutoGFBService</service-interface>
        <wsdl-file>WEB-INF/wsdl/DETValidAddQuoteAutoGFB.wsdl</wsdl-file>
        <jaxrpc-mapping-file>WEB-INF/DETValidAddQuoteAutoGFB_mapping.xml</jaxrpc-mapping-file>
        <service-qname xmlns:pfx=...">pfx:DETValidAddQuoteAutoGFBService</service-qname>
        <port-component-ref>
          <service-endpoint-interface>hu.ahbrt.hws.services.DETValidAddQuoteAutoGFB</service-endpoint-interface>
        </port-component-ref>
      </service-ref>
    When the job gets executed, a javax.naming.ConfigurationException occurs. Below the relevant part of stack trace:

    Code:
    [10/9/08 14:31:36:189 CEST] 0000054c javaURLContex E   NMSV0310E: 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. Exception stack trace: 
    javax.naming.ConfigurationException [Root exception is javax.naming.NameNotFoundException: Name comp/env/service not found in context "java:".]
    	at com.ibm.ws.naming.java.javaURLContextImpl.throwConfigurationExceptionWithDefaultJavaNS(javaURLContextImpl.java:411)
    	at com.ibm.ws.naming.java.javaURLContextImpl.lookup(javaURLContextImpl.java:388)
    	at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:204)
    	at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:144)
    	at javax.naming.InitialContext.lookup(InitialContext.java:363)
    	at 
    (our code using the JNDI handle...)
    
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:615)
    	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:304)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:139)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    	at org.springframework.orm.hibernate3.HibernateInterceptor.invoke(HibernateInterceptor.java:104)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:203)
    	at $Proxy405.sendPolicyToOPUS(Unknown Source)
    	at com.adss.hu.scheduler.jobs.OPUSPutPolicyJobHU.doExecuteInternal(OPUSPutPolicyJobHU.java:53)
    	at com.adss.scheduler.jobs.AbstractAdssJob.processJobExecution(AbstractAdssJob.java)
    	at com.adss.scheduler.jobs.AbstractAdssJob.execute(AbstractAdssJob.java)
    	at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
    	at org.springframework.scheduling.commonj.DelegatingWork.run(DelegatingWork.java:61)
    	at com.ibm.ws.asynchbeans.J2EEContext$RunProxy.run(J2EEContext.java:255)
    	at java.security.AccessController.doPrivileged(AccessController.java:214)
    	at javax.security.auth.Subject.doAs(Subject.java:495)
    	at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:118)
    	at com.ibm.ws.asynchbeans.J2EEContext$DoAsProxy.run(J2EEContext.java:326)
    	at java.security.AccessController.doPrivileged(AccessController.java:241)
    	at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1109)
    	at com.ibm.ws.asynchbeans.WorkWithExecutionContextImpl.go(WorkWithExecutionContextImpl.java:195)
    	at com.ibm.ws.asynchbeans.CJWorkItemImpl.run(CJWorkItemImpl.java:187)
    	at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1469)
    Caused by: javax.naming.NameNotFoundException: Name comp/env/service not found in context "java:".
    	at com.ibm.ws.naming.ipbase.NameSpace.getParentCtxInternal(NameSpace.java:1767)
    	at com.ibm.ws.naming.ipbase.NameSpace.lookupInternal(NameSpace.java:1083)
    	at com.ibm.ws.naming.ipbase.NameSpace.lookup(NameSpace.java:991)
    	at com.ibm.ws.naming.urlbase.UrlContextImpl.lookup(UrlContextImpl.java:1263)
    	at com.ibm.ws.naming.java.javaURLContextImpl.lookup(javaURLContextImpl.java:384)
    	... 36 more
    Obviously (root of the stack) the job is run within a managed thread from WAS default thread pool. Now, what I don't understand is why a JNDI resource cannot be accessed from within a managed thread (the documentation says that the context should be propagated to the executing thread from pool). My vague suspicion is that it is somehow caused by the fact that the scheduling thread is Quartz's own thread (I see it when debugging the server instance) and because of that the J2EE context is not properly propagated to the executing thread...? But then, is it not possible at all to access the JNDI context resources in this kind of scenario?

  • #2
    Same with JMS

    Strangely enough, today I'm having the same problem...Please bear with me if in my case it does not apply directly to Quartz.

    I'm using Spring JMS to consume messages (configuration follows) and the consumer needs to perform a JNDI lookup of a resource, which is referenced in the deployment descriptor.

    Note that the problem occurs using a WAS-managed threadpool, not with self-managed threads. The only hint that I have is that these threads do not belong to the web application context that defines the resource-ref 's.

    context snippet:

    Code:
    <jee:jndi-lookup id="cobroQ" jndi-name="jms/CobroTasaInQueue"/>
    <jee:jndi-lookup id="workManager" jndi-name="wm/pagoWm" resource-ref="true" />
    
            <bean id="wasDefaultWorkManager" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
                    <property name="workManager" ref="workManager" />
            </bean>
    	
            <bean id="wasSIBJMSResourceAdapter" class="org.springframework.jca.support.ResourceAdapterFactoryBean">
                    <property name="resourceAdapter">
                            <bean class="com.ibm.ws.sib.api.jmsra.impl.JmsJcaResourceAdapterImpl"/>
                    </property>
                    <property name="workManager">
                            <bean class="org.springframework.jca.work.SimpleTaskWorkManager">
                                    <property name="asyncTaskExecutor" ref="wasDefaultWorkManager" />
                            </bean>
                    </property>
            </bean>
    	
    	
            <bean class="org.springframework.jms.listener.endpoint.JmsMessageEndpointManager">
                    <property name="resourceAdapter" ref="wasSIBJMSResourceAdapter"/>
                    <property name="activationSpec">
                            <bean class="com.ibm.ws.sib.api.jmsra.impl.JmsJcaActivationSpecImpl">
                                    <property name="destination" ref="cobroQ"/>
                                    <property name="destinationType" value="javax.jms.Queue"/>
                                    <property name="busName" value="PAGO"/>
                                    <property name="maxConcurrency" value="5"/>
                            </bean>
                    </property>
                    <property name="messageListener" ref="cobroTasaInMessageListener"/>
            </bean>
    web.xml:

    Code:
    	
    	<resource-ref id="ResourceRef_1217256917736">
    		<description>
    		</description>
    		<res-ref-name>eis/host</res-ref-name>
    		<res-type>javax.resource.cci.ConnectionFactory</res-type>
    		<res-auth>Container</res-auth>
    		<res-sharing-scope>Shareable</res-sharing-scope>
    	</resource-ref>
    I don't deploy was specific deployment descriptors. The "eis/host" resource is looked up fine when the lookup is done within a [WebContainer] thread.

    Environment:
    • Spring: 2.5
    • WAS: 6.1.0.15

    The trace looks as follows:

    Code:
    [Root exception is javax.naming.NameNotFoundException: Name comp/env/eis not found in context "java:".]
            at com.ibm.ws.naming.java.javaURLContextImpl.throwConfigurationExceptionWithDefaultJavaNS(javaURLContextImpl.java:411)
            at com.ibm.ws.naming.java.javaURLContextImpl.lookup(javaURLContextImpl.java:388)
            at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:204)
            at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:144)
            at javax.naming.InitialContext.lookup(InitialContext.java:351)
            at es.trafico.ccom.host.CHost.exec(CHost.java:167)
            at es.trafico.ccom.host.CHostOperation.getXML(CHostOperation.java:167)
            at es.trafico.pago.tasa.neg.host.operacion.CHostOperationAdapter.ejecuta(CHostOperationAdapter.java:123)
            at es.trafico.pago.tasa.neg.host.ServicioHostSincrono.anotarJustificante(ServicioHostSincrono.java:57)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:585)
            at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
            at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:54)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:160)
            at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:54)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:160)
            at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:160)
            at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
            at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
            at $Proxy183.anotarJustificante(Unknown Source)
            at es.trafico.pago.tasa.neg.jms.listener.AnotarJustificanteInAction.execute(AnotarJustificanteInAction.java:37)
            at es.trafico.pago.tasa.neg.jms.listener.MessageEventHandler.onMessage(MessageEventHandler.java:45)
            at org.springframework.jms.listener.endpoint.JmsMessageEndpointFactory$JmsMessageEndpoint.onMessage(JmsMessageEndpointFactory.java:83)
            at com.ibm.ws.sib.api.jmsra.impl.JmsJcaEndpointInvokerImpl.invokeEndpoint(JmsJcaEndpointInvokerImpl.java:201)
            at com.ibm.ws.sib.ra.inbound.impl.SibRaDispatcher.dispatch(SibRaDispatcher.java:768)
            at com.ibm.ws.sib.ra.inbound.impl.SibRaSingleProcessListener$SibRaWork.run(SibRaSingleProcessListener.java:584)
            at org.springframework.jca.work.SimpleTaskWorkManager$DelegatingWorkAdapter.run(SimpleTaskWorkManager.java:232)
            at org.springframework.scheduling.commonj.DelegatingWork.run(DelegatingWork.java:61)
            at com.ibm.ws.asynchbeans.J2EEContext$RunProxy.run(J2EEContext.java:257)
            at java.security.AccessController.doPrivileged(Native Method)
            at javax.security.auth.Subject.doAs(Subject.java:337)
            at com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:118)
            at com.ibm.ws.asynchbeans.J2EEContext$DoAsProxy.run(J2EEContext.java:328)
            at java.security.AccessController.doPrivileged(Native Method)
            at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1111)
            at com.ibm.ws.asynchbeans.WorkWithExecutionContextImpl.go(WorkWithExecutionContextImpl.java:195)
            at com.ibm.ws.asynchbeans.CJWorkItemImpl.run(CJWorkItemImpl.java:187)
            at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1473)
    Caused by: javax.naming.NameNotFoundException: Name comp/env/eis not found in context "java:".
            at com.ibm.ws.naming.ipbase.NameSpace.getParentCtxInternal(NameSpace.java:1767)
            at com.ibm.ws.naming.ipbase.NameSpace.lookupInternal(NameSpace.java:1083)
            at com.ibm.ws.naming.ipbase.NameSpace.lookup(NameSpace.java:991)
            at com.ibm.ws.naming.urlbase.UrlContextImpl.lookup(UrlContextImpl.java:1263)
            at com.ibm.ws.naming.java.javaURLContextImpl.lookup(javaURLContextImpl.java:384)
            ... 42 more

    Comment


    • #3
      Originally posted by drvillo View Post

      I don't deploy was specific deployment descriptors. The "eis/host" resource is looked up fine when the lookup is done within a [WebContainer] thread.

      Environment:
      • Spring: 2.5
      • WAS: 6.1.0.15

      Same for me. I am able to retrieve the resource as Spring bean using org.springframework.jndi.JndiObjectFactoryBean at application startup (context created). But retrieval fails in case of asynchronous managed thread from pool.

      I use Spring 2.0.4.

      Comment


      • #4
        For what is worth I circumvented the problem and made so that the JNDI lookup is performed by the client code, thus passing the managed object to the code executing in the threadpool. You might want to do the same.

        By the way: I don't think this is a Spring issue.

        cheers
        Francesco

        Comment


        • #5
          Originally posted by drvillo View Post
          For what is worth I circumvented the problem and made so that the JNDI lookup is performed by the client code, thus passing the managed object to the code executing in the threadpool. You might want to do the same.

          By the way: I don't think this is a Spring issue.
          Could you elaborate on that? I am having very much the same problems, but I wonder how I could pass the managed object to a spring bean.

          Comment


          • #6
            Thread outside of the J2EE container

            The issue here is that Quartz is executing a thread outside the control of the container. The method you hooked up for Quartz to execute when your trigger is fired is now a part of this outside thread and thus you receive the following error:

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

            I found that all I needed to do was move the code that fetches the enviroment variables outside of the method and since I was not invoking the method from a web application, the only other place I could put it was in the constructor of the class of my method. This solved my issue and I was able to fetch the environments variables using the following code:

            Code:
            Context env = (Context) new InitialContext().lookup("java:comp/env");
            String envDevTestProd = (String) env.lookup("DevTestProdKey");

            Comment

            Working...
            X