Web框架上的Cron Scheduler的Org.springframework.jndi.JndiLookupFailureException

Sha*_*dav 2 java cron websphere spring jndi

我正在开发一个项目,我必须以固定的时间间隔调用一个函数,它使用jndi与数据库交互以提供一些值.该项目在tomcat上运行正常,但在Websphere上部署时会出现JndiLookupFailureException.但是如果我们使用使用url的手动命中来调用相同的函数,则该函数在websphere上成功执行,而不会给出jndi的任何异常.我认为问题在于cron调度程序,但没有得到确切的根本原因.

以下是详细信息:

1)web.xml

<resource-ref>
    <res-ref-name>jdbc/dummyJndi</res-ref-name>
    <res-type>oracle.jdbc.pool.OracleDataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
  </resource-ref>
Run Code Online (Sandbox Code Playgroud)

2)database.xml

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/dummyJndi" />
        <property name="lookupOnStartup" value="false" />
        <property name="cache" value="true" />
        <property name="proxyInterface" value="javax.sql.DataSource" /> 
    </bean> 
Run Code Online (Sandbox Code Playgroud)

3)scheduler.xml

<task:scheduled-tasks>
        <task:scheduled ref="sampleService" method="getData"
            cron="0 0/20 * * * ?" />
    </task:scheduled-tasks>

<bean id="sampleService"
class="com.service.SampleService">  
    </bean>
Run Code Online (Sandbox Code Playgroud)

4)Websphere上的异常

org.springframework.jndi.JndiLookupFailureException: JndiObjectTargetSource failed to obtain new target object; nested exception is 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/env/jdbc not found in context "java:".]
    at org.springframework.jndi.JndiObjectTargetSource.getTarget(JndiObjectTargetSource.java:139)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:182)
    at com.sun.proxy.$Proxy940.getConnection(Unknown Source)
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:381)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:455)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:463)
    at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:471)
    at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:476)
    at org.springframework.jdbc.core.JdbcTemplate.queryForInt(JdbcTemplate.java:485)
Run Code Online (Sandbox Code Playgroud)

Sky*_*ker 5

我提出一些建议.你可以逐一尝试.希望它可以帮到你.

建议1:

在您的database.xml中,使用

<property name="jndiName" value="jdbc/dummyJndi" />
Run Code Online (Sandbox Code Playgroud)

代替

<property name="jndiName" value="java:comp/env/jdbc/dummyJndi" />
Run Code Online (Sandbox Code Playgroud)

有时,它解决了这个问题.

资源链接:

https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000013872292


建议#2

问题:

"javax.naming.NamingException - 在上下文中找不到名称comp/env/jdbc"java:"

根本原因分析:

此异常的最可能原因是应用程序执行间接JNDI查找,但查找的资源不存在资源引用.为了提供一些背景信息,WebSphere Application Server中有两种不同类型的JNDI查找:当应用程序查找绑定到命名空间的资源的物理JNDI名称时,会发生直接或全局JNDI查找.例如,如果数据源的JNDI名称是"jdbc/myDS",则查找将如下所示:

DataSource ds = (DataSource)ctx.lookup("jdbc/myDS");
Run Code Online (Sandbox Code Playgroud)

当应用程序查找映射到物理JNDI名称的资源引用时,会发生间接或本地JNDI查找.资源引用在应用程序部署描述符中定义,Web.xml用于Web模块,ejb-jar.xml用于EJB模块,或application-client.xml用于应用程序客户端模块.例如,如果资源引用名称是"jdbc/myDSresref",则查找将如下所示:

DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/myDSresref");
Run Code Online (Sandbox Code Playgroud)

间接JNDI查找被认为是J2EE最佳实践.间接JNDI查找的优点是它使您的应用程序更易于维护.如果资源的实际JNDI名称发生更改,则不需要对应用程序进行任何更改.这是因为资源的JNDI名称存储在资源引用中,而不是存储在应用程序代码中.

如果应用程序模块中不存在资源引用,则JNDI查找将失败,并显示上面提到的javax.naming.NamingException.同样重要的是要注意间接JNDI查找只能从J2EE容器(Web模块,EJB模块或应用程序客户端模块)中的应用程序完成.

解决问题:

要解决此问题,您需要在Web,EJB或应用程序客户端模块的部署描述符中创建资源引用,并将其映射到资源的物理JNDI名称.这可以使用Application Server Toolkit(AST),WebSphere Studio Application Developer(WSAD)或Rational Application Developer(RAD)来完成.

创建或更改资源引用http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/com.ibm.websphere.nd.doc/info/ae/ae/tatk_crtresref.html

当间接JNDI查找完成时,资源引用的名称是"java:comp/env"之后的JNDI名称的一部分.配置资源引用时,资源的物理JNDI名称将设置为JNDI绑定.

资源链接:

http://www-01.ibm.com/support/docview.wss?uid=swg21106933

建议三:

Spring引导JNDI数据源查找失败 - 在上下文中找不到名称comp/env/jdbc"java:"