1

在打开连接池之前,我正在努力启动 h2“服务器”数据库。这是我的代码:

应用程序.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
}

启动模块.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);
    });
    }
}

问题是连接池是在 Singleton 之前创建的,并且数据库还没有准备好。

--- (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]

有人用play应用成功启动H2服务器数据库吗?

谢谢!

4

1 回答 1

1

最后我做到了!

我不得不扩展GuiceApplicationLoader和覆盖builder启动服务器的方法。

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));
    }
}
于 2018-03-29T23:42:21.057 回答