gpt4 book ai didi

tomcat - 带有 Apache CXF 和 JNDI 查找 javax.naming.NameNotFoundException 的嵌入式 Tomcat 的 Spring Boot

转载 作者:行者123 更新时间:2023-11-28 22:25:46 24 4
gpt4 key购买 nike

我在将遗留 Java 应用程序迁移到 Spring Boot 时遇到了障碍。具体来说,该应用程序将 Apache CXF 用于 SOAP Web 服务,这些服务具有从 Oracle 数据库获取数据的操作。我看到的问题是,一旦 Web 服务尝试进行 JNDI 查找,就会抛出以下异常:

Name [java:comp/env/jdbc/myDataSource] is not bound in this Context. Unable to find [java:comp].

NamingException: javax.naming.NameNotFoundException: Name [java:comp/env/jdbc/myDataSource] is not bound in this Context. Unable to find [java:comp].

作为引用,我在这里检查了一个问题示例: https://github.com/pmercer/spring-boot-sample-tomcat-jndi-cxf-ws

因此,如果有人可以向我指出一个工作示例和/或提供解决问题的建议,那么将不胜感激。

添加更多细节......

下面是在现有应用程序中执行查找的方式,该应用程序作为 .war 文件部署在外部 Tomcat 服务器上 ...

/**
* 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=***

最佳答案

我不确定为什么在 Apache CXF SOAP Web 服务调用的上下文中执行直接 JNDI 查找会失败。但是,使用 JndiObjectFactoryBean bean 完成的查找正在运行,所以这就是我要运行的。

关于tomcat - 带有 Apache CXF 和 JNDI 查找 javax.naming.NameNotFoundException 的嵌入式 Tomcat 的 Spring Boot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45744365/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com