1

I'm struggling to startup h2 "server" database before the connection pool is opened. Here's my code:

application.conf:

play.modules {
    ...
    enabled += modules.StartupModule
}
...
db {
  default.driver = org.h2.Driver
  #default.url = "jdbc:h2:mem:play"
  #See also http://h2database.com/javadoc/org/h2/tools/Server.html
  default.server = "-web -webAllowOthers -webPort 8082 -webSSL -tcp -tcpAllowOthers -tcpDaemon -tcpPort 9092 -tcpSSL -baseDir ~/.h2/"
  default.url = "jdbc:h2:ssl://localhost/~/.h2/play"
  default.username = sa
  default.password = "" 
  default.logSql=true
}

StartupModule.java

public class StartupModule extends AbstractModule {

    @Override
    public void configure() {
        //H2 server startup
        bind(H2Server.class).asEagerSingleton();
        ...
    }

H2Server.java

@Singleton
public class H2Server {

    private static Server server;

    @Inject
    public H2Server(ApplicationLifecycle appLifecycle, Config config) throws SQLException {
    // start the TCP Server
    String[] h2serverargs = StringUtils.arraySplit(config.getString("db.default.server"), ' ', true);
    Logger.info("Starting H2 Server at " + Instant.now());
    Logger.info("args: %s", h2serverargs);
    server = Server.createTcpServer(h2serverargs).start();
    Logger.info("DB Status: " + server.getStatus());

    appLifecycle.addStopHook(() -> {
        Logger.info("Stopping H2 Server at " + Instant.now());
        server.stop();
        return CompletableFuture.completedFuture(null);
    });
    }
}

The problem is that the connection pool is being created before the Singleton and the database is not ready yet.

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Enter to stop and go back to the console...)

[success] Compiled in 1s
[info] application - Creating Pool for datasource 'default'
[error] c.z.h.p.HikariPool - HikariPool-1 - Exception during pool initialization.
org.h2.jdbc.JdbcSQLException: Connection is broken: "java.net.ConnectException: Connection refused (Connection refused): localhost" [90067-196]

Does anybody succeeded to startup the H2 server database withing a play app?

Thanks!

inieto
  • 680
  • 12
  • 17

1 Answers1

1

Finally I did it!

I had to extend GuiceApplicationLoader and override the builder method to start the server.

public class H2ServerLoader extends GuiceApplicationLoader {

    private Server tcp;
    private Server web;

    @Override
    public GuiceApplicationBuilder builder(Context context) {

    Config config = context.initialConfig();
    // start the TCP Server
    String[] h2serverargs = StringUtils.arraySplit(config.getString("db.default.server"), ' ', true);
    Logger.info("Starting H2 Server at " + Instant.now() + " with args: " + String.join(" ", h2serverargs));

    try {
        this.tcp = Server.createTcpServer(h2serverargs).start();
        Logger.info("TCP server Status: " + this.tcp.getStatus());
        Logger.info("Starting web console too");
        this.web = Server.createWebServer(h2serverargs).start();
        Logger.info("Web server Status: " + this.web.getStatus());

        context.applicationLifecycle().addStopHook(() -> {
            Logger.info("Stopping H2Server at " + Instant.now());
            this.web.stop();
            this.tcp.stop();
            return CompletableFuture.completedFuture(null);
        });
    } catch (SQLException e) {
        Logger.error("Error starting H2Server %s", e);
        e.printStackTrace();
    }
    return initialBuilder
            .in(context.environment())
            .loadConfig(config)
            .overrides(overrides(context));
    }
}
inieto
  • 680
  • 12
  • 17