WildFly(JBoss) 15 + Oracle 12c (非XA) のデータソース作成

Adam Bien氏が[INSTALLING ORACLE JDBC-DRIVER ON WILDFLY / JBOSS](http://www.adam-bien.com/roller/abien/entry/installing_oracle_jdbc_driver_on)という記事を公開しています。それをベースに、コメント欄のツッコミも考慮して、Oracle 12c PDBでは以下の手順でいけることを確認しました。

* [WildFly Full 15.0.0.Final](http://wildfly.org)
* [Oracle Database Server 12.2.0.1 Enterprise EditionのDockerイメージ](https://hub.docker.com/_/oracle-database-enterprise-edition)

## JBossへのCLIログイン

`[WILDFLY_HOME]/bin/jboss-cli.sh`を実行し、WildFlyサーバにログインしておきます。

```
$ ./jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect
```

## ドライバモジュールの登録

[元記事](http://www.adam-bien.com/roller/abien/entry/installing_oracle_jdbc_driver_on)には` [WILDFLY_HOME]/modules/system/layers/base/com/oracle/main/`にモジュールを置いて、そこに`module.xml`を書いて配置する旨の記述がありますが、コマンドを実行すれば、不要です。

```terminal:ojdbc7.jarを使う場合の例
[standalone@localhost:9990 /] module add --name=com.oracle.ojdbc7 --resources=[配置パス]/ojdbc7.jar --dependencies=javax.api,javax.transaction.api
```

コマンドの実行が成功すると、`[WILDFLY_HOME]/modules/com/oracle/ojdbc7/main`に`ojdbc7.jar`がコピーされ、`module.xml`が以下の内容で作成されます。

```module.xml
<module xmlns="urn:jboss:module:1.1" name="com.oracle.ojdbc7">

    <resources>
        <resource-root path="ojdbc7.jar"/>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.transaction.api"/>
    </dependencies>
</module>
```

> 元記事では`name="com.oracle"`で登録されていますが、複数のOracle JDBCドライバを使い分けることを考慮して、上記のように`ojdbc7`という名称を追加しています。

## ドライバを登録

[元記事](http://www.adam-bien.com/roller/abien/entry/installing_oracle_jdbc_driver_on)には` standalone.xml`に記述を追加する旨の記述がありますが、コマンドを実行すれば不要です。

```terminal:ojdbc7を登録する場合の例
[standalone@localhost:9990 /] /subsystem=datasources/jdbc-driver=ojdbc7:add(driver-name=ojdbc7,driver-module-name=com.oracle.ojdbc7,driver-class-name=oracle.jdbc.driver.OracleDriver)
```

コマンドの実行が成功すると、`[WILDFLY_HOME]/standalone/configuration/standalone-full.xml`に、以下の記述が追加されます。

```standalone-full.xml
<driver name="ojdbc7" module="com.oracle.ojdbc7">
    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
</driver>
```

## データソースを登録

[元記事](http://www.adam-bien.com/roller/abien/entry/installing_oracle_jdbc_driver_on)には` standalone.xml`に記述を追加する旨の記述がありますが、コマンドを実行すれば不要です。

以下は、サービス名が`ORCLPDB1.localdomain`であるOracle 12c PDBのHRスキーマを、`OracleDS`という名前で登録しています。

```terminal
[standalone@localhost:9990 /] /subsystem=datasources/data-source=OracleDS:add(jta="true",use-ccm="true",use-java-context="true",enabled="true",jndi-name=java:/jdbc/OracleDS,max-pool-size=5,min-pool-size=1,pool-prefill="true",driver-name=ojdbc7,connection-url=jdbc:oracle:thin:@//localhost:1521/ORCLPDB1.localdomain,user-name="hr",password="[PASS]")
```

コマンドの実行が成功すると、`[WILDFLY_HOME]/standalone/configuration/standalone-full.xml`に、以下の記述が追加されます。

```standalone-full.xml
<datasource jta="true" jndi-name="java:/jdbc/OracleDS" pool-name="OracleDS" enabled="true" use-java-context="true" use-ccm="true">
    <connection-url>jdbc:oracle:thin:@//localhost:1521/ORCLPDB1.localdomain</connection-url>
    <driver>ojdbc7</driver>
    <pool>
        <min-pool-size>1</min-pool-size>
        <max-pool-size>5</max-pool-size>
        <prefill>true</prefill>
    </pool>
    <security>
        <user-name>hr</user-name>
        <password>[PASS]</password>
    </security>
</datasource>
```

## 接続テスト

以下のコマンドを実行します。

```terminal:OracleDSデータソースをテストする場合
[standalone@localhost:9990 /] /subsystem=datasources/data-source=OracleDS:test-connection-in-pool
```

このように返ってきたら、成功です。

```terminal
{
    "outcome" => "success",
    "result" => [true]
}
```

参考: [Red Hat JBoss Enterprise Application Platform 7.0 設定ガイド 13.6. データソース接続のテスト](https://access.redhat.com/documentation/ja-jp/red_hat_jboss_enterprise_application_platform/7.0/html/configuration_guide/datasource_management)

## うまくいかないときは

```terminal
{
    "outcome" => "failed",
    "failure-description" => "WFLYJCA0040: failed to invoke operation: WFLYJCA0047: Connection is not valid",
    "rolled-back" => true
}
```

`[WILDFLY_HOME]/standalone/log/server.log`で、`WFLYJCA0040: failed to invoke operation: WFLYJCA0047: Connection is not valid`のメッセージの直前に表示されているスタックトレースの最後のほうを確認します。

### ケース1

```
Caused by: oracle.net.ns.NetException: Invalid number format for port number
```

`jdbc:oracle:thin:@//localhost:1521:ORCLPDB1.localdomain`のように、サービス名の前を`/`ではなく`:`にしてしまっています。

### ケース2

```
Caused by: java.sql.SQLException: 無効なOracle URLが指定されました。
```

`jdbc:oracle:thin@//localhost:1521/ORCLPDB1.localdomain`のように、`@`の前に`:`を追加していません。

### ケース3

```
Caused by: oracle.net.ns.NetException: Listener refused the connection with the following error:
ORA-12514, TNS:listener does not currently know of service requested in connect descriptor
```

リスナーには到達したようですが、リスナーが認識していないサービス名を指定しています。

### ケース4

```
Caused by: oracle.net.ns.NetException: Unknown host specified 

Caused by: java.net.SocketTimeoutException: connect timed out

Caused by: java.net.ConnectException: Connection refused (Connection refused)
```

リスナーに到達する以前の問題です。ホスト名やポート番号に誤りがあります。

### 消してやり直す

間違いに気づいたら、データソースを一旦削除して、やり直します。削除した後は、リロードが必要です。

```terminal:OracleDSデータソースの削除とリロード
[standalone@localhost:9990 /] /subsystem=datasources/data-source=OracleDS:remove
[standalone@localhost:9990 /] reload
```