I am successfully using H2 database in AUTO_SERVER mode so that a database file is shared among a number of desktop clients on a network transparently. This way a server is
H2 does not implement JMS (in fact I don't know of a database that does). However, you could build a simple notify mechanism within H2, using a trigger and a user defined function, as follows. Please note this would require the multi-threaded mode in H2, which is not fully tested yet. Because of that, it might make sense to use a separate database for messaging than the database you use for your data.
import java.sql.*;
import java.util.concurrent.atomic.AtomicLong;
import org.h2.tools.TriggerAdapter;
public class TestSimpleDb {
public static void main(String[] args) throws Exception {
final String url = "jdbc:h2:mem:test;multi_threaded=true";
Connection conn = DriverManager.getConnection(url);
Statement stat = conn.createStatement();
stat.execute("create alias wait_for_change for \"" +
TestSimpleDb.class.getName() +
".waitForChange\"");
stat.execute("create table test(id identity)");
stat.execute("create trigger notifier " +
"before insert, update, delete, rollback " +
"on test call \"" +
TestSimpleDb.Notifier.class.getName() + "\"");
new Thread() {
public void run() {
try {
Connection conn = DriverManager.getConnection(url);
for (int i = 0; i < 10; i++) {
conn.createStatement().execute(
"call wait_for_change(10000)");
System.out.println("Receiver: event received");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
Thread.sleep(500);
for (int i = 0; i < 10; i++) {
System.out.println("Sender: I change something...");
stat.execute("insert into test values(null)");
Thread.sleep(1000);
}
conn.close();
}
static AtomicLong modCount = new AtomicLong();
public static void waitForChange(long maxWaitMillis) {
synchronized (modCount) {
try {
modCount.wait(maxWaitMillis);
} catch (InterruptedException e) {
// ignore
}
}
}
public static class Notifier extends TriggerAdapter {
public void fire(Connection conn, ResultSet oldRow, ResultSet newRow)
throws SQLException {
modCount.incrementAndGet();
synchronized (modCount) {
modCount.notifyAll();
}
}
}
}