Oracle Autonomous Database 21c へJDBC Thin接続してみてみた

Autonomous DatabaseではTransport Layer Security (TLSv1.2)を使用するセキュアな接続が要求されます。 JDBC Thinドライバを使用するJavaアプリケーションには、Oracle WalletまたはJava KeyStore (JKS)が必要です。 
ということで、[JDBCコード・サンプル](https://github.com/oracle/oracle-db-examples/tree/master/java/jdbc/ConnectionSamples)から[DataSourceSample.java](https://github.com/oracle/oracle-db-examples/blob/master/java/jdbc/ConnectionSamples/DataSourceSample.java)と[UCPSample.java](https://github.com/oracle/oracle-db-examples/blob/master/java/jdbc/ConnectionSamples/UCPSample.java)をダウンロードしてJDBC Thin接続できることを確認してみてみます。


# ■ 環境

|項目|version|
|---|---|
Autonomous Database	|	21c(21.1.0.0.0)
Client OS |  Oracle Linux Server release 7.9
Oracle Instant Client |	12.2.0.1, 19.8.0.0.0, or 21.1.0.0.0
JDK |		JDK8(openjdk 1.8.0) or JDK11(openjdk 11.0.9.11)
JDBC 			|		ojdbc8 (Oracle Database 21c (21.1)  drivers)



# ■ 事前準備
事前に sqlplusでhrスキーマへ接続しSQLできることを確認しておきます。
Autonomous DatabaseとhrスキーマーとOracle Clientは以下を参考に事前に設定しておきます。
　・参考: [Autonomous Database 21c へsqlplus接続してHRスキーマ作成してみてみた](https://qiita.com/shirok/items/bcc355de5515ee54e8dc)


## ● hrスキーマ接続テスト
```shell
[opc@oci-inst01 ~]$ sqlplus hr/Password@atp_high

	SQL*Plus: Release 12.2.0.1.0 Production on Wed Jan 20 01:23:22 2021

	Copyright (c) 1982, 2016, Oracle.  All rights reserved.

	Last Successful login time: Tue Jan 19 2021 15:46:29 +00:00

	Connected to:
	Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production

SQL> select count(*) from employees;

	COUNT(*)
	----------
		107
```

# ■ JDK 8 インストール

## ● Java 8 (JDK) Runtime インストール

```shell
[root@oci-inst01 opc]# yum install java-1.8.0-openjdk
	読み込んだプラグイン:langpacks, ulninfo
	依存性の解決をしています
	--> トランザクションの確認を実行しています。
	---> パッケージ java-1.8.0-openjdk.x86_64 1:1.8.0.275.b01-0.el7_9 を インストール
```


## ● Java 8 (JDK) Development Kit  インストール

```shell
[root@oci-inst01 opc]# yum install java-1.8.0-openjdk-devel
	読み込んだプラグイン:langpacks, ulninfo
	依存性の解決をしています
	--> トランザクションの確認を実行しています。
	---> パッケージ java-1.8.0-openjdk-devel.x86_64 1:1.8.0.275.b01-0.el7_9 を インストール
	--> 依存性解決を終了しました。

	依存性を解決しました

	========================================================================================================================================================
	Package                                     アーキテクチャー          バージョン                                   リポジトリー                   容量
	========================================================================================================================================================
	インストール中:
	java-1.8.0-openjdk-devel                    x86_64                    1:1.8.0.275.b01-0.el7_9                      ol7_latest                    9.7 M

	トランザクションの要約
	========================================================================================================================================================
	インストール  1 パッケージ

	総ダウンロード容量: 9.7 M
	インストール容量: 40 M
	Is this ok [y/d/N]:  y
	Downloading packages:
	java-1.8.0-openjdk-devel-1.8.0.275.b01-0.el7_9.x86_64.rpm                                                                        | 9.7 MB  00:00:00
	Running transaction check
	Running transaction test
	Transaction test succeeded
	Running transaction
	インストール中          : 1:java-1.8.0-openjdk-devel-1.8.0.275.b01-0.el7_9.x86_64                                                                 1/1
	検証中                  : 1:java-1.8.0-openjdk-devel-1.8.0.275.b01-0.el7_9.x86_64                                                                 1/1

	インストール:
	java-1.8.0-openjdk-devel.x86_64 1:1.8.0.275.b01-0.el7_9

	完了しました!
```


## ● Java Version確認

```shell
[opc@oci-inst01 ~]$ java -version
	openjdk version "1.8.0_275"
	OpenJDK Runtime Environment (build 1.8.0_275-b01)
	OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)
```







# ■ JDK 11 インストール

## ● Java 11 (JDK) Runtime インストール

```shell
[opc@oci-inst01 ~]$ sudo yum install -y java-11-openjdk
		読み込んだプラグイン:langpacks, ulninfo
		依存性の解決をしています
		--> トランザクションの確認を実行しています。
		---> パッケージ java-11-openjdk.x86_64 1:11.0.9.11-2.0.1.el7_9 を インストール
		--> 依存性の処理をしています: java-11-openjdk-headless(x86-64) = 1:11.0.9.11-2.0.1.el7_9 のパッケージ: 1:java-11-openjdk-11.0.9.11-2.0.1.el7_9.x86_64
		--> トランザクションの確認を実行しています。
		---> パッケージ java-11-openjdk-headless.x86_64 1:11.0.9.11-2.0.1.el7_9 を インストール
		--> 依存性解決を終了しました。

		依存性を解決しました

		========================================================================================================================================================
		Package                                     アーキテクチャー          バージョン                                   リポジトリー                   容量
		========================================================================================================================================================
		インストール中:
		java-11-openjdk                             x86_64                    1:11.0.9.11-2.0.1.el7_9                      ol7_latest                    224 k
		依存性関連でのインストールをします:
		java-11-openjdk-headless                    x86_64                    1:11.0.9.11-2.0.1.el7_9                      ol7_latest                     39 M

		トランザクションの要約
		========================================================================================================================================================
		インストール  1 パッケージ (+1 個の依存関係のパッケージ)

		総ダウンロード容量: 39 M
		インストール容量: 165 M
		Downloading packages:
		(1/2): java-11-openjdk-11.0.9.11-2.0.1.el7_9.x86_64.rpm                                                                          | 224 kB  00:00:00
		(2/2): java-11-openjdk-headless-11.0.9.11-2.0.1.el7_9.x86_64.rpm                                                                 |  39 MB  00:00:01
		--------------------------------------------------------------------------------------------------------------------------------------------------------
		合計                                                                                                                     35 MB/s |  39 MB  00:00:01
		Running transaction check
		Running transaction test
		Transaction test succeeded
		Running transaction
		インストール中          : 1:java-11-openjdk-headless-11.0.9.11-2.0.1.el7_9.x86_64                                                                 1/2
		インストール中          : 1:java-11-openjdk-11.0.9.11-2.0.1.el7_9.x86_64                                                                          2/2
		検証中                  : 1:java-11-openjdk-11.0.9.11-2.0.1.el7_9.x86_64                                                                          1/2
		検証中                  : 1:java-11-openjdk-headless-11.0.9.11-2.0.1.el7_9.x86_64                                                                 2/2

		インストール:
		java-11-openjdk.x86_64 1:11.0.9.11-2.0.1.el7_9

		依存性関連をインストールしました:
		java-11-openjdk-headless.x86_64 1:11.0.9.11-2.0.1.el7_9

		完了しました!
```



## ● Java 11 (JDK) Development Kit インストール

```shell
[opc@oci-inst01 ~]$ yum install java-11-openjdk-devel
		読み込んだプラグイン:langpacks, ulninfo
		このコマンドを実行するには root である必要があります。
		[opc@oci-inst01 ~]$ sudo yum install java-11-openjdk-devel
		読み込んだプラグイン:langpacks, ulninfo
		依存性の解決をしています
		--> トランザクションの確認を実行しています。
		---> パッケージ java-11-openjdk-devel.x86_64 1:11.0.9.11-2.0.1.el7_9 を インストール
		--> 依存性解決を終了しました。

		依存性を解決しました

		========================================================================================================================================================
		Package                                   アーキテクチャー           バージョン                                   リポジトリー                    容量
		========================================================================================================================================================
		インストール中:
		java-11-openjdk-devel                     x86_64                     1:11.0.9.11-2.0.1.el7_9                      ol7_latest                     3.3 M

		トランザクションの要約
		========================================================================================================================================================
		インストール  1 パッケージ

		総ダウンロード容量: 3.3 M
		インストール容量: 5.2 M
		Is this ok [y/d/N]: y
		Downloading packages:
		java-11-openjdk-devel-11.0.9.11-2.0.1.el7_9.x86_64.rpm                                                                           | 3.3 MB  00:00:00
		Running transaction check
		Running transaction test
		Transaction test succeeded
		Running transaction
		インストール中          : 1:java-11-openjdk-devel-11.0.9.11-2.0.1.el7_9.x86_64                                                                    1/1
		検証中                  : 1:java-11-openjdk-devel-11.0.9.11-2.0.1.el7_9.x86_64                                                                    1/1

		インストール:
		java-11-openjdk-devel.x86_64 1:11.0.9.11-2.0.1.el7_9

		完了しました!
```

# ■ Javaのバージョンの切り替え
複数のJDK 8と11等がインストールされている場合
使用したいバージョンは、切り替えをすることで使いたいバージョンを設定できます

## ● Java バージョン切り替え
alternativesコマンドで表示される選択番号を選択することで、JAVAバージョンを切り替えることができます

```shell
[opc@oci-inst01 ~]$ sudo alternatives --config java

	2 プログラムがあり 'java' を提供します。

	選択       コマンド
	-----------------------------------------------
	*+ 1           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre/bin/java)
	2           java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.9.11-2.0.1.el7_9.x86_64/bin/java)

	Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2
```


## ● javaバージョン確認

```shell
[opc@oci-inst01 ~]$ java -version
	openjdk version "11.0.9.1" 2020-11-04 LTS
	OpenJDK Runtime Environment 18.9 (build 11.0.9.1+1-LTS)
	OpenJDK 64-Bit Server VM 18.9 (build 11.0.9.1+1-LTS, mixed mode, sharing)
```



# ■ 環境変数の設定
## ● JDK 8(openjdk 1.8.0)の場合

**・ JAVA_HOME pathの確認**

```shell
[opc@oci-inst01 jvm]$ dirname $(readlink $(readlink $(which java)))
	/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre/bin
```


**・ 環境変数の設定**

```shell
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar 
export JRE_HOME=$JAVA_HOME/jre
```



## ● JDK 11 (openjdk 11.0.9.1)の場合

**・ JAVA_HOME pathの確認**

```shell
[opc@oci-inst01 ~]$ dirname $(readlink $(readlink $(which java)))
	/usr/lib/jvm/java-11-openjdk-11.0.9.11-2.0.1.el7_9.x86_64/bin
```

**・ 環境変数の設定**

```shell
export JAVA_HOME=/usr/lib/jvm/jre-11-openjdk-11.0.9.11-2.0.1.el7_9.x86_64
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar 
export JRE_HOME=$JAVA_HOME/jre
```





# ■ JDK 8 追加設定 
JDKバージョンがJDK8u162より小さい場合は、JCE Unlimited Strength Jurisdiction Policy Filesをダウンロードする必要があります。 インストール・ノートについては、READMEファイルを参照してください。 「Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8ダウンロード」からJCEファイルをダウンロードします。
JDK11, JDK10, or JDK9の場合は不要

## ●JCE Unlimited Strength Jurisdiction Policy Files設定
**1) ダウンロード**

・JCE Unlimited Strength Jurisdiction Policy Files
https://www.oracle.com/java/technologies/javase-jce8-downloads.html

```shell
[root@oci-inst01 tmp]# ls -l
	合計 16
	-rw-rw-r--. 1 opc opc 12417  1月 18 04:39 jce_policy-8.zip
```


**2) zip解凍**

```shell
[root@oci-inst01 tmp]# unzip jce_policy-8.zip
	Archive:  jce_policy-8.zip
	creating: UnlimitedJCEPolicyJDK8/
	inflating: UnlimitedJCEPolicyJDK8/US_export_policy.jar
	inflating: UnlimitedJCEPolicyJDK8/local_policy.jar
	inflating: UnlimitedJCEPolicyJDK8/README.txt
```


**3) US_export_policy.jar 設定**
JDK8(java-1.8.0)の $JAVA_HOME/jre/lib/security 配下へファイルを配置

```shell
[root@oci-inst01 tmp]# ls -l UnlimitedJCEPolicyJDK8/
	合計 24
	-rw-r--r--. 1 root root 7921  7月  1  2020 README.txt
	-rw-r--r--. 1 root root 5373  6月 19  2020 US_export_policy.jar
	-rw-r--r--. 1 root root 5372  6月 19  2020 local_policy.jar

[root@oci-inst01 UnlimitedJCEPolicyJDK8]# mv UnlimitedJCEPolicyJDK8/US_export_policy.jar local_policy.jar /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre/lib/security

[root@oci-inst01 UnlimitedJCEPolicyJDK8]# ls -l /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre/lib/security
	合計 76
	-rw-r--r--. 1 root root  5373  6月 19  2020 US_export_policy.jar
	-rw-r--r--. 1 root root  2488 12月 15 18:10 blacklisted.certs
	lrwxrwxrwx. 1 root root    41  1月 18 05:12 cacerts -> ../../../../../../../etc/pki/java/cacerts
	-rw-r--r--. 1 root root  2567 12月 15 18:10 java.policy
	-rw-r--r--. 1 root root 47872  1月  1  2014 java.security
	-rw-r--r--. 1 root root  5372  6月 19  2020 local_policy.jar
	-rw-r--r--. 1 root root   139 12月 15 18:14 nss.cfg
	drwxr-xr-x. 4 root root    38  1月 18 05:12 policy
```


## ● ウォレットのロケーションの設定
・$JAVA_HOME/jre/lib/security/java.securityファイル設定

**1) java.securityファイル確認**

```shell
[opc@oci-inst01 ~]$ ls -l /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre/lib/security/java.security
	-rw-r--r--. 1 root root 47872  1月  1  2014 java.security
```


**2) java.securityファイル設定**
・末尾に以下１行追加

　security.provider.14=oracle.security.pki.OraclePKIProvider

```shell
[root@oci-inst01 security]# vi /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre/lib/security/java.security
[root@oci-inst01 security]# tail -2 java.security
	#Wallet Loction
	security.provider.14=oracle.security.pki.OraclePKIProvider
```




# ■ JDBCインストール

## ● ojdbc8-full.tar.gzダウンロード

・JDBC and UCP Downloads page
https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html
※ 21.1, 19.9 と 12.2のファイルは同じ名前ojdbc8-full.tar.gzですが、Bytes数が異なり中身は別物なので注意


## ● JDBC (ojdbc8)配置
今回は、＄HOME/oracleディレクトリへ配置してみます

**1) 配置ディレクトリ移動**

```shell
[opc@oci-inst01 ~]$ cd ＄HOME/oracle
```

**2) tar.gz解凍配置**

```shell
[opc@oci-inst01 oracle]$ tar zxvf /tmp/ojdbc8-full.tar.gz
[opc@oci-inst01 oracle]$ ls -l ojdbc8-full/
    合計 12144
    drwxr-xr-x. 2 opc opc    4096  1月 14 19:52 .
    drwxrwxr-x. 8 opc opc    4096  1月 20 12:56 ..
    -rw-r--r--. 1 opc opc    5903  1月 14 19:51 BASIC_LICENSE.txt
    -rw-r--r--. 1 opc opc    3324  1月 15 10:54 README.txt
    -rw-r--r--. 1 opc opc   11515  1月 14 19:51 ojdbc.policy
    -rw-r--r--. 1 opc opc 5040465  1月 14 19:51 ojdbc8.jar
    -rw-r--r--. 1 opc opc  198469  1月 14 19:51 ons.jar
    -rw-r--r--. 1 opc opc  306476  1月 14 19:51 oraclepki.jar
    -rw-r--r--. 1 opc opc 1664450  1月 14 19:51 orai18n.jar
    -rw-r--r--. 1 opc opc  210338  1月 14 19:51 osdt_cert.jar
    -rw-r--r--. 1 opc opc  312230  1月 14 19:51 osdt_core.jar
    -rw-r--r--. 1 opc opc  345036  1月 14 19:51 rsi.jar
    -rw-r--r--. 1 opc opc   32169  1月 14 19:51 simplefan.jar
    -rw-r--r--. 1 opc opc 1788363  1月 14 19:51 ucp.jar
    -rw-r--r--. 1 opc opc  265864  1月 14 19:51 xdb.jar
    -r--r--r--. 1 opc opc  262415  8月  2  2018 xdb6.jar
    -rw-r--r--. 1 opc opc 1951430  1月 14 19:51 xmlparserv2.jar
```


**3) Version確認**

```shell
[opc@oci-inst01 ojdbc8-full]$ java -jar ./ojdbc8-full/ojdbc8.jar -version
	    Oracle 21.1.0.0.0 JDBC 4.2 compiled with javac 1.8.0_271 on Fri_Oct_09_09:20:04_PDT_2020
    #Default Connection Properties Resource
    #Wed Jan 20 12:57:33 GMT 2021

    ***** JCE UNLIMITED STRENGTH IS INSTALLED ****
```




# ■ Java KeyStore使用設定
Java KeyStore (JKS)および18.3 JDBC Thinドライバを使用してAutonomous Transaction Processingに接続するには、次のステップを実行します。
JKSに関連する接続プロパティを設定: JKSに関連する接続プロパティをojdbc.propertiesファイルに追加します。 keyStoreおよびトラスト・ストアのパスワードは、Autonomous Transaction Processingサービス・コンソールからクライアント資格証明.zipファイルをダウンロードする際に指定されるパスワードです。
Oracle WalletではなくSSL接続を使用するには、次のように、キーストアおよびトラスト・ストアのファイルおよびそのパスワードをojdbc.propertiesファイルで指定します。
 ※ 12.2または以前のJDBCドライバでは、ojdbc.propertiesファイルがサポートされません。 より古いJDBCドライバ・バージョンでは、ウォレットまたはJKS関連プロパティをシステム・プロパティとして渡すか、接続を確立する接続プロパティとして渡す必要があります。

## ● ojdbc.propertiesファイル設定
$TNS_ADMIN配下にojdbc.propertiesファイルへパスワード設定

```shell
[opc@oci-inst01 ~]$ cd $TNS_ADMIN
[opc@oci-inst01 ~]$ pwd 
	/home/opc/oracle/instantclient_19_8/network/admin
[opc@oci-inst01 admin]$ cat ojdbc.properties
	# Connection property while using Oracle wallets.
	oracle.net.wallet_location=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=${TNS_ADMIN})))
	# FOLLOW THESE STEPS FOR USING JKS
	# (1) Uncomment the following properties to use JKS.
	# (2) Comment out the oracle.net.wallet_location property above
	# (3) Set the correct password for both trustStorePassword and keyStorePassword.
	# It's the password you specified when downloading the wallet from OCI Console or the Service Console.
	#javax.net.ssl.trustStore=${TNS_ADMIN}/truststore.jks
	#javax.net.ssl.trustStorePassword=<password_from_console>
	#javax.net.ssl.keyStore=${TNS_ADMIN}/keystore.jks
	#javax.net.ssl.keyStorePassword=<password_from_console>
	oracle.net.ssl_server_dn_match=true
	javax.net.ssl.trustStore=${TNS_ADMIN}/truststore.jks
	javax.net.ssl.trustStorePassword=パスワード
	javax.net.ssl.keyStore=${TNS_ADMIN}/keystore.jks
	javax.net.ssl.keyStorePassword=パスワード
```

# ■ JDBC Thin接続: DataSourceSample.java
JDBC Thin接続テスト用のDataSourceSample.javaを「JDBCコード・サンプル」からダウンロードしテストしてみます。
・GitHub: [JDBCコード・サンプル](https://github.com/oracle/oracle-db-examples/tree/master/java/jdbc/ConnectionSamples)


## ● DataSourceSample.java設定
ダウンロードした DataSourceSample.javaの下記３行を環境に合わせた、TNS接続名とhrスキーマパスワードを設定

	final static String DB_URL="jdbc:oracle:thin:@atp_high";
	final static String DB_USER = "hr";
	final static String DB_PASSWORD = "Password";


・DataSourceSample.javaサンプル

```shell
[opc@oci-inst01 work]$ cat DataSourceSample.java

/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.*/
/*
   DESCRIPTION    
   The code sample shows how to use the DataSource API to establish a connection
   to the Database. You can specify properties with "setConnectionProperties".
   This is the recommended way to create connections to the Database.
   Note that an instance of oracle.jdbc.pool.OracleDataSource doesn't provide
   any connection pooling. It's just a connection factory. A connection pool,
   such as Universal Connection Pool (UCP), can be configured to use an
   instance of oracle.jdbc.pool.OracleDataSource to create connections and 
   then cache them.
    
    Step 1: Enter the Database details in this file. 
            DB_USER, DB_PASSWORD and DB_URL are required
    Step 2: Run the sample with "ant DataSourceSample"
  
   NOTES
    Use JDK 1.7 and above
   MODIFIED    (MM/DD/YY)
    nbsundar    02/17/15 - Creation 
 */

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import oracle.jdbc.pool.OracleDataSource;
import oracle.jdbc.OracleConnection;
import java.sql.DatabaseMetaData;

public class DataSourceSample {  
  // The recommended format of a connection URL is the long format with the
  // connection descriptor.
// final static String DB_URL= "jdbc:oracle:thin:@myhost:1521/myorcldbservicename";
final static String DB_URL="jdbc:oracle:thin:@atp_high";


  // For ATP and ADW - use the TNS Alias name along with the TNS_ADMIN when using 18.3 JDBC driver
  // final static String DB_URL="jdbc:oracle:thin:@wallet_dbname?TNS_ADMIN=/Users/test/wallet_dbname";
  // In case of windows, use the following URL 
  // final static String DB_URL="jdbc:oracle:thin:@wallet_dbname?TNS_ADMIN=C:\\Users\\test\\wallet_dbname";
  final static String DB_USER = "hr";
  final static String DB_PASSWORD = "Password";

 /*
  * The method gets a database connection using 
  * oracle.jdbc.pool.OracleDataSource. It also sets some connection 
  * level properties, such as,
  * OracleConnection.CONNECTION_PROPERTY_DEFAULT_ROW_PREFETCH,
  * OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES, etc.,
  * There are many other connection related properties. Refer to 
  * the OracleConnection interface to find more. 
  */
  public static void main(String args[]) throws SQLException {
    Properties info = new Properties();     
    info.put(OracleConnection.CONNECTION_PROPERTY_USER_NAME, DB_USER);
    info.put(OracleConnection.CONNECTION_PROPERTY_PASSWORD, DB_PASSWORD);          
    info.put(OracleConnection.CONNECTION_PROPERTY_DEFAULT_ROW_PREFETCH, "20");    
  

    OracleDataSource ods = new OracleDataSource();
    ods.setURL(DB_URL);    
    ods.setConnectionProperties(info);

    // With AutoCloseable, the connection is closed automatically.
    try (OracleConnection connection = (OracleConnection) ods.getConnection()) {
      // Get the JDBC driver name and version 
      DatabaseMetaData dbmd = connection.getMetaData();       
      System.out.println("Driver Name: " + dbmd.getDriverName());
      System.out.println("Driver Version: " + dbmd.getDriverVersion());
      // Print some connection properties
      System.out.println("Default Row Prefetch Value is: " + 
         connection.getDefaultRowPrefetch());
      System.out.println("Database Username is: " + connection.getUserName());
      System.out.println();
      // Perform a database operation 
      printEmployees(connection);
    }   
  }
 /*
  * Displays first_name and last_name from the employees table.
  */
  public static void printEmployees(Connection connection) throws SQLException {
    // Statement and ResultSet are AutoCloseable and closed automatically. 
    try (Statement statement = connection.createStatement()) {      
      try (ResultSet resultSet = statement
          .executeQuery("select first_name, last_name from employees")) {
        System.out.println("FIRST_NAME" + "  " + "LAST_NAME");
        System.out.println("---------------------");
        while (resultSet.next())
          System.out.println(resultSet.getString(1) + " "
              + resultSet.getString(2) + " ");       
      }
    }   
  } 
}
```



## ● DataSourceSample.java コンパイル
**1) javac実行**
DataSourceSample.javaをclassファイルにコンパイル

**・ 実行コマンド**

```shell
javac -classpath \
/home/opc/oracle/ojdbc8-full/ojdbc8.jar:\
/home/opc/oracle/ojdbc8-full/ucp.jar:\
/home/opc/oracle/ojdbc8-full/oraclepki.jar:\
/home/opc/oracle/ojdbc8-full/osdt_core.jar:\
/home/opc/oracle/ojdbc8-full/osdt_cert.jar:. \
-Doracle.net.tns_admin=/home/opc/oracle/instantclient_12_2/network/admin \
DataSourceSample.java
```

**・ 実行結果**
javacコマンドでコンパイルしてclassファイル作成確認

```shell
[opc@oci-inst01 work]$ javac -classpath \
> /home/opc/oracle/ojdbc8-full/ojdbc8.jar:\
> /home/opc/oracle/ojdbc8-full/ucp.jar:\
> /home/opc/oracle/ojdbc8-full/oraclepki.jar:\
> /home/opc/oracle/ojdbc8-full/osdt_core.jar:\
> /home/opc/oracle/ojdbc8-full/osdt_cert.jar:. \
> -Doracle.net.tns_admin=/home/opc/oracle/instantclient_12_2/network/admin \
> DataSourceSample.java

[opc@oci-inst01 work]$ ls -l
	-rw-rw-r--. 1 opc opc 3222  1月 19 05:33 DataSourceSample.class
	-rw-rw-r--. 1 opc opc 4297  1月 19 05:33 DataSourceSample.java
```


## ● DataSourceSample実行

**・ 実行コマンド**

```shell
java -classpath \
/home/opc/oracle/ojdbc8-full/ojdbc8.jar:\
/home/opc/oracle/ojdbc8-full/ucp.jar:\
/home/opc/oracle/ojdbc8-full/oraclepki.jar:\
/home/opc/oracle/ojdbc8-full/osdt_core.jar:\
/home/opc/oracle/ojdbc8-full/osdt_cert.jar:. \
-Doracle.net.tns_admin=/home/opc/oracle/instantclient_12_2/network/admin \
DataSourceSample
```


**・ 実行結果**

```shell
[opc@oci-inst01 work]$ java -classpath \
> /home/opc/oracle/ojdbc8-full/ojdbc8.jar:\
> /home/opc/oracle/ojdbc8-full/ucp.jar:\
> /home/opc/oracle/ojdbc8-full/oraclepki.jar:\
> /home/opc/oracle/ojdbc8-full/osdt_core.jar:\
> /home/opc/oracle/ojdbc8-full/osdt_cert.jar:. \
> -Doracle.net.tns_admin=/home/opc/oracle/instantclient_12_2/network/admin \
> DataSourceSample

    Driver Name: Oracle JDBC driver
    Driver Version: 21.1.0.0.0
    Default Row Prefetch Value is: 20
    Database Username is: HR

	FIRST_NAME  LAST_NAME
	---------------------
	Ellen Abel
	Sundar Ande
	Mozhe Atkinson
	・・・
```


## ● OS環境変数設定による実行
javac, java実行時の -classpath は以下のように OS環境変数\$CLASSPATH設定でも可能
-Doracle.net.tns_admin は OS環境変数\$TNS_ADMIN設定でも可能
**1) CLASSPATH OS環境変数設定**

```shell
[opc@oci-inst01 work]$ export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar:/home/opc/oracle/ojdbc8-full/ojdbc8.jar:/home/opc/oracle/ojdbc8-full/ucp.jar:/home/opc/oracle/ojdbc8-full/oraclepki.jar:/home/opc/oracle/ojdbc8-full/osdt_core.jar:/home/opc/oracle/ojdbc8-full/osdt_cert.jar:. 
[opc@oci-inst01 work]$ export ORACLE_HOME=/home/opc/oracle/instantclient_12_2
[opc@oci-inst01 work]$ export TNS_ADMIN=$ORACLE_HOME/network/admin
```

**2) コンパイル**
javacコマンドでコンパイルしてclassファイル作成確認

```shell
[opc@oci-inst01 work]$ javac DataSourceSample.java
[opc@oci-inst01 work]$ ls -l
	-rw-rw-r--. 1 opc opc 3222  1月 19 10:55 DataSourceSample.class
	-rw-rw-r--. 1 opc opc 4297  1月 19 05:33 DataSourceSample.java
```

**3) 実行**

```shell
[opc@oci-inst01 work]$ java DataSourceSample
    Driver Name: Oracle JDBC driver
    Driver Version: 21.1.0.0.0
    Default Row Prefetch Value is: 20
    Database Username is: HR

	FIRST_NAME  LAST_NAME
	---------------------
	Ellen Abel
	Sundar Ande
	Mozhe Atkinson
	・・・
	Eleni Zlotkey
```



# ■ JDBC Thin接続テスト: UCPSample.java
JDBC Thin接続テスト用のUCPSample.javaを「JDBCコード・サンプル」からダウンロードしテストしてみます。
・GitHub: [JDBCコード・サンプル](https://github.com/oracle/oracle-db-examples/tree/master/java/jdbc/ConnectionSamples)



## ● UCPSample.java 設定
ダウンロードした UCPSample.javaの下記３行を環境に合わせた、TNS接続名とhrスキーマパスワードを設定

	final static String DB_URL="jdbc:oracle:thin:@atp_high";
	final static String DB_USER = "hr";
	final static String DB_PASSWORD = "Password";

・DataSourceSample.javaサンプル

```shell
[opc@oci-inst01 work]$ vi UCPSample.java
[opc@oci-inst01 work]$ cat UCPSample.java
/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.*/

/*
 DESCRIPTION
 The code sample demonstrates Universal Connection Pool (UCP) as a client
 side connection pool and does the following.
 (a)Set the connection factory class name to
 oracle.jdbc.pool.OracleDataSource before getting a connection.
 (b)Set the driver connection properties(e.g.,defaultNChar,includeSynonyms).
 (c)Set the connection pool properties(e.g.,minPoolSize, maxPoolSize).
 (d)Get the connection and perform some database operations.
 Step 1: Enter the Database details in DBConfig.properties file.
 USER, PASSWORD, UCP_CONNFACTORY and URL are required.
 Step 2: Run the sample with "ant UCPSample"
 NOTES
 Use JDK 1.7 and above
 MODIFIED    (MM/DD/YY)
 nbsundar    02/13/15 - Creation (Contributor - tzhou)
 */
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import oracle.ucp.jdbc.PoolDataSourceFactory;
import oracle.ucp.jdbc.PoolDataSource;

public class UCPSample {
  // final static String DB_URL="jdbc:oracle:thin:@myhost:1521/orclservicename";
  // Use the TNS Alias name along with the TNS_ADMIN - For ATP and ADW
  // final static String DB_URL="jdbc:oracle:thin:@dbname_alias?TNS_ADMIN=/Users/test/wallet_dbname";
  final static String DB_URL="jdbc:oracle:thin:@atp_high";
  final static String DB_USER = "hr";
  final static String DB_PASSWORD = "Password";
  final static String CONN_FACTORY_CLASS_NAME="oracle.jdbc.pool.OracleDataSource";

  /*
   * The sample demonstrates UCP as client side connection pool.
   */
  public static void main(String args[]) throws Exception {
    // Get the PoolDataSource for UCP
    PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();

    // Set the connection factory first before all other properties
    pds.setConnectionFactoryClassName(CONN_FACTORY_CLASS_NAME);
    pds.setURL(DB_URL);
    pds.setUser(DB_USER);
    pds.setPassword(DB_PASSWORD);
    pds.setConnectionPoolName("JDBC_UCP_POOL");

    // Default is 0. Set the initial number of connections to be created
    // when UCP is started.
    pds.setInitialPoolSize(5);

    // Default is 0. Set the minimum number of connections
    // that is maintained by UCP at runtime.
    pds.setMinPoolSize(5);

    // Default is Integer.MAX_VALUE (2147483647). Set the maximum number of
    // connections allowed on the connection pool.
    pds.setMaxPoolSize(20);

    // Default is 30secs. Set the frequency in seconds to enforce the timeout
    // properties. Applies to inactiveConnectionTimeout(int secs),
    // AbandonedConnectionTimeout(secs)& TimeToLiveConnectionTimeout(int secs).
    // Range of valid values is 0 to Integer.MAX_VALUE. .
    pds.setTimeoutCheckInterval(5);

    // Default is 0. Set the maximum time, in seconds, that a
    // connection remains available in the connection pool.
    pds.setInactiveConnectionTimeout(10);

    // Get the database connection from UCP.
    try (Connection conn = pds.getConnection()) {
      System.out.println("Available connections after checkout: "
          + pds.getAvailableConnectionsCount());
      System.out.println("Borrowed connections after checkout: "
          + pds.getBorrowedConnectionsCount());
      // Perform a database operation
      doSQLWork(conn);
    }
    catch (SQLException e) {
      System.out.println("UCPSample - " + "SQLException occurred : "
          + e.getMessage());
    }
    System.out.println("Available connections after checkin: "
        + pds.getAvailableConnectionsCount());
    System.out.println("Borrowed connections after checkin: "
        + pds.getBorrowedConnectionsCount());
  }

  /*
   * Creates an EMP table and does an insert, update and select operations on
   * the new table created.
   */
  public static void doSQLWork(Connection conn) {
    try {
      conn.setAutoCommit(false);
      // Prepare a statement to execute the SQL Queries.
      Statement statement = conn.createStatement();
      // Create table EMP
      statement.executeUpdate("create table EMP(EMPLOYEEID NUMBER,"
          + "EMPLOYEENAME VARCHAR2 (20))");
      System.out.println("New table EMP is created");
      // Insert some records into the table EMP
      statement.executeUpdate("insert into EMP values(1, 'Jennifer Jones')");
      statement.executeUpdate("insert into EMP values(2, 'Alex Debouir')");
      System.out.println("Two records are inserted.");

      // Update a record on EMP table.
      statement.executeUpdate("update EMP set EMPLOYEENAME='Alex Deborie'"
          + " where EMPLOYEEID=2");
      System.out.println("One record is updated.");

      // Verify the table EMP
      ResultSet resultSet = statement.executeQuery("select * from EMP");
      System.out.println("\nNew table EMP contains:");
      System.out.println("EMPLOYEEID" + " " + "EMPLOYEENAME");
      System.out.println("--------------------------");
      while (resultSet.next()) {
        System.out.println(resultSet.getInt(1) + " " + resultSet.getString(2));
      }
      System.out.println("\nSuccessfully tested a connection from UCP");
    }
    catch (SQLException e) {
      System.out.println("UCPSample - "
          + "doSQLWork()- SQLException occurred : " + e.getMessage());
    }
    finally {
      // Clean-up after everything
      try (Statement statement = conn.createStatement()) {
        statement.execute("drop table EMP");
      }
      catch (SQLException e) {
        System.out.println("UCPSample - "
            + "doSQLWork()- SQLException occurred : " + e.getMessage());
      }
    }
  }
}
```


**1) CLASSPATH OS環境変数設定**

```shell
[opc@oci-inst01 work]$ export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar:/home/opc/oracle/ojdbc8-full/ojdbc8.jar:/home/opc/oracle/ojdbc8-full/ucp.jar:/home/opc/oracle/ojdbc8-full/oraclepki.jar:/home/opc/oracle/ojdbc8-full/osdt_core.jar:/home/opc/oracle/ojdbc8-full/osdt_cert.jar:. 
[opc@oci-inst01 work]$ export ORACLE_HOME=/home/opc/oracle/instantclient_12_2
[opc@oci-inst01 work]$ export TNS_ADMIN=$ORACLE_HOME/network/admin
```

**2) コンパイル**
javacコマンドでコンパイルしてclassファイル作成確認

```shell
[opc@oci-inst01 work]$ javac UCPSample.java
[opc@oci-inst01 work]$ ls -l
	-rw-rw-r--. 1 opc opc 4866  1月 19 15:46 UCPSample.class
	-rw-rw-r--. 1 opc opc 5675  1月 19 15:46 UCPSample.java
```

**3) 実行**

```shell
[opc@oci-inst01 work]$ java UCPSample
	Available connections after checkout: 4
	Borrowed connections after checkout: 1
	New table EMP is created
	Two records are inserted.
	One record is updated.

	New table EMP contains:
	EMPLOYEEID EMPLOYEENAME
	--------------------------
	1 Jennifer Jones
	2 Alex Deborie

	Successfully tested a connection from UCP
	Available connections after checkin: 5
	Borrowed connections after checkin: 0
```





# ■ 参考
## ● Download
・[JDBC and UCP Downloads page](https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html)
・[JCE Unlimited Strength Jurisdiction Policy Files](https://www.oracle.com/java/technologies/javase-jce8-downloads.html)
・[JDBCコード・サンプル](https://github.com/oracle/oracle-db-examples/tree/master/java/jdbc/ConnectionSamples)

## ● Oracleマニュアル
・[JDBC Thin接続とウォレット](https://docs.oracle.com/cd/E83857_01/paas/atp-cloud/atpug/connect-jdbc-thin-wallet.html#GUID-EBBB5D6B-118D-48BD-8D68-A3954EC92D2B)
・[Java Connectivity with Autonomous Database (ATP or ADW) using 19c and 18.3 JDBC](https://www.oracle.com/database/technologies/java-connectivity-to-atp.html)