JDK6(Java) + JDBC OCI Driver(type 2) で Autonomous Database に接続してみる。

ゆえ有って、JDK6(Java) + JDBC OCI Driver(type 2) で Autonomous Database に接続してみます。

# 1. Oracle Instant Client 12.1.0.2 をダウンロード＆解凍

Oracle Instant Client をダウンロードします。JDK6に対応した ojdbc6.jar を含む 12.1.0.2 の Instant Client をダウンロードします。

 > * Instant Client Downloads for Linux x86-64 (64-bit)  
 > https://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html  
 > instantclient-basic-linux.x64-12.1.0.2.0.zip  
 > instantclient-jdbc-linux.x64-12.1.0.2.0.zip  

今回は /home/opc/work/instantclient_12_1/ に展開したものとします。

```shell
unzip instantclient-basic-linux.x64-12.1.0.2.0.zip
unzip instantclient-jdbc-linux.x64-12.1.0.2.0.zip
ls -la /home/opc/work/instantclient_12_1/
total 192020
drwxrwxr-x. 2 opc opc      4096 Jul 20 10:41 .
drwxrwxr-x. 7 opc opc      4096 Jul 21 12:55 ..
-rwxrwxr-x. 1 opc opc     29404 Jul  7  2014 adrci
:
-r-xr-xr-x. 1 opc opc    156353 Jul  7  2014 libocijdbc12.so
-r-xr-xr-x. 1 opc opc    337137 Jul  7  2014 libons.so
-rwxrwxr-x. 1 opc opc    118491 Jul  7  2014 liboramysql12.so
-r--r--r--. 1 opc opc   3692096 Jul  7  2014 ojdbc6.jar
-r--r--r--. 1 opc opc   3698857 Jul  7  2014 ojdbc7.jar
-r--r--r--. 1 opc opc   1659574 Jul  7  2014 orai18n.jar
-r--r--r--. 1 opc opc     87292 Jul  7  2014 orai18n-mapping.jar
-rwxrwxr-x. 1 opc opc    227410 Jul  7  2014 uidrvci
-rw-rw-r--. 1 opc opc     71202 Jul  7  2014 xstreams.jar
```

# 2. Autonomous Database のウォレットをダウンロード＆解凍

Autonomous Database のウォレットをダウンロードして展開します。下記記事等を参照して下さい。

 > * 自律型データベース(Autonomous Transaction Processing)に Golang を使って接続  
 > https://qiita.com/sugimount/items/69e11c116a895c9feb97

```shell
cd /home/opc/work/wallet
unzip Wallet_DBxxxxxxxxxxxxxx.zip
ls -la
total 68
drwxrwxr-x. 2 opc opc  4096 Jul 21 13:36 .
drwxrwxr-x. 6 opc opc  4096 Jul 21 13:36 ..
-rw-rw-r--. 1 opc opc  6661 Jun 24 10:18 cwallet.sso
-rw-rw-r--. 1 opc opc  6616 Jun 24 10:18 ewallet.p12
-rw-rw-r--. 1 opc opc  3242 Jun 24 10:18 keystore.jks
-rw-rw-r--. 1 opc opc    87 Jun 24 10:18 ojdbc.properties
-rw-rw-r--. 1 opc opc   114 Jun 24 10:18 sqlnet.ora
-rw-rw-r--. 1 opc opc  5638 Jun 24 10:18 tnsnames.ora
-rw-rw-r--. 1 opc opc  3336 Jun 24 10:18 truststore.jks
-rw-rw-r--. 1 opc opc 19912 Jun 24 10:18 Wallet_DBxxxxxxxx.zip
```

# 3. Autonomous Database のウォレットのsqlnet.oraを編集

ウォレットのzipを展開するとsqlnet.oraが生成されますが、この sqlnet.ora の DIRECTORY をウォレットの展開ディレクトリに書き換えます。

```
WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="?/network/admin")))
↓
WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="/home/opc/work/wallet")))
```

# 4. テスト用のサンプルコード

finally でリソース解放もしていない雑コードだけど、許してクレメンス……:(;ﾞﾟ'ωﾟ'):
JDK6だとtry-with-resources構文が使えないんですよねー。彡(ﾟ)(ﾟ)

```java
import java.sql.*;

public class GetContainerName {
    public static void main(String[] args) {
        final String path = "jdbc:oracle:oci:@dbxxxxxxxx_tp";
        final String id = "ADMIN";  //ID
        final String pw = "xxxxxxxx";  //password

        try {
            Connection conn = DriverManager.getConnection(path, id, pw);
            Statement  stmt = conn.createStatement();
            ResultSet  rs   = stmt.executeQuery("SELECT NAME FROM V$CONTAINERS");
            while (rs.next()) {
                String cn = rs.getString("name");
                System.out.println("Container Name => " + cn);
            }
        } catch(SQLException ex) {
            ex.printStackTrace();  //Error
        }
    }
}
```

ポイントは JDBC URL のココ、ociドライバを指定しつつtnsnames.oraの接続文字列を指定します。

```java
final String path = "jdbc:oracle:oci:@dbxxxxxxxx_tp";
```

# 5. コードのコンパイルと実行

javacでコンパイルして実行します。実行時には下記の環境変数を指定します。

> * LD_LIBRARY_PATH  
> ⇒ Oracle Instant Client を展開したディレクトリを指定します。
> * TNS_ADMIN  
> ⇒ Autonomous Database のウォレットを展開したディレクトリを指定します。

実行コマンドは下記の通りです。

```shell
export JAVA_HOME=/usr/java/jdk1.6.0_211
export PATH=${JAVA_HOME}/bin:${PATH}
java -version
javac -version
javac GetContainerName.java
export LD_LIBRARY_PATH=/home/opc/work/instantclient_12_1:$LD_LIBRARY_PATH
export TNS_ADMIN=/home/opc/work/wallet
java -classpath /home/opc/work/instantclient_12_1/ojdbc6.jar:. GetContainerName
```

実行結果は下記の通り、上手く動いたやで！彡(^)(^)

```shell
$ export JAVA_HOME=/usr/java/jdk1.6.0_211
$ export PATH=${JAVA_HOME}/bin:${PATH}
$ java -version
java version "1.6.0_211"
Java(TM) SE Runtime Environment (build 1.6.0_211-b11)
Java HotSpot(TM) 64-Bit Server VM (build 20.211-b11, mixed mode)
$ javac -version
javac 1.6.0_211
$ javac GetContainerName.java
$ export LD_LIBRARY_PATH=/home/opc/work/instantclient_12_1:$LD_LIBRARY_PATH
$ export TNS_ADMIN=/home/opc/work/wallet
java -classpath /home/opc/work/instantclient_12_1/ojdbc6.jar:. GetContainerName

Container Name => VRWV9351YZ4NXNS_DB201906031608
```

# 6. 参考ドキュメント

> * Connection using JDBC-OCI driver using Wallets
> https://www.oracle.com/technetwork/database/application-development/jdbc-eecloud-3089380.html#jdbcoci
>  
> * Oracle JDBCのリリースとJDKのバージョンの関連について教えてください。
> https://www.oracle.com/technetwork/jp/database/application-development/jdbc/overview/default-090281-ja.html#01_03_1
>  
> * Oracle JDBC Driver スタート・ガイド - インストール、動作保証、その他 (ドキュメントID 1999901.1) ※要ログイン
> https://support.oracle.com/epmos/faces/DocumentDisplay?id=1999901.1


# 補足. Thin Driver では接続できないのか？

Autonomous Database は TLSv1.2 で通信する必要があり、JDK8以降では標準装備、JDK7ではバックポート用のパッチが提供されているのですが、~~JDK6 だとこのバックポートが提供されていない模様で、苦しそう？~~彡(ﾟ)(ﾟ)  
  
 > * JDBC Thin Connections and Wallets  
 > https://docs.oracle.com/en/cloud/paas/autonomous-data-warehouse-cloud/user/connect-jdbc-thin-wallet.html#GUID-5ED3C08C-1A84-4E5A-B07A-A5114951AA9E  
 > > Autonomous Data Warehouse mandates a secure connection that uses Transport Layer Security (TLSv1.2).   
> 
> * JDBC ThinおよびUCPを使用した接続のためのソフトウェア要件
> https://docs.oracle.com/cd/E83857_01/paas/atp-cloud/atpug/connecting-jdbc-thin-driver.html#GUID-EEB8AC2B-AE63-486A-A7DB-96460DCA881E
> > パッチ適用済の12.1.0.2 JDBC Thinドライバ (ojdbc7.jar)と12.1.0.2 UCP (ucp.jar)をダウンロードし、その場所をクラスパスに追加します。
>  
> * Doc ID 2122800.1 "IO Error: No appropriate protocol" When Trying to Connect to Oracle Database 12.1 with TLSv1.1 and TLSv1.2 Protocols ※要ログイン
> https://support.oracle.com/epmos/faces/DocumentDisplay?id=2122800.1

(追記)下記で JDK6 + JDBC Thin Driver 12.1.0.2 でも接続できる事を確認しました。サポート契約が有る方はご参照下さい。

 > * JDK6 u211(JDK6 u181以降) を Doc ID 1534791.1 からダウンロードしてきてインストール
 > * Oracle Client(※Instantではない) 12.1.0.2 をインストール
 > * Oracle Client に PSU 12.1.0.2.20190716(Patch 29494060)を適用
 > * Oracle Client に 個別Patch 23176395(※20426934, 19030178, 19154304 の Merge版)を適用  
 > * Oracle Client に 個別Patch 25797943(※12.1.0.2版を選択)を適用  
 > * Patchによるバックポートが適用された Oracle Client配下のJDBC Driver(ojdbc6.jar)や各種jarを指定して接続

参考情報は下記となります。

 > * Java SE and JRockit Archived Downloads on MOS for Java Versions that Have Reached EOL (Doc ID 1534791.1)  
 > https://support.oracle.com/epmos/faces/DocumentDisplay?id=1534791.1
 > * JDBC TLS Connections Fail with java.io.EOFException: SSL peer shut down incorrectly After Patching the Database With APRIL 2018 PSU + TLS 1.2 Patch:28362304 (Doc ID 2477104.1)  
 > https://support.oracle.com/epmos/faces/DocumentDisplay?id=2477104.1
 > * JDBC Thin Driver receives "java.security.NoSuchAlgorithmException: SSO KeyStore not available" (Doc ID 2321763.1)  
 > https://support.oracle.com/epmos/faces/DocumentDisplay?id=2321763.1  
 > * "IO Error: No appropriate protocol" When Trying to Connect to Oracle Database 12.1 with TLSv1.1 and TLSv1.2 Protocols (ドキュメントID 2122800.1)  
https://support.oracle.com/epmos/faces/DocumentDisplay?id=2122800.1  
 > * Java SE 6 Advanced and Java SE 6 Support 
(formerly known as Java SE for Business 6)
Release Notes  
 > https://www.oracle.com/technetwork/java/javase/downloads/overview-156328.html#R160_181  
 > ⇒ (6u181)The SHA224withDSA and SHA256withDSA algorithms are now supported in the TLS 1.2  
 > * How To Configure Oracle JDBC Thin Driver To Connect To Database Using TLS v1.2 (ドキュメントID 2436911.1)  
 > https://support.oracle.com/epmos/faces/DocumentDisplay?id=2436911.1