Rhythm & Biology

Engineering, Science, et al.

WildFly: ポート番号の変更方法

ポートを変更する方法を何種類か、備忘録

デフォルト

  • HTTPポート: 8080
  • 管理ポート: 9990

起動時にポート番号指定

  • HTTPポート: 18080
  • 管理ポート: 19990
$ ./standalone.sh \
    -Djboss.http.port=18080 \
    -Djboss.management.http.port=19990

起動時にオフセット値指定

オフセット値を指定すると、HTTPポート、管理ポートなど、全てのポート番号がオフセット値ぶんだけ加算されて起動する

同一マシンでWildFly複数立ち上げようとするとポートの衝突が問題になるが、オフセットを利用することで、全ポート番号を指定する必要がなくなる

$ ./standalone.sh -Djboss.socket.binding.port-offset=100

ちなみに、ポート番号指定も同時にすると、オフセット値は無視される(ポート番号指定されていないものだけにオフセット値が適用される)

standalone.xmlを直接編集

変数の部分にダイレクトに数値を埋め込む

書き方を真似すれば、デフォルトのポート番号を変更して、起動時にさらに変更可能にしておくこともできる

<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
    <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
    <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
    <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
    <socket-binding name="http" port="${jboss.http.port:8080}"/>
    <socket-binding name="https" port="${jboss.https.port:8443}"/>
    <socket-binding name="txn-recovery-environment" port="4712"/>
    <socket-binding name="txn-status-manager" port="4713"/>
    <outbound-socket-binding name="mail-smtp">
        <remote-destination host="localhost" port="25"/>
    </outbound-socket-binding>
</socket-binding-group>

CLIツールで編集

write-attributeコマンドを利用してポート番号を変更(standalone.xmlが書き変わる)

reloadコマンドを実行するとWildFlyが新しいポートで再起動する

$ ./jboss-cli.sh -c
[standalone@localhost:9990 /] /socket-binding-group=standard-sockets/socket-binding=http:write-attribute(name="port",value="18080")
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}
[standalone@localhost:9990 /] /socket-binding-group=standard-sockets/socket-binding=management-http:write-attribute(name="port",value="19990")
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}
[standalone@localhost:9990 /] :reload
{
    "outcome" => "success",
    "result" => undefined
}

WildFly: MySQLをデータソースとして利用 (CLI設定)

CLIツールにこだわって、WildFlyへのMySQLのドライバインストール、データソース追加までやってみます。

WildFlyのバージョンは8.1.0.Finalです。

ドライバのダウンロード

WildFlyにはドライバは標準ではついてこない(?)ため、ダウンロードしてきます。

$ cd $WILDFLY_HOME/bin
$ curl -LO http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.31.tar.gz
$ tar xvfz mysql-connector-java-5.1.31.tar.gz

ドライバのデプロイ

さきほどダウンロードしたドライバファイルをWildFlyにデプロイします。

$ ./jboss-cli.sh -c
[standalone@localhost:9990 /] module add --name=org.mysql --resources=mysql-connector-java-5.1.31/mysql-connector-java-5.1.31-bin.jar --dependencies=javax.api,javax.transaction.api
[standalone@localhost:9990 /] /subsystem=datasources/jdbc-driver=mysql:add(driver-module-name=org.mysql,driver-name=mysql,driver-class-name=com.mysql.jdbc.Driver)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=datasources/jdbc-driver=mysql:read-resource
{
    "outcome" => "success",
    "result" => {
        "deployment-name" => undefined,
        "driver-class-name" => "com.mysql.jdbc.Driver",
        "driver-datasource-class-name" => undefined,
        "driver-major-version" => undefined,
        "driver-minor-version" => undefined,
        "driver-module-name" => "org.mysql",
        "driver-name" => "mysql",
        "driver-xa-datasource-class-name" => undefined,
        "jdbc-compliant" => undefined,
        "module-slot" => undefined,
        "xa-datasource-class" => undefined
    }
}

データソースの追加

データソースの追加から、接続テストまでやります。

[standalone@localhost:9990 /] /subsystem=datasources/data-source=mysqlds:add(jndi-name=java:jboss/datasources/mysqlds,driver-name=mysql,connection-url=jdbc:mysql://localhost:3306/dbname,user-name=dbuser,password=dbpass)            
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=datasources/data-source=mysqlds:test-connection-in-pool
{
    "outcome" => "success",
    "result" => [true]
}
[standalone@localhost:9990 /] /subsystem=datasources/data-source=mysqlds:read-resource
{
    "outcome" => "success",
    "result" => {
        "allocation-retry" => undefined,
        "allocation-retry-wait-millis" => undefined,
        "allow-multiple-users" => false,
        "background-validation" => undefined,
        "background-validation-millis" => undefined,
        "blocking-timeout-wait-millis" => undefined,
        "capacity-decrementer-class" => undefined,
        "capacity-decrementer-properties" => undefined,
        "capacity-incrementer-class" => undefined,
        "capacity-incrementer-properties" => undefined,
        "check-valid-connection-sql" => undefined,
        "connection-listener-class" => undefined,
        "connection-listener-property" => undefined,
        "connection-properties" => undefined,
        "connection-url" => "jdbc:mysql://localhost:3306/dbname",
        "datasource-class" => undefined,
        "driver-class" => undefined,
        "driver-name" => "mysql",
        "enabled" => true,
        "exception-sorter-class-name" => undefined,
        "exception-sorter-properties" => undefined,
        "flush-strategy" => undefined,
        "idle-timeout-minutes" => undefined,
        "initial-pool-size" => undefined,
        "jndi-name" => "java:jboss/datasources/mysqlds",
        "jta" => true,
        "max-pool-size" => undefined,
        "min-pool-size" => undefined,
        "new-connection-sql" => undefined,
        "password" => "dbpass",
        "pool-prefill" => undefined,
        "pool-use-strict-min" => undefined,
        "prepared-statements-cache-size" => undefined,
        "query-timeout" => undefined,
        "reauth-plugin-class-name" => undefined,
        "reauth-plugin-properties" => undefined,
        "security-domain" => undefined,
        "set-tx-query-timeout" => false,
        "share-prepared-statements" => false,
        "spy" => false,
        "stale-connection-checker-class-name" => undefined,
        "stale-connection-checker-properties" => undefined,
        "track-statements" => "NOWARN",
        "transaction-isolation" => undefined,
        "url-delimiter" => undefined,
        "url-selector-strategy-class-name" => undefined,
        "use-ccm" => true,
        "use-fast-fail" => false,
        "use-java-context" => true,
        "use-try-lock" => undefined,
        "user-name" => "dbuser",
        "valid-connection-checker-class-name" => undefined,
        "valid-connection-checker-properties" => undefined,
        "validate-on-match" => false,
        "statistics" => {
            "jdbc" => undefined,
            "pool" => undefined
        }
    }
}

追加された設定

$ diff standalone/configuration/standalone.xml{.org,}
148a149,156
>                 <datasource jndi-name="java:jboss/datasources/mysqlds" pool-name="mysqlds" enabled="true">
>                     <connection-url>jdbc:mysql://localhost:3306/dbname</connection-url>
>                     <driver>mysql</driver>
>                     <security>
>                         <user-name>dbuser</user-name>
>                         <password>dbpass</password>
>                     </security>
>                 </datasource>
152a161,163
>                     <driver name="mysql" module="org.mysql">
>                         <driver-class>com.mysql.jdbc.Driver</driver-class>
>                     </driver>

サンプルアプリケーション

MySQL内のデータを読み書きする小さなWebアプリを作ってみます。

テーブル作成

idフィールドとnameフィールドだけを持つbookテーブルを作成。

create table book (
  id int primary key auto_increment,
  name varchar(128) not null
);

プロジェクト作成

今回はNetBeans8.0を使います。

  1. 新規プロジェクト
  2. Java Web
  3. Webアプリケーション
  4. プロジェクト名「SampleApp」
  5. サーバはWildFlyを選択
  6. Pluginをインストールし、WildFlyをサーバに追加しておく

Webサービス作成

  1. 新規
  2. データベースからのRESTful Webサービス
  3. データソースはmysqldsを選択
  4. テーブルはbookを選択
  5. パッケージ名は今回はcom.mythosilとする
  6. ApplicationConfigの作成
  7. BookFacadeRESTクラス上で「Alt+Enter」で作成

デプロイ・動作確認

デプロイはNetBeans上で「実行」ボタンを押すだけ。

動作確認はcurlで行います。

$ curl 'http://localhost:8080/SampleApp/webresources/com.mythosil.book' -X POST -H "Content-Type: application/json" -d '{"name":"Book1"}'
$ curl 'http://localhost:8080/SampleApp/webresources/com.mythosil.book' -X POST -H "Content-Type: application/json" -d '{"name":"Book2"}'
$ curl 'http://localhost:8080/SampleApp/webresources/com.mythosil.book' -H "Accept: application/json" | python -mjson.tool
[
    {
        "id": 1,
        "name": "Book1"
    },
    {
        "id": 2,
        "name": "Book2"
    }
]

補足1: 設定変更

write-attributeコマンドを利用します。
設定変更後は:reloadが必要です。

[standalone@localhost:9990 /] /subsystem=datasources/data-source=mysqlds:write-attribute(name=connection-url,value=jdbc:mysql://localhost:3306/otherdb)
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}
[standalone@localhost:9990 /] :reload
{
    "outcome" => "success",
    "result" => undefined
}

補足2: データソースの削除

データソースに対してremoveコマンドを実行するだけです。

[standalone@localhost:9990 /] /subsystem=datasources/data-source=mysqlds:remove
{"outcome" => "success"}

参考資料

WildFly: デプロイ時のnameとruntime-nameの役割

WildFlyへのCLIツールを利用したデプロイ時に--nameオプションと--runtime-nameオプションがあり、それぞれが何を意味しているのか分からなかったため、実験しつつ調べてみました。

まずはヘルプを読む

ざっくり把握した内容

  • nameはユニークでなければならない
  • 明示的に指定されなければ、ファイル名(war)がそのままnameになる
  • runtime-nameはユニークである必要はない
  • runtime-nameが重複している場合、どれか一つしか起動できない
[standalone@localhost:9990 /] deploy --help
SYNOPSIS

    deploy ((file_path | --url=deployment_url)
               [--script=script_name] [--name=deployment_name]
               [--runtime-name=deployment_runtime_name]
               [--force | --disabled] [--unmanaged])
           | --name=deployment_name
           [--server-groups=group_name (,group_name)* | --all-server-groups]
           [--headers={operation_header (;operation_header)*}]

DESCRIPTION

  Deploys the application designated by the file_path or enables an already
  existing but disabled in the repository deployment designated by the name
  argument. If executed w/o arguments, will list all the existing deployments.

ARGUMENTS
...(中略)...

 --name            - the unique name of the deployment. If the file path
                     argument is specified the name argument is optional with
                     the file name been the default value. If the file path
                     argument isn't specified then the command is supposed to
                     enable an already existing but disabled deployment, and in
                     this case the name argument is required.

 --runtime-name    - optional, the runtime name for the deployment. This will
                     form the basis for such things as default Java EE
                     application and module names. This would typically be the
                     same as --name, and if not specified the value used for
                     --name will be used. In some cases users may wish to have
                     two deployments with the same 'runtime-name' (e.g. two
                     versions of "example.war") both available in the management
                     configuration, in which case the deployments would need to
                     have distinct 'name' values but would have the same
                     'runtime-name'. Within an individual server, only one
                     deployment with a given 'runtime-name' can deployed.
                     However, multiple deployments with the same 'runtime-name'
                     can exist in the configuration, so long as only one is
                     enabled.

...(略)...

サンプルアプリケーション

2つのごく単純なアプリケーション(war)を用意

  • app-a.war: 「Hello, A」と表示
  • app-b.war: 「Hello, B」と表示

何もオプションを指定せずデプロイ

NAMERUNTIME-NAMEはどちらもそのままwarファイル名となります。
アプリケーションにアクセスする際も、warファイル名がURLに含まれます(suffixは除く)。

[standalone@localhost:9990 /] deploy app-a.war
[standalone@localhost:9990 /] deployment-info
NAME      RUNTIME-NAME PERSISTENT ENABLED STATUS 
app-a.war app-a.war    true       true    OK     
app-b.war app-b.war    true       true    OK

アンデプロイする時はNAME(=warファイル名)を指定します。
ファイルは残してdisabled状態にしたい場合は、--keep-contentオプションを付けます。

この状態でアクセスすると、どちらも「404 - Not Found」と表示されます。

[standalone@localhost:9990 /] undeploy app-a.war
[standalone@localhost:9990 /] undeploy app-b.war --keep-content
[standalone@localhost:9990 /] deployment-info 
NAME      RUNTIME-NAME PERSISTENT ENABLED STATUS  
app-b.war app-b.war    true       false   STOPPED

--nameオプションを指定してデプロイ

hoge.warにすると/hogeでアクセス出来るようになります。

[standalone@localhost:9990 /] deploy app-a.war --name=A.war
[standalone@localhost:9990 /] deploy app-b.war --name=B.war
[standalone@localhost:9990 /] deployment-info 
NAME  RUNTIME-NAME PERSISTENT ENABLED STATUS 
A.war A.war        true       true    OK     
B.war B.war        true       true    OK

アンデプロイは自分で指定したNAMEでやります。

[standalone@localhost:9990 /] undeploy A.war
[standalone@localhost:9990 /] undeploy B.war

--runtime-nameオプションを指定してデプロイ

どちらもapp.warというruntime-nameで起動しようとしてみます。

[standalone@localhost:9990 /] deploy app-a.war --runtime-name=app.war
[standalone@localhost:9990 /] deployment-info 
NAME      RUNTIME-NAME PERSISTENT ENABLED STATUS 
app-a.war app.war      true       true    OK     
[standalone@localhost:9990 /] deploy app-b.war --runtime-name=app.war
{"JBAS014653: Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-1" => "JBAS018785: There is already a deployment called app-a.war with the same runtime name app.war"}}

app-b.warのほうは、runtime-nameがかぶってしまったため、デプロイ失敗しました。
この状態で http://localhost:8080/app/ にアクセスすると「Hello, A」と表示されます。

次に、app-a.wardisabled状態に変えて、app-b.warをデプロイしてみます。

[standalone@localhost:9990 /] undeploy app-a.war --keep-content
[standalone@localhost:9990 /] deploy app-b.war --runtime-name=app.war
[standalone@localhost:9990 /] deployment-info 
NAME      RUNTIME-NAME PERSISTENT ENABLED STATUS  
app-a.war app.war      true       false   STOPPED 
app-b.war app.war      true       true    OK

この状態で http://localhost:8080/app/ にアクセスすると「Hello, B」という表示に変わっています。

まとめ

  • nameは管理上利用する名称
    • デプロイ・アンデプロイ時のコマンドの引数として与える
    • ユニークでなければならない
  • runtime-nameはURLの一部となる
    • ユニークである必要はない
    • 同一のruntime-nameのものは、どれか1つしかデプロイ状態にできない