有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

尝试从数据库检索数据时,xml NoInitialContextException。Heroku Java web应用程序

我是一个通常靠自己研究和尝试东西来解决问题的人(这就是为什么我在这里没有问题)。然而,我已经浪费了好几天时间试图弄明白这一点,我别无选择。我希望你们能帮我。我试图让我的Java/Maven/Hibernate/JPA/Tomcat web应用程序在一个免费的Heroku帐户上工作。我成功地部署并向Heroku Postgres数据库发送了一些数据。在本地服务器(Tomcat/IntelliJ)上运行的同一应用程序可以成功连接Heroku数据库并从中检索数据。 但是,部署的Heroku应用程序不能与Heroku数据库一起工作。应用程序运行良好,但在尝试从数据库检索数据时,我遇到了错误

我在这里搜索了与此错误和下面堆栈中其他错误相关的解决方案,包括已经建议的解决方案:The meaning of NoInitialContextException error。 似乎都不适合我的情况。上面的链接提到使用Properties对象,但正如我所提到的,它在本地运行良好,我以前从未使用过这样的对象。如果您认为这是一个解决方案,您能提供更多关于如何在我的环境中实现的细节吗

我没有Procfile设置,正在使用以下Heroku命令部署应用程序:

heroku war:deploy target/appname.war --app appname

这是我得到的错误堆栈(来自启用调试日志的Heroku日志):

2021-07-18T19:27:42.218347+00:00 app[web.1]: SEVERE: Servlet.service() for servlet [AdminServlet] in context with path [] threw exception [Servlet execution threw an exception] with root cause
2021-07-18T19:27:42.218348+00:00 app[web.1]: 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
2021-07-18T19:27:42.218349+00:00 app[web.1]:    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:673)
2021-07-18T19:27:42.218349+00:00 app[web.1]:    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
2021-07-18T19:27:42.218350+00:00 app[web.1]:    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
2021-07-18T19:27:42.218350+00:00 app[web.1]:    at javax.naming.InitialContext.getNameParser(InitialContext.java:505)
2021-07-18T19:27:42.218358+00:00 app[web.1]:    at org.hibernate.engine.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:118)
2021-07-18T19:27:42.218358+00:00 app[web.1]:    at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:95)
2021-07-18T19:27:42.218359+00:00 app[web.1]:    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:98)
2021-07-18T19:27:42.218363+00:00 app[web.1]:    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:107)
2021-07-18T19:27:42.218363+00:00 app[web.1]:    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
2021-07-18T19:27:42.218365+00:00 app[web.1]:    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
2021-07-18T19:27:42.218366+00:00 app[web.1]:    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
2021-07-18T19:27:42.218366+00:00 app[web.1]:    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
2021-07-18T19:27:42.218366+00:00 app[web.1]:    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
2021-07-18T19:27:42.218366+00:00 app[web.1]:    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
2021-07-18T19:27:42.218367+00:00 app[web.1]:    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
2021-07-18T19:27:42.218367+00:00 app[web.1]:    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
2021-07-18T19:27:42.218367+00:00 app[web.1]:    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
2021-07-18T19:27:42.218368+00:00 app[web.1]:    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
2021-07-18T19:27:42.218368+00:00 app[web.1]:    at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
2021-07-18T19:27:42.218369+00:00 app[web.1]:    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
2021-07-18T19:27:42.218369+00:00 app[web.1]:    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
2021-07-18T19:27:42.218369+00:00 app[web.1]:    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:176)
2021-07-18T19:27:42.218370+00:00 app[web.1]:    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127)
2021-07-18T19:27:42.218370+00:00 app[web.1]:    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1224)
2021-07-18T19:27:42.218370+00:00 app[web.1]:    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1255)
2021-07-18T19:27:42.218370+00:00 app[web.1]:    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
2021-07-18T19:27:42.218371+00:00 app[web.1]:    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
2021-07-18T19:27:42.218371+00:00 app[web.1]:    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
2021-07-18T19:27:42.218376+00:00 app[web.1]:    at dataaccess.HibernateUtil.<clinit>(HibernateUtil.java:12)
2021-07-18T19:27:42.218376+00:00 app[web.1]:    at dataaccess.CityDB.getAllCities(CityDB.java:37)
2021-07-18T19:27:42.218376+00:00 app[web.1]:    at servlets.AdminServlet.doGet(AdminServlet.java:61)
2021-07-18T19:27:42.218377+00:00 app[web.1]:    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
2021-07-18T19:27:42.218377+00:00 app[web.1]:    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
2021-07-18T19:27:42.218378+00:00 app[web.1]:    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
2021-07-18T19:27:42.218378+00:00 app[web.1]:    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2021-07-18T19:27:42.218378+00:00 app[web.1]:    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
2021-07-18T19:27:42.218386+00:00 app[web.1]:    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2021-07-18T19:27:42.218387+00:00 app[web.1]:    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2021-07-18T19:27:42.218387+00:00 app[web.1]:    at filters.AdminFilter.doFilter(AdminFilter.java:35)
2021-07-18T19:27:42.218387+00:00 app[web.1]:    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2021-07-18T19:27:42.218388+00:00 app[web.1]:    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2021-07-18T19:27:42.218388+00:00 app[web.1]:    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
2021-07-18T19:27:42.218388+00:00 app[web.1]:    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
2021-07-18T19:27:42.218389+00:00 app[web.1]:    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
2021-07-18T19:27:42.218389+00:00 app[web.1]:    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
2021-07-18T19:27:42.218389+00:00 app[web.1]:    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
2021-07-18T19:27:42.218389+00:00 app[web.1]:    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
2021-07-18T19:27:42.218390+00:00 app[web.1]:    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
2021-07-18T19:27:42.218390+00:00 app[web.1]:    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)
2021-07-18T19:27:42.218391+00:00 app[web.1]:    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
2021-07-18T19:27:42.218391+00:00 app[web.1]:    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
2021-07-18T19:27:42.218391+00:00 app[web.1]:    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598)
2021-07-18T19:27:42.218391+00:00 app[web.1]:    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
2021-07-18T19:27:42.218392+00:00 app[web.1]:    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
2021-07-18T19:27:42.218392+00:00 app[web.1]:    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
2021-07-18T19:27:42.218392+00:00 app[web.1]:    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
2021-07-18T19:27:42.218393+00:00 app[web.1]:    at java.lang.Thread.run(Thread.java:748)

当应用程序中的任何类调用HibernateUtil类中的EntityManagerFactory方法时,就会发生错误。这是被调用的代码:

public class HibernateUtil {
    private static final EntityManagerFactory emf =
            Persistence.createEntityManagerFactory("AbsPu");

    public static EntityManagerFactory getEmFactory() {
        return emf;
    }
}

这就是我的webapp/META-INF/上下文。xml看起来像(我删除了sensisitve数据)。在这里,我还尝试使用Heroku中的DATABASE_URL系统变量,而不是硬编码URL,但我不知道如何使其工作。但它是这样工作的:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/">
    <Resource name="jdbc/postgres" auth="Container"
              type="javax.sql.DataSource"
              driverClassName="org.postgresql.Driver"
              url="jdbc:postgresql://ec2-52-2-118-38.compute-1.amazonaws.com:5432/...?sslmode=require"
              username="..." password="..."
              maxActive="100" maxIdle="30" maxWait="10000"
              logAbandoned="true" removeAbandoned="true"
              removeAbandonedTimeout="60" />
</Context>

这就是我的参考资料/META-INF/所说的。xml看起来像。我再次删除了敏感数据(类名):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">
  <persistence-unit name="AbsPu">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <non-jta-data-source>java:/comp/env/jdbc/postgres</non-jta-data-source>
    <class>...</class>
    ...
    <class>...</class>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
  </persistence-unit>
</persistence>

最后,我的pom。xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <version>1.0</version>
  <packaging>war</packaging>

  <name>...</name>
  <URL>...</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.4.30.Final</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <dependency>
      <groupId>org.postgresql</groupId>
      <artifactId>postgresql</artifactId>
      <version>42.2.20</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>...</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <source>8</source>
                  <target>8</target>
              </configuration>
          </plugin>
      </plugins>
  </build>
</project>

我提供了尽可能多的细节。如果你需要更多细节,请告诉我


共 (2) 个答案

  1. # 1 楼答案

    终于解决了。以下是我解决问题的步骤:

    1. 通过在初始化中添加“启用命名”来启用JNDI命名: heroku config:set WEBAPP_RUNNER_OPTS=" enable-naming" app appname。在添加这个之后,我开始得到一个不同的错误:java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory

    2. 基于新的错误,我在上下文中指定了资源工厂。xml: factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory"

    3. 最后,向pom添加了一个新的依赖项。xml:

      <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-dbcp</artifactId>
            <version>10.1.0-M2</version>
      </dependency>
      

    最后两步来自这个问题:SpringBoot JNDI datasource throws java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory

    我相信IntelliJ在默认情况下可以与JNDI命名配合使用,并且为Tomcat提供了一个嵌入式数据库连接池API。这可能就是为什么它在本地运行良好,而不是在Heroku上

  2. # 2 楼答案

    你有没有尝试过针对同一个例外的相关问题的方法Here is one of them。 我注意到maven编译器的java版本在属性和实际插件中不匹配

    这里:

      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
      </properties>
    

    这里:

     <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <configuration>
              <source>8</source>
              <target>8</target>
         </configuration>
     </plugin>
    

    According to the docsHeroku目前默认值为1.8