2016-03-18 159 views
3

我试图配置一个码头EmbeddedContainerServlet和JNDI数据源的弹簧启动的项目,下面春天开机豆订购

@Configuration 
public class EmbeddedJettyServer { 

    @Value("${jetty.http.port:8080}") 
    private Integer port; 
    @Value("${jetty.threadPool.maxThreads:200}") 
    private String maxThreads; 
    @Value("${jetty.threadPool.minThreads:8}") 
    private String minThreads; 
    @Value("${jetty.threadPool.idleTimeout:60000}") 
    private Integer idleTimeout; 

private JettyServerCustomizer jettyServerCustomizer() { 
    return new JettyServerCustomizer() { 

     @Override 
     public void customize(Server server) { 
      try { 
       // Tweak the connection pool used by Jetty to handle 
       // incoming HTTP connections 
       final QueuedThreadPool threadPool = new QueuedThreadPool(); 
       threadPool.setMaxThreads(Integer.valueOf(maxThreads)); 
       threadPool.setMinThreads(Integer.valueOf(minThreads)); 
       server.getBeans().add(threadPool); 
       WebAppContext webAppContext = (WebAppContext) server.getHandler(); 
       createConfiguration(
        "/Users/kewnen/git/zeus-info-provider/zeus-info-provider-web/ops/resources/jetty-datasource.xml") 
         .configure(webAppContext); 
      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
     } 

     private XmlConfiguration createConfiguration(String xml) throws IOException, SAXException { 
      return new XmlConfiguration(new FileInputStream(xml)); 
     } 
    }; 
} 

@Bean 
public EmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() { 
    final JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory = new JettyEmbeddedServletContainerFactory() { 
     @Override 
     protected JettyEmbeddedServletContainer getJettyEmbeddedServletContainer(Server server) { 
      return new JettyEmbeddedServletContainer(server); 
     } 
    }; 
    jettyEmbeddedServletContainerFactory.addServerCustomizers(jettyServerCustomizer()); 
    jettyEmbeddedServletContainerFactory.setPort(port); 
    jettyEmbeddedServletContainerFactory.setSessionTimeout(idleTimeout); 
    return jettyEmbeddedServletContainerFactory; 
} 

代码}

码头,datasource.xml文件,其中的内容我定义数据源的东西

<?xml version="1.0"?> 
    <Configure class="org.eclipse.jetty.webapp.WebAppContext"> 
    <Set name="contextPath">/</Set> 

     <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> 
     <Arg>jdbc/zeus-info</Arg> 
     <Arg> 
      <New class="org.apache.commons.dbcp.BasicDataSource"> 
      <Set name="driverClassName">org.postgresql.Driver</Set> 
      <Set name="url">jdbc:postgresql://localhost:5433/myDb</Set> 
      <Set name="username">postgres</Set> 
      <Set name="password">password</Set> 
      <Set name="validationQuery">SELECT 1</Set> 
     </New> 
    </Arg> 
</New> 

,然后我定义一个数据源下面

@Bean 
public DataSource dataSource() { 
    JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); 
    return dsLookup.getDataSource("jdbc/zeus-info"); 
} 

代码当我运行它,我得到这个例外

Caused by: javax.naming.NameNotFoundException; remaining name 'jdbc/zeus-info' 
at  org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:490) 
at org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:536) 
at javax.naming.InitialContext.lookup(InitialContext.java:417) 
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:155) 
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87) 
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152) 
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179) 
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:104) 
at org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup.getDataSource(JndiDataSourceLookup.java:45) 
debuggin时,我清楚地看到这里我定义我的JNDI的JettyEmbeddedServletContainerFactory之前定义数据源bean实例

datasource,

我试图强制通过添加@DependsOn注释到数据源定义但不起作用,它总是实例化容器之前的DataSource bean,

编辑:

透露更多的细节,

我已经通过定义数据源不使用JNDI这种方式测试它与正常工作:

@Bean 
public DataSource dataSource() { 
    DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
    dataSource.setDriverClassName(DRIVER_CLASS_NAME); 
    dataSource.setUrl(URL); 
    dataSource.setUsername(USER); 
    dataSource.setPassword(PASS); 
    return dataSource; 
} 

但由于其从克拉西克迁移与jndi定义的数据源战争启动jar包装项目,我想从现有的项目中重现相同,因为我不知道改变jndi方式对这个项目的影响。

我试图加入这一行的数据源定义

@DependsOn("jettyEmbeddedServletContainerFactory") 

迫使数据源的容器后,被实例化,但始终码头集装箱

修复之前实例化的数据源:

的问题是,spring-boot会自动配置一个名为jettyEmbeddedServletContainerFactory的容器,这就是为什么 @DependsOn(“jetty EmbeddedServletContainerFactory“)没有工作,

我添加

@EnableAutoConfiguration(exclude = EmbeddedServletContainerAutoConfiguration.class) 

到我的应用程序,现在,它的工作原理

感谢您的帮助!

回答

0

你可以使用Spring引导属性,而不是初始化JNDI数据源豆:上评论

spring.datasource.driver-class-name=org.postgresql.Driver 
spring.datasource.password=password 
spring.datasource.type=org.apache.commons.dbcp.BasicDataSource 
spring.datasource.url=jdbc:postgresql://localhost:5433/myDb 
spring.datasource.username=postgres 
spring.datasource.validation-query=SELECT 1 

反应:

所以,你的开发环境应尽量靠近PROD越好。因此我不会使用嵌入式容器,而是使用独立的容器进行开发。对于CI构建你可以横置 Maven的码头,插件或Gradle Jetty plugin

+0

谢谢您的回答,我编辑我的评论,以增加更多的细节,这个想法是用在我们的生产环境在使用的码头XML文件来复制相同的我嵌入式容器,这就是为什么我试图使它与jndi – Awnen

+0

为什么你不建议使用嵌入式容器,是否有任何理由? – Awnen

+0

因为您正在生产中使用WAR部署。你想尽可能接近生产地发展环境。 – luboskrnac