Tomcat 6/7 JNDI具有多个数据源 [英] Tomcat 6/7 JNDI with multiple datasources

查看:139
本文介绍了Tomcat 6/7 JNDI具有多个数据源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当context.xml中有多个< Resource> 元素和多个< resource-ref> web.xml中的元素,我的应用程序开始抛出

  TNS:找不到适当的服务处理程序

  ORA-01017:无效的用户名/密码;登录拒绝

但是,如果JNDI中只有一个数据源,意思是另一个使用常规的JDBC数据源,应用程序像一个魅力一样运行



两个数据源都来自相同的数据库URL,但使用不同的模式。



我的猜测是,它可能是由具有不同用户名/密码(模式)的每个资源的相同数据库URL引起的。但是tomcat应该能够处理这样的情况,所以我的推理是可能有一些我错过的配置?



另一个有趣的发现是:
当我使用jdbc url jdbc:oracle:thin:@myhost:1521:orcl 与SQL Developer建立连接,有时它连接没有问题,但有时它被拒绝与同样的问题: 发现相应的服务处理程序,同时此Web应用程序处于活动状态。但是,与使用常规JDBC连接(不是JNDI)的另一个Spring应用程序相同的JDBC URL正常工作。那么什么窍门?



以下是当前配置的详细信息:



在Context.xml

 <资源名称=jdbc / app_Aauth =容器type =javax.sql.DataSource
driverClassName =oracle.jdbc.driver.OracleDriverurl =jdbc:oracle:thin:@myhost:1521:orcl
username =usernameApassword =passwordAmaxActive =20maxIdle =10 maxWait = - 1/>
<资源名称=jdbc / app_Bauth =容器type =javax.sql.DataSource
driverClassName =oracle.jdbc.driver.OracleDriverurl =jdbc:oracle: thin:@myhost:1521:orcl
username =usernameBpassword =usernameBmaxActive =20maxIdle =10maxWait = - 1/>

在应用程序的Web.xml中:

 <资源引用> 
< description>用于app_A< / description>的Oracle数据源
< res-ref-name> jdbc / app_A< / res-ref-name>
< res-type> javax.sql.DataSource< / res-type>
< res-auth>容器< / res-auth>
< / resource-ref>
< resource-ref>
< description>用于app_B< / description>的Oracle数据源
< res-ref-name> jdbc / app_B< / res-ref-name>
< res-type> javax.sql.DataSource< / res-type>
< res-auth>容器< / res-auth>
< / resource-ref>

在ApplicationContext.xml中

 < jee:jndi-lookup id =dataSource1jndi-name =java:comp / env / jdbc / app_Aresource-ref =true/> 
< jee:jndi-lookup id =dataSource2jndi-name =java:comp / env / jdbc / app_Bresource-ref =true/>

最后我收到这样的异常堆栈:

  2013年1月31日3:36:55 PM org.apache.catalina.core.NamingContextListener addResource 
警告:无法在JMX中注册:javax.naming.NamingException :ORA-01017:用户名/密码无效;登录拒绝

2013年1月31日3:36:56 PM org.apache.naming.NamingContext lookup
警告:意外异常解析引用
java.sql.SQLException:侦听器拒绝与以下错误的连接:
ORA-12519,TNS:找不到适当的服务处理程序

在oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:412)
at oracle.jdbc.driver.PhysicalConnection。< init>(PhysicalConnection.java:531)
at oracle.jdbc.driver.T4CConnection。< init>(T4CConnection.java:221)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503)
在org.apache.tomcat.jdbc。 pool.PooledConnection.connectUsingDriver(PooledConnection.java:278)
在org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
在org.apache.tomcat.jdbc。 pool.ConnectionPool.createConnection(ConnectionPool.java:699)
在org.apache.tomcat.jdbc.po ol.ConnectionPool.borrowConnection(ConnectionPool.java:631)
在org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:485)
在org.apache.tomcat.jdbc。 pool.ConnectionPool。< init>(ConnectionPool.java:143)
在org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
在org.apache.tomcat .jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
在org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:539)
在org.apache.tomcat .jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:237)
在org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:143)
在javax.naming.spi.NamingManager .getObjectInstance(NamingManager.java:304)
在org.apache.naming.NamingContext.lookup(NamingContext.java:843)
在org.apache.naming.NamingContext.lookup(NamingContext.java:154 )
在org.apache.naming.NamingContext.lookup(NamingContext.java:831)
在org.apache.naming.NamingContext.lookup(NamingContext.java:168)
在org.apache.catalina.core.NamingContextListener.addResource(NamingContextListener.java:1061)
在org.apache.catalina .core.NamingContextListener.createNamingContext(NamingContextListener.java:671)
在org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:270)
在org.apache.catalina.util.LifecycleSupport .fireLifecycleEvent(LifecycleSupport.java:119)
在org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
在org.apache.catalina.core.StandardContext.startInternal(StandardContext .java:5173)
在org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
在org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901 )
在org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
在org.apache.catalina.core.StandardHost.addChild(StandardHost.java:618)
在org.apache.catalin a.startup.HostConfig.deployDirectory(HostConfig.java:1100)
在org.apache.catalina.startup.HostConfig $ DeployDirectory.run(HostConfig.java:1618)
在java.util.concurrent。执行者$ RunnableAdapter.call(Executors.java:441)
在java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:303)
在java.util.concurrent.FutureTask.run( FutureTask.java:138)
在java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java:886)
在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java: 908)
在java.lang.Thread.run(Thread.java:662)
导致:oracle.net.ns.NetException:侦听器拒绝连接与以下错误:
ORA -12519,TNS:找不到适当的服务处理程序

在oracle.net.ns.NSProtocol.connect(NSProtocol.java:385)
at oracle.jdbc.driver.T4CConnection.connect( T4CConnection.java:1042)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:301)
... 38更多
2013年1月31日3:36:56 PM org.apache.catalina.core.NamingContextListener addResource
警告:无法在JMX中注册:javax.naming.NamingException:侦听器拒绝连接并出现以下错误:
ORA-12519 ,TNS:找不到适当的服务处理程序

2013年1月31日3:36:56 PM org.apache.naming.NamingContext lookup
警告:意外异常解析引用
java。 sql.SQLException:侦听器拒绝连接以下错误:
ORA-12519,TNS:找不到适当的服务处理程序

真的不知道为什么没有找到适当的服务处理程序错误弹出,似乎连接不被orcl Listener接受/理解。



这是我在persisntence.xml中插入的内容

 < persistence-unit NAME = persistenceUnit1 > 
....
< jta-data-source> jdbc / app_A< / jta-data-source>
....
< / persistence-unit>

< persistence-unit name =persistenceUnit2>
....
< jta-data-source> jdbc / app_B< / jta-data-source>
....
< / persistence-unit>


解决方案

ORA-12519,TNS :找不到适当的服务处理程序错误可能是使用旧式JDBC连接字符串的结果。根据第8章数据源和URL Oracle 11.1 JDBC开发人员指南和参考,连接字符串格式如下:

  jdbc:oracle:thin:@ // host_name:port_number / service_name 

还有一个注释说em启动Oracle数据库10g,Oracle服务ID不是支持。所以您使用的语法必须适用于Oracle 9i。它可能适用于较新版本,但不能保证。



所以考虑更改JDBC连接字符串的格式,以遵循指南中建议的格式。



此外,对于Oracle 9i,您应该使用 oracle.jdbc.OracleDriver 而不是 oracle.jdbc。 driver.OracleDriver ,因为Oracle已经声明, oracle.jdbc.driver.OracleDriver 已被弃用,并且此驱动程序类的支持将被停用。


When there are more than one <Resource> elements in context.xml and more than one <resource-ref> elements in web.xml, my application begins to throw

TNS:no appropriate service handler found

and

ORA-01017: invalid username/password; logon denied

However, if there is only one of the data sources in JNDI, meaning the other one use regular JDBC data source, the application runs like a charm

Both data sources come from same db URL but use different schema.

My guess is that it may be caused by the same database URL of each resources with different username/password(schema). But tomcat should be capable of handling such situation, so my reasoning is that there maybe some configuration I missed?

Another interesting finding is: When I use jdbc url jdbc:oracle:thin:@myhost:1521:orcl with SQL Developer to setup a connection, sometimes it connects without issue, but sometimes it gets rejected with the same issue: appropriate service handler found while this web application is active at the same time. However, the same JDBC URL works fine with another Spring application with regular JDBC connection(not JNDI). So what is the trick?

Here are the details of current config:

In Context.xml

<Resource name="jdbc/app_A" auth="Container" type="javax.sql.DataSource"
    driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@myhost:1521:orcl"
    username="usernameA" password="passwordA" maxActive="20" maxIdle="10" maxWait="-1" />
<Resource name="jdbc/app_B" auth="Container" type="javax.sql.DataSource"
    driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@myhost:1521:orcl"
    username="usernameB" password="usernameB" maxActive="20" maxIdle="10" maxWait="-1" />

In Web.xml of the application:

<resource-ref>
    <description>Oracle Datasource for app_A</description>
    <res-ref-name>jdbc/app_A</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
    <description>Oracle Datasource for app_B</description>
    <res-ref-name>jdbc/app_B</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

In ApplicationContext.xml

<jee:jndi-lookup id="dataSource1" jndi-name="java:comp/env/jdbc/app_A" resource-ref="true" />
<jee:jndi-lookup id="dataSource2" jndi-name="java:comp/env/jdbc/app_B" resource-ref="true" />

And finally I get exception piled up like this:

Jan 31, 2013 3:36:55 PM org.apache.catalina.core.NamingContextListener addResource
WARNING: Failed to register in JMX: javax.naming.NamingException: ORA-01017: invalid username/password; logon denied

Jan 31, 2013 3:36:56 PM org.apache.naming.NamingContext lookup
WARNING: Unexpected exception resolving reference
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12519, TNS:no appropriate service handler found

at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:412)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:531)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:221)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503)
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:278)
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:699)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:631)
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:485)
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:143)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:539)
at org.apache.tomcat.jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:237)
at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:143)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
at org.apache.naming.NamingContext.lookup(NamingContext.java:843)
at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
at org.apache.catalina.core.NamingContextListener.addResource(NamingContextListener.java:1061)
at org.apache.catalina.core.NamingContextListener.createNamingContext(NamingContextListener.java:671)
at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:270)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5173)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:618)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1100)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1618)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: oracle.net.ns.NetException: Listener refused the connection with the following error:
ORA-12519, TNS:no appropriate service handler found

at oracle.net.ns.NSProtocol.connect(NSProtocol.java:385)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1042)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:301)
... 38 more
Jan 31, 2013 3:36:56 PM org.apache.catalina.core.NamingContextListener addResource
WARNING: Failed to register in JMX: javax.naming.NamingException: Listener refused the  connection with the following error:
ORA-12519, TNS:no appropriate service handler found

Jan 31, 2013 3:36:56 PM org.apache.naming.NamingContext lookup
WARNING: Unexpected exception resolving reference
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12519, TNS:no appropriate service handler found

Really not sure why the no appropriate service handler found error pops up, it seems the connection is not accepted/understood by orcl Listener.

Here is what I insert into persisntence.xml

<persistence-unit name="persistenceUnit1">
....
<jta-data-source>jdbc/app_A</jta-data-source>
....
</persistence-unit>

<persistence-unit name="persistenceUnit2">
....
<jta-data-source>jdbc/app_B</jta-data-source>
....
</persistence-unit>

解决方案

ORA-12519, TNS:no appropriate service handler found error might be the result of using an old-style JDBC connection string. According to chapter 8 Data Sources and URLs of Oracle 11.1 JDBC Developer's Guide and Reference, connection string format is following:

jdbc:oracle:thin:@//host_name:port_number/service_name

There's also a note saying "Starting Oracle Database 10g, Oracle Service IDs are not supported". So the syntax you're using must have been suitable for Oracle 9i. It might work on newer versions, but that's not guaranteed.

So consider changing the format of your JDBC connection strings to follow the format suggested in the guide.

Also, for Oracle 9i onwards you should use oracle.jdbc.OracleDriver rather than oracle.jdbc.driver.OracleDriver as Oracle have stated that oracle.jdbc.driver.OracleDriver is deprecated and support for this driver class will be discontinued.

这篇关于Tomcat 6/7 JNDI具有多个数据源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆