Talend - tAccessConnectionコンポーネント

TalendのtAccessConnectionコンポーネントの挙動が6系から変わっており
エラーが起きることがあるので記載しておきます。

# 対象読者 or 前提条件 or 環境
- Talendユーザ
- Talend Data Services Platform 6.3.1 (*)

(*) 一部 Talend Open Source for Big Data 6.5.1でも確認済み

# tAccessConnectionでOutOfMemoryErrorが発生する

## 事象
Talend v6系のtAccessConnectionを利用すると、OutOfMemoryErrorが発生することがあります。

```bash:エラー内容
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
	at org.hsqldb.result.Result.newBatchedExecuteResponse(Unknown Source)
	at org.hsqldb.Session.executeCompiledBatchStatement(Unknown Source)
	at org.hsqldb.Session.execute(Unknown Source)
	at org.hsqldb.jdbc.JDBCPreparedStatement.executeBatch(Unknown Source)
	at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:906)
	at net.ucanaccess.converters.LoadJet$TablesLoader.loadTablesData(LoadJet.java:1064)
	at net.ucanaccess.converters.LoadJet$TablesLoader.loadTables(LoadJet.java:1108)
	at net.ucanaccess.converters.LoadJet$TablesLoader.access$5(LoadJet.java:1102)
	at net.ucanaccess.converters.LoadJet.loadDB(LoadJet.java:1632)
	at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:249)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:208)
	at hello_project.rb_access_0_1.RB_Access.tAccessConnection_1Process(RB_Access.java:416)
	at hello_project.rb_access_0_1.RB_Access.tJava_1Process(RB_Access.java:1167)
	at hello_project.rb_access_0_1.RB_Access.runJobInTOS(RB_Access.java:1388)
	at hello_project.rb_access_0_1.RB_Access.main(RB_Access.java:1245)
```

## 原因
v6からAccessへの接続に内部でUCanAccessを利用していますが、このJDBCは接続時にミラーDB(DBのコピー)をHSQLDBとして作成しています。

このミラーDBを作成する際にデフォルト設定ではメモリ上に作成する為、JVMのメモリ割り当てが足りないとOutOfMemoryErrorで落ちてしまいます。

## 解決策
ある程度大きいサイズのアクセスファイルを扱う場合には、追加JDBCパラメータでメモリではなくディスクを使うように指定します。

```java:追加JDBCパラメータ
"memory=false"
```

また、ETLジョブで使う場合には以下の2つのオプションも指定すると良いと思います。
・immediatelyReleaseResources（接続が切れたら全てのリソースを解放する）
・preventReloading（データのリロードを無視する）

![tAccessConnection.png](https://qiita-image-store.s3.amazonaws.com/0/138821/d6b88695-9d2d-e122-d4d4-b74f8bf74c25.png)

## 参考
Getting Started > Connection Properties
http://ucanaccess.sourceforge.net/site.html

# tAccessConnectionでorg.hsqldb.HsqlException: unknown tokenが発生する

## 事象
mdbのテーブル名に機種依存文字を含むテーブル名（例：テーブルⅡ）が存在していると、tAccessConnectionで接続する際にエラーが発生します。
エラー内容は以下の通りです。

```bash:エラー内容
Exception in component tAccessConnection_1
net.ucanaccess.jdbc.UcanaccessSQLException: unknown token: 
	at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:247)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:247)
	at hello_project.helloaccess_0_1.HelloAccess.tAccessConnection_1Process(HelloAccess.java:352)
	at hello_project.helloaccess_0_1.HelloAccess.runJobInTOS(HelloAccess.java:1081)
	at hello_project.helloaccess_0_1.HelloAccess.main(HelloAccess.java:938)
Caused by: java.sql.SQLSyntaxErrorException: unknown token: 
	at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
	at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
	at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
	at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
	at net.ucanaccess.converters.LoadJet.exec(LoadJet.java:1308)
	at net.ucanaccess.converters.LoadJet.access$0(LoadJet.java:1303)
	at net.ucanaccess.converters.LoadJet$TablesLoader.createSyncrTable(LoadJet.java:421)
	at net.ucanaccess.converters.LoadJet$TablesLoader.createSyncrTable(LoadJet.java:379)
	at net.ucanaccess.converters.LoadJet$TablesLoader.createTable(LoadJet.java:742)
	at net.ucanaccess.converters.LoadJet$TablesLoader.createTable(LoadJet.java:698)
	at net.ucanaccess.converters.LoadJet$TablesLoader.createTables(LoadJet.java:873)
	at net.ucanaccess.converters.LoadJet$TablesLoader.loadTables(LoadJet.java:967)
	at net.ucanaccess.converters.LoadJet$TablesLoader.access$3(LoadJet.java:966)
	at net.ucanaccess.converters.LoadJet.loadDB(LoadJet.java:1361)
	at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:236)
	... 5 more
Caused by: org.hsqldb.HsqlException: unknown token: 
	at org.hsqldb.error.Error.error(Unknown Source)
	at org.hsqldb.error.Error.error(Unknown Source)
	at org.hsqldb.ParserBase.read(Unknown Source)
	at org.hsqldb.ParserDQL.readNewSchemaObjectName(Unknown Source)
	at org.hsqldb.ParserDDL.compileCreateTable(Unknown Source)
	at org.hsqldb.ParserDDL.compileCreate(Unknown Source)
	at org.hsqldb.ParserCommand.compilePart(Unknown Source)
	at org.hsqldb.ParserCommand.compileStatements(Unknown Source)
	at org.hsqldb.Session.executeDirectStatement(Unknown Source)
	at org.hsqldb.Session.execute(Unknown Source)
	... 18 more
```

## 原因
原因はv6からAccessへの接続に内部で利用しているJDBCがUCanAccessへ変更されており、そのバージョン(v2.0.9.5)が古いことにあります。
Talend 6系で利用されているこのJDBCにはバグがあり、上記の通り接続エラーが発生します。

## 解決策
以下のようにUCanAccessのjarを差し替えることで、対応可能です。
[公式サイト](http://ucanaccess.sourceforge.net/site.html)の「Change Log」にも、この問題にv3.0.0から対応した旨が記載されています。

## 対応手順
以下の手順のバージョンは、Talendバージョンに合わせて適宜あわせてください。
また、UCanAccessのバージョンは2018/04/06時点で「4.0.3」が最新になっています。

### 1. tAccessConnectionフォルダのバックアップをする

下記フォルダを、「tAccessConnection.ori」フォルダとしてコピーします。

```bat:tAccessComponentフォルダ
[TalendStudioインストールフォルダ]\studio\plugins\org.talend.designer.components.localprovider_6.3.1.20161216_1026\components\tAccessConnection
```

### 2. 公式サイトから最新版のjarを取得

公式サイトの「Download UCanAccess 4.0.3」から「UCanAccess-4.0.3-bin.zip」をダウンロードして解凍します。
http://ucanaccess.sourceforge.net/site.html

### 3. ucanaccess-4.0.3.jarを配備

下記フォルダに「ucanaccess-4.0.1.jar」を配備します。

```bat:tAccessComponentフォルダ
[TalendStudioインストールフォルダ]\studio\plugins\org.talend.designer.components.localprovider_6.3.1.20161216_1026\components\tAccessConnection
```

### 4. 「tAccessConnection_java.xml」ファイルを修正
tAccessComponentフォルダにある「tAccessConnection_java.xml」ファイルを以下のように修正します。

```bat:tAccessComponentフォルダ
[TalendStudioインストールフォルダ]\studio\plugins\org.talend.designer.components.localprovider_6.3.1.20161216_1026\components\tAccessConnection
```

```diff:tAccessConnection_java.xml
-		<IMPORT NAME="Driver-ucanaccess" MODULE="ucanaccess-2.0.9.5.jar" MVN="mvn:org.talend.libraries/ucanaccess-2.0.9.5/6.0.0"  REQUIRED="true"/>
+		<!--<IMPORT NAME="Driver-ucanaccess" MODULE="ucanaccess-2.0.9.5.jar" MVN="mvn:org.talend.libraries/ucanaccess-2.0.9.5/6.0.0"  REQUIRED="true"/>-->
+		<IMPORT NAME="Driver-ucanaccess" MODULE="ucanaccess-4.0.3.jar" REQUIRED="true"/>
```