I have an embedded H2 Database I\'d like to put in the WEB-INF directory of a web application.
What is the proper way to refer to this in a JDBC url?
Ideally I\
I managed to make the embedded solution work without AES like this:
try {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection(
"jdbc:h2:" + getServletContext().getRealPath("/") +
"/WEB-INF/data/myDB", "sa", "");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.TABLES");
while (rs.next()) {
}
rs.close();
stmt.close();
conn.close();
} catch(SQLException e) {
} catch(ClassNotFoundException e) {
} finally {
}
This was tested with H2 1.3.176 on Tomcat8. It should work with H2 1.4 and CIPHER=AES
provided the embedded database is already inside the war file I guess.
The idea is the following: you need to get the absolute path, and that deployment path may not be the same depending on how you deployed the war file.
So we need to use the servlet context and request the real path. For this we use getServletContext().getRealPath("/")
and append /WEB-INF/data/myDB
to it as per your needs.
I did not test the CIPHER=AES
part as I've never used it.
Update:
Getting a good reference to the servlet context is tricky. One could use a raw request, get the underlying session and then get to the servlet context.
But it would be good to have the embedded H2 database opened as soon as the application is deployed/started in Tomcat, and closed properly as soon as the application is stopped.
In order to perform that, the use of a listener is needed. Here's what I propose as an update to my previous answer. This time the solution is complete with AES CIPHER and it should be easy to plug into your code.
Suggestion: the listener java code can be easily modified to start a H2 tcp server as well, useful to enable the automatic mixed mode (embedded+tcp).
Add 3 lines to the file web.xml:
com.mine.MyServletContextListener
File MyServletContextListener.java:
package com.mine;
import javax.servlet.*;
import java.sql.*;
public class MyServletContextListener implements ServletContextListener {
Connection conn;
public void contextInitialized(ServletContextEvent sce) {
try {
Class.forName("org.h2.Driver");
conn = DriverManager.getConnection( "jdbc:h2:" + sce.getServletContext().getRealPath("/") + "/WEB-INF/data/myDB;CIPHER=AES", "sa", "aespassword dbpassword");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.TABLES");
while (rs.next()) {
}
rs.close();
stmt.close();
} catch(SQLException e) {
} catch(ClassNotFoundException e) {
} finally {
}
}
public void contextDestroyed(ServletContextEvent sce) {
try {
conn.close();
} catch(SQLException e) {
} finally {
}
}
}