2017-09-17 89 views
0

我知道關於嵌入式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運行良好!

回答

0

我的問題已修復。而不是像上面所說的那樣返回「container」,我返回super.getTomcatEmbeddedServletContainer(tomcat);我的第一次更新中的手動GlobalContext運行良好!