【问题标题】:JNDI jdbc data source in embedded tomcat 7嵌入式tomcat 7中的JNDI jdbc数据源
【发布时间】:2011-07-11 10:35:08
【问题描述】:

我有一个在 META-INF/context.xml 中定义了数据库数据源的 Web 应用程序:

<Context>
    <Resource
        name="jdbc/mkddb"
        auth="Container"
        type="javax.sql.DataSource"
        maxActive="10"
        maxIdle="5"
        maxWait="10000"
        driverClassName="org.postgresql.Driver"
        username="woky"
        password="XYZ"
        url="jdbc:postgresql://[::1]:5433/mkddb" />
</Context>

这是我的 peristence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">
    <persistence-unit name="myJpaUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <non-jta-data-source>java:comp/env/jdbc/mkddb</non-jta-data-source>
        <class>mkd.model.User</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
        </properties>
    </persistence-unit>
</persistence>

这是我在测试代码中运行 Tomcat (7.0.8) 的方式:

Tomcat tomcat = new Tomcat();
tomcat.addWebapp("", "ROOT");
tomcat.enableNaming();
tomcat.start();
System.in.read();
tomcat.stop();

我的工作区中有一个tomcat.8080 目录,其中包含webapps 和工作目录。 ROOT 指向 src/main/webapp(所有 Java 代码都在类路径中)。

问题是当我运行此代码时出现以下异常:

javax.persistence.PersistenceException: [PersistenceUnit: myJpaUnit] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:892)
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
    at com.google.inject.persist.jpa.JpaPersistService.start(JpaPersistService.java:94)
    at com.google.inject.persist.PersistFilter.init(PersistFilter.java:77)
    at com.google.inject.servlet.FilterDefinition.init(FilterDefinition.java:114)
    at com.google.inject.servlet.ManagedFilterPipeline.initPipeline(ManagedFilterPipeline.java:98)
    at com.google.inject.servlet.GuiceFilter.init(GuiceFilter.java:172)
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:273)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:254)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:98)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4461)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5133)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5128)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: org.hibernate.HibernateException: Could not find datasource
    at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:79)
    at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:137)
    at org.hibernate.ejb.InjectionSettingsFactory.createConnectionProvider(InjectionSettingsFactory.java:51)
    at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:91)
    at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2163)
    at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2159)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1383)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
    ... 20 more
Caused by: javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
    at org.apache.naming.NamingContext.lookup(NamingContext.java:803)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:145)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:814)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:145)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:814)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
    at org.apache.naming.SelectorContext.lookup(SelectorContext.java:158)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:75)
    ... 28 more

我做错了什么?

谢谢。

【问题讨论】:

  • 您是否为您的数据库安装了 JDBC 驱动程序?
  • 是的,它在类路径中。如果我将战争/目录复制到 $TOMCAT_HOME/webapps 并运行“$TOMCAT_HOME/bin/catalina.sh run”,它会起作用。

标签: tomcat jdbc datasource jndi


【解决方案1】:

我认为配置文件 (context.xml) 不会被嵌入式 Tomcat 实现自动解析,即使它位于默认位置 (META-INF)。如果您以编程方式设置配置文件,您的应用程序应该能够创建数据源。确保您的context.xml 的路径正确。这是一个例子:

File configFile = new File("META-INF/context.xml")
Context context = tomcat.addWebapp("", "ROOT");
context.setConfigFile(configFile.toURI().toURL());

【讨论】:

  • 我遇到了这个确切的问题;您的解决方案给了我以下错误:org.apache.catalina.Context.setConfigFile(Ljava/lang/String;)V java.lang.NoSuchMethodError: org.apache.catalina.Context.setConfigFile(Ljava/lang/String;)V;有什么想法吗?
  • 听起来您想使用java.lang.String 而不是java.net.URL 来设置配置文件。请参阅JavaDocs 了解更多信息。
  • 谢谢;我确定我的 IDE 昨天抱怨使用了 URL .. 工作正常。
【解决方案2】:

顺便说一句,您可以使用 Spring Test 框架中的模拟 JNDI 上下文,也适用于嵌入式 tomcat,eq:

OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:@127.0.0.1:1521/orcldb");
ods.setUser("*");
ods.setPassword("*");
SimpleNamingContextBuilder builder = null;
    try {
        builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
        builder.bind("java:comp/env/jdbc/db",ods);
    } catch (NamingException e) {
        logger.error(e);
    }

【讨论】:

    【解决方案3】:

    我对这个配置有同样的问题:

    <Resource name="jdbc/casper" ... ... />
    

    原因:javax.naming.NameNotFoundException:名称 jdbc 未绑定在此上下文中

    我终于让它工作了,把配置改成这样:

    <Resource name="jdbc/Casper" ... ... />
    

    是的,这很荒谬,我不知道它是否是规范的一部分,但名称的第一个字母必须大写。我看到你在使用“jdbc/mkddb”,尝试使用“jdbc/Mkddb”,并且不要忘记更改所有对名称的引用。

    我希望这是你的解决方案,JNDI 错误很麻烦

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-18
      • 2018-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      相关资源
      最近更新 更多