在将旧版Java应用程序迁移到Spring Boot时,我遇到了阻止程序。具体来说,应用程序将Apache CXF用于SOAP Web服务,该服务具有从Oracle数据库获取数据的操作。我看到的问题是,只要Web服务尝试进行JNDI查找,就会抛出以下异常:
名称[java:comp / env / jdbc / myDataSource]未绑定在此Context中。 无法找到[java:comp]。
NamingException:javax.naming.NameNotFoundException:Name [java:comp / env / jdbc / myDataSource]未绑定在此Context中。无法 找到[java:comp]。
作为参考,我在这里查看了一个问题的例子: https://github.com/pmercer/spring-boot-sample-tomcat-jndi-cxf-ws
所以,如果有人能指出一个有效的例子和/或提供解决问题的建议,那么我们将非常感激。
添加更多详情......
以下是在现有应用程序中执行查找的方式,该应用程序在外部Tomcat服务器上部署为.war文件...
/**
* Returns a database connection for the specified datasource
* @param db - ex. "jdbc/DatasourceXyz"
* @return db Connection
* @throws Exception
*/
public static Connection getDbConnection(String db) throws Exception {
java.sql.Connection conn = null;
try {
LOG.debug("getting db connection for " + db + " ...");
javax.naming.Context initCtx = new javax.naming.InitialContext();
javax.naming.Context envCtx = (javax.naming.Context) initCtx.lookup("java:comp/env");
javax.sql.DataSource ds = (javax.sql.DataSource) envCtx.lookup(db);
conn = ds.getConnection();
initCtx.close();
LOG.debug("got db connection for " + db);
LOG.debug("url = " + conn.getMetaData().getURL());
} catch (Exception e) {
String message = String.format("Exception thrown while creating a JDBC connection for %s: %s", db,
e.getMessage());
throw new Exception(message);
}
return conn;
}
数据库属性存储在Tomcat服务器的context.xml文件中......
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- environment-specific jdbc data sources: -->
<Resource name="jdbc/DatasourceXyz" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@hostname:1521:database" username="someUser" password="***" maxTotal="20" maxIdle="10" maxWaitMillis="60000"/>
<!-- set other jdbc data sources below: -->
此外,由于现有的getDbConnection方法调用很普遍,并且应用程序的数据库CRUD代码很广泛,因此目标是保持该代码的原样。所以基本上我只需要能够创建数据库连接,就像这样......
public static Connection getDbConnection(String db) throws Exception {
java.sql.Connection conn = null;
try {
LOG.debug("getting db connection for " + db + " ...");
// Get the SampleUtilService from the Bridge
SampleUtilService sampleUtilService = SpringContextBridge.services().getSampleUtilService();
// Get DataSource from the JndiObjectFactoryBean
javax.sql.DataSource ds = sampleUtilService.getDataSourcefromFactoryBean(db);
conn = ds.getConnection();
LOG.debug("got db connection for " + db);
LOG.debug("url = " + conn.getMetaData().getURL());
} catch (Exception e) {
String message = String.format("Exception thrown while creating a JDBC connection for %s: %s", db,
e.getMessage());
throw new Exception(message);
}
return conn;
}
因此,在SpringContextBridge功能的帮助下,使用嵌入式Tomcat服务器配置JNDI,在我的示例项目README中得到了记录,基本上就是我的计划。此外,由于我对Spring Boot相当新,我不确定这是否是最好的方法。
此外,在我的初始帖子之后做了一些额外的测试之后,看起来我看到的问题可能只是将JndiObjectFactoryBean.setLookupOnStartup属性设置为false,即。,
@Bean(destroyMethod="")
public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("java:comp/env/jdbc/myDataSource");
bean.setProxyInterface(DataSource.class);
bean.setLookupOnStartup(false);
bean.afterPropertiesSet();
return (DataSource)bean.getObject();
}
当我将bean的setLookupOnStartup属性设置为true时,应用程序能够成功获取数据库连接。但是,当应用程序尝试通过JNDI进行查找时,我仍然会看到问题,即。,
DataSource dataSource =
(DataSource) new InitialContext().lookup("java:comp/env/jdbc/myDataSource");
因此,如果使用bean的其他测试证明是成功的,那么我可能只是使用bean进行查找。此外,如果有更好的方法,我可以提出建议。
另外,据我所知,数据源配置应该存储在应用程序的application.properties文件中......
jdbc.xyz.datasource.name=jdbc/DatasourceXyz
jdbc.xyz.datasource.driver=oracle.jdbc.OracleDriver
jdbc.xyz.datasource.url=jdbc:oracle:thin:@hostname:1521:database
jdbc.xyz.datasource.username=someUser
jdbc.xyz.datasource.password=***
答案 0 :(得分:0)
我不确定为什么在Apache CXF SOAP Web服务调用的上下文中执行直接JNDI查找失败。但是,使用JndiObjectFactoryBean bean完成的查找正在运行,因此我将使用它。