I am someone that normally figures things out by myself researching and trying stuff (That's why I had zero questions here). However, I already wasted days trying to figure this out and I am out of options. I hope you guys can help me. I am trying to make my Java/Maven/Hibernate/JPA/Tomcat web application work on a free Heroku account. I was able to deploy successfully and send some data to the Heroku Postgres DB. The same application, running on a local server (Tomcat/IntelliJ), can successfully connect and retrieve data from the Heroku database. However, the deployed Heroku application is not working with the Heroku database. The application is running fine, but I am getting errors when it tries to retrieve data from the database.
I searched here for solutions related to this error and the others in the stack below, including the one already suggested: The meaning of NoInitialContextException error. None seems to fit my situation. The link above mentions using a Properties object, but as I mentioned, it is working fine locally and I never had to use such an object before. If you believe this could be a solution, could you provide more details on how to implement that in my environment?
I don't have a Procfile setup and I am deploying the application using the following Heroku command:
heroku war:deploy target/appname.war --app appname
This is the error stack I am getting (from Heroku log with debug log enabled):
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)
The error happens when any of the classes in my application calls the EntityManagerFactory method in my HibernateUtil class. This is the code being called:
public class HibernateUtil {
private static final EntityManagerFactory emf =
Persistence.createEntityManagerFactory("AbsPu");
public static EntityManagerFactory getEmFactory() {
return emf;
}
}
This is what my webapp/META-INF/context.xml looks like (I removed sensisitve data). Here I also tried to use the DATABASE_URL system variable from Heroku instead of hard coding the url but I couldn't figure out how to make it work. But it is working like this:
<?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>
And this is what my resources/META-INF/persisence.xml looks like. Again, I just removed the sensitive data (class names):
<?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>
And lastly, my 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>
I provided as many details as I could think of. Let me know if you need more details!