payara-embedded-all が Address already in use: bind で複数起動できない場合の対処方


JMS ポートがバッティングして起動できない

payara-embedded-allで以下のようにアプリケーションサーバを起動できる。

final var gf = GlassFishRuntime
        .bootstrap(new BootstrapProperties())
        .newGlassFish(new GlassFishProperties());
gf.start();

ポート番号などは、GlassFishProperties を経由して設定できる。

var properties = new GlassFishProperties();
properties.setPort("http-listener", 8080);

しかしJMSのポートは起動時に変更できないため、複数インスタンスを起動すると java.net.BindException: Address already in use: bind となる。

以下のコマンドでポート番号を変更できるが、設定反映には再起動が必要であり望ましくない。

asadmin set configs.config.server-config.jms-service.jms-host.default_JMS_host.port=7677


payara-embedded-all に含まれる domain.xml を書き換える

GlassFishRuntime 起動時には、payara-embedded-all 内の config/domain.xml が展開されて利用される。

ポート番号は以下のようにシステムプロパティとして定義されているので、この 7676 を書き換えれば良い。

<system-property name="JMS_PROVIDER_PORT" value="7676" description="Port Number that JMS Service will listen for remote clients connection." />

以下の要領で FatJar 生成時に置換してやると良い。

tasks.named<Jar>("jar") {

    dependsOn(":ear:ear")
    setProperty("zip64", true)
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    dependsOn(configurations.runtimeClasspath)
    from({
        configurations.runtimeClasspath.get()
            .filter { it.name.endsWith("jar") }
            .map { zipTree(it) }
    }) {
        exclude("META-INF/*.SF")
        exclude("META-INF/*.DSA")
        exclude("META-INF/*.RSA")
        filesMatching("config/domain.xml") { // replace jms port
            filter { line ->
                if (line.contains("""name="JMS_PROVIDER_PORT" value="7676"""")) {
                    line.replace("""value="7676"""", """value="7677"""")
                } else {
                    line
                }
            }
        }
    }
    from(sourceSets.main.get().output)
    // ...
}


glassfish-embedded-all の場合は org/glassfish/embed/domain.xml にある以下の定義を書き換えれば良い。

<jms-service type="EMBEDDED" default-jms-host="default_JMS_host">
    <jms-host name="default_JMS_host" host="localhost" port="7676" admin-user-name="admin" admin-password="admin" lazy-init="false"/>
</jms-service>