【问题标题】:Spring Boot, JNDI datasource, Tomcat [duplicate]Spring Boot,JNDI 数据源,Tomcat [重复]
【发布时间】:2015-12-11 21:47:55
【问题描述】:

我现在承认,在我尝试使用 JNDI 数据源创建一个带有嵌入式 Tomcat(并且可部署到实际 Tomcat)的 Spring Boot 应用程序时,我已经断断续续地阅读了许多问题、答案和网站。多次失败后,我开始认为这根本不可能,这只是一个大阴谋!

在我永远放弃之前的最后一次尝试中,我现在要问:你到底是怎么做到的?

这是我目前所拥有的: 我的主要课程:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class FinanceApplication {

  public static void main(String[] args) throws Exception {
    SpringApplication.run(FinanceApplication.class, args);
  }

  @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) {
            ContextResource resource = new ContextResource();
            resource.setName("jdbc/finance");
            resource.setType(DataSource.class.getName());
            resource.setProperty("driverClassName", "com.mysql.jdbc.Driver");
            resource.setProperty("url", "jdbc:mysql://localhost:3306/finance");
            resource.setProperty("username", "xxxx");
            resource.setProperty("password", "yyyy");

            context.getNamingResources().addResource(resource);
        }
    };
  }

  @Bean(destroyMethod="")
  public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
    JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
    bean.setJndiName("java:comp/env/jdbc/finance");
    bean.setProxyInterface(DataSource.class);
    bean.setLookupOnStartup(false);
    bean.afterPropertiesSet();
    return (DataSource)bean.getObject();
  }
}

我的 Servlet 配置(基于 java):

public class ServletInitializer extends SpringBootServletInitializer {

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(FinanceApplication.class);
  }

}

我使用的是 Maven,我的 pom.xml 是基于 this one

问题:

当我在 Eclipse 中运行它时,我得到了这些异常(切入正题):

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is org.springframework.jndi.JndiLookupFailureException: JndiObjectTargetSource failed to obtain new target object; nested exception is javax.naming.NameNotFoundException: Name [comp/env/jdbc/finance] is not bound in this Context. Unable to find [comp].

当我使用 Maven 部署到独立的 Tomcat 实例时,我得到了这个异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is org.springframework.jndi.JndiLookupFailureException: JndiObjectTargetSource failed to obtain new target object; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
...

【问题讨论】:

  • 我之前没有在 Spring Boot 中使用过 JNDI,所以我真的帮不上忙(很抱歉 :( 但我确实有一个问题。既然您使用的是嵌入式 Tomcat,为什么要使用 JNDI?为什么不使用标准的 Spring Boot 约定来设置数据源?它会为你省去很多麻烦
  • 它应该通过嵌入式和单独的 Tomcat 实例工作。仍然没有找到答案。我认为这是不可能的。
  • 我建议您使用 Spring Profiles。当嵌入式配置文件处于活动状态时,将根据属性文件配置数据源。启用经典配置文件后,您可以使用 Spring Boot 的 JNDI 自动配置。看看here

标签: java maven tomcat spring-boot jndi


【解决方案1】:

问题根本不在于我的应用程序,而在于我的 Tomcat 配置。感谢对this question 的接受回答,我发现我需要在Tomcat 的context.xml 中添加一个ResourceLink 元素。我想知道为什么 Tomcat JNDI HowTo 没有提到它?

【讨论】:

  • 有什么例子你的代码最终是如何工作的吗?可以分享你的上一个版本吗?谢了,
  • 其实在global configuration下面也有简要提及:Tomcat maintains a separate namespace of global resources for the entire server. These are configured in the <GlobalNamingResources> element of $CATALINA_BASE/conf/server.xml. You may expose these resources to web applications by using a <ResourceLink> to include it in the per-web-application context.context.xml会有助于理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-01
  • 2020-03-06
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
  • 2018-08-08
相关资源
最近更新 更多