我知道關於嵌入式tomcat中的JNDI資源存在很多問題,但我嘗試了所有我沒有成功找到的解決方案。SpringBoot Tomcat嵌入式全局JNDI資源
我有一個應用程序爲我的客戶端公開Rest API。在這個應用程序內部,我們有一個使用JMS和Amazon SQS的異步解決方案。該應用程序使用第三方庫,它使用JNDI來獲取sql.Datasource,因此,我需要使用JNDI數據源。
問題是,當應用程序在Rest Controller的同一線程中調用此庫時,JNDI Lookup起作用,並且數據源被獲取。
當我的@JmsListener調用這個庫時,我得到一個NamingNotFoungException異常。
我已經在我的代碼的兩點中使用了context.list(「java」),並確認在JmsListener中沒有JNDI上下文。
我的tomcat的工廠類: 配置 公共類CustomTomcatEmbeddedServletContainerFactory {
@Value("${spring.log.datasource.jndiName}")
private String logJndiName;
@Value("${spring.log.datasource.password}")
private String logPassword;
@Value("${spring.log.datasource.url}")
private String logUrl;
@Value("${spring.log.datasource.username}")
private String logUsername;
@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
// LogDS
context.getNamingResources()
.addResource(
getContextResource(logJndiName, logUrl, logUsername, logPassword)
);
ContextResourceLink contextResourceLink = new
ContextResourceLink();
contextResourceLink.setGlobal(logJndiName);
contextResourceLink.setName(logJndiName);
contextResourceLink.setType("javax.sql.DataSource");
context.getNamingResources().addResourceLink(contextResourceLink);
}
private ContextResource getContextResource(
final String name
, final String url
, final String username
, final String password
) {
ContextResource resource = new ContextResource();
resource.setName(name);
resource.setType(DataSource.class.getName());
resource.setProperty("factory", "com.zaxxer.hikari.HikariJNDIFactory");
resource.setProperty("jdbcUrl", url);
resource.setProperty("dataSource.user", username);
resource.setProperty("dataSource.password", AESCrypto.decrypt(password));
resource.setScope("Sharable");
return resource;
}
};
}
}
這個問題的任何想法?
-------更新---------
當我使用下面的代碼,在JMSListener背景下解決,但我RestController不回答了,404 HTTP狀態發生。
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
tomcat.enableNaming();
TomcatEmbeddedServletContainer container = super.getTomcatEmbeddedServletContainer(tomcat);
for (Container child : container.getTomcat().getHost().findChildren()) {
if (child instanceof Context) {
ClassLoader contextClassLoader = ((Context) child).getLoader().getClassLoader();
Thread.currentThread().setContextClassLoader(contextClassLoader);
break;
}
}
return container;
}
------- UPDATE2 --------- 我的問題是固定的。而不是像上面所說的那樣返回「container」,我返回super.getTomcatEmbeddedServletContainer(tomcat);我的第一次更新中的手動GlobalContext運行良好!