Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 12.0.1 » SQL Anywhere サーバー プログラミング » SQL Anywhere 外部環境のサポート

 

Java 外部環境

SQL Anywhere では、Java ストアドプロシージャーおよび関数をサポートしています。Java ストアドプロシージャーまたはファンクションの動作は、SQL ストアドプロシージャーまたはファンクションと同じです。ただし、プロシージャーまたはファンクションのコードは Java で記述され、その実行はデータベースサーバーの外側 (つまり Java VM 環境内) で行われます。接続ごとに 1 つのインスタンスではなく、各データベースの Java VM に 1 つのインスタンスがあります。Java ストアドプロシージャーは結果セットを返すことができます。

データベースでの Java のサポートを使用するためには、いくつかの前提条件があります。

  1. Java Runtime Environment のコピーをデータベースサーバーコンピューターにインストールする必要があります。

  2. SQL Anywhere データベースサーバーが Java 実行ファイル (Java VM) を検出できる必要があります。

Java をデータベースで使用するには、データベースサーバーが Java 実行ファイルを検出して開始できることを確認してください。これは、次の文を実行して確認できます。

START EXTERNAL ENVIRONMENT JAVA;

データベースサーバーが Java を開始できない場合は、データベースサーバーが Java 実行ファイルを検出できないことが問題の原因であると考えられます。この場合は、ALTER EXTERNAL ENVIRONMENT 文を実行して、Java 実行ファイルのロケーションを明示的に設定してください。実行ファイル名を必ず含めてください。

ALTER EXTERNAL ENVIRONMENT JAVA
  LOCATION 'java-path';

次に例を示します。

ALTER EXTERNAL ENVIRONMENT JAVA
  LOCATION 'c:\\jdk1.6.0\\jre\\bin\\java.exe';

次の SQL クエリを実行して、データベースサーバーが使用する Java VM のロケーションを問い合わせることができます。

SELECT db_property('JAVAVM');

START EXTERNAL ENVIRONMENT JAVA 文は、データベースサーバーが Java VM を開始できるかどうかを確認する以外で使用することはありません。通常、Java ストアドプロシージャーまたはファンクションを呼び出すと、Java VM は自動的に開始されます。

これと同様に、Java のインスタンスを停止するために STOP EXTERNAL ENVIRONMENT JAVA 文を使用する必要もありません。インスタンスは、データベースへの接続がすべて切断されると自動的に停止します。ただし、Java をこれ以上使用することがなく、一部のリソースを解放する必要がある場合は、STOP EXTERNAL ENVIRONMENT JAVA 文によって Java VM の使用カウントを減分できます。

データベースサーバーが Java VM 実行ファイルを開始できることを確認したら、次に必要な Java クラスコードをデータベースにインストールします。これは、INSTALL JAVA 文を使用して行います。たとえば、次の文を実行して Java クラスをファイルからデータベースにインストールできます。

INSTALL JAVA 
NEW 
FROM FILE 'java-class-file';

データベースには、Java JAR ファイルもインストールできます。

INSTALL JAVA 
NEW
JAR 'jar-name'
FROM FILE 'jar-file';

Java クラスは、次のようにして変数からインストールできます。

CREATE VARIABLE JavaClass LONG VARCHAR;
SET JavaClass = xp_read_file('java-class-file')
INSTALL JAVA 
NEW
FROM JavaClass;

Java JAR ファイルは、次のようにして変数からインストールできます。

CREATE VARIABLE JavaJar LONG VARCHAR;
SET JavaJar = xp_read_file('jar-file')
INSTALL JAVA 
NEW
JAR 'jar-name'
FROM JavaJar;

Java クラスをデータベースから削除するには、次のように REMOVE JAVA 文を使用します。

REMOVE JAVA CLASS java-class

Java JAR をデータベースから削除するには、次のように REMOVE JAVA 文を使用します。

REMOVE JAVA JAR 'jar-name'

既存の Java クラスを変更するには、次のように INSTALL JAVA 文の UPDATE 句を使用します。

INSTALL JAVA 
UPDATE
FROM FILE 'java-class-file'

データベース内の既存の Java JAR ファイルを更新することもできます。

INSTALL JAVA 
UPDATE
JAR 'jar-name'
FROM FILE 'jar-file';

Java クラスは、次のようにして変数から更新できます。

CREATE VARIABLE JavaClass LONG VARCHAR;
SET JavaClass = xp_read_file('java-class-file')
INSTALL JAVA 
UPDATE
FROM JavaClass;

Java JAR ファイルは、次のようにして変数から更新できます。

CREATE VARIABLE JavaJar LONG VARCHAR;
SET JavaJar = xp_read_file('jar-file')
INSTALL JAVA 
UPDATE
FROM JavaJar;

Java クラスをデータベースにインストールしたら、次に Java メソッドへのインターフェイスとなるストアドプロシージャーおよび関数を作成できます。EXTERNAL NAME 文字列には、Java メソッドを呼び出し、OUT パラメーターおよび戻り値を返すために必要な情報が含まれています。EXTERNAL NAME 句の LANGUAGE 属性には JAVA を指定する必要があります。EXTERNAL NAME 句のフォーマットは次のとおりです。

EXTERNAL NAME 'java-call' LANGUAGE JAVA
java-call :
[package-name.]class-name.method-name method-signature
method-signature : 
( [ field-descriptor, ... ] ) return-descriptor
field-descriptorreturn-descriptor :
Z 
| B 
| S 
| I 
| J 
| F 
| D 
| C 
| V 
| [descriptor 
| Lclass-name;

Java メソッドシグネチャーは、パラメーターの型と戻り値の型を簡潔に文字で表現したものです。パラメーターの数がメソッドシグネチャーに指定された数字よりも小さい場合は、この差が DYNAMIC RESULT SETS に指定された数と等しくなるようにします。また、プロシージャーパラメーターリストよりも多いメソッドシグネチャー内の各パラメーターには、メソッドシグネチャー [Ljava/sql/ResultSet; が必要です。

field-descriptorreturn-descriptor の意味は次のとおりです。

フィールドタイプ Java データ型
B byte
C char
D double
F float
I int
J long
L class-name; クラス class-name のインスタンス。クラス名は、完全に修飾された名前で、ドットを / に置き換えたものとします。例:java/lang/String
S short
V void
Z Boolean
[ 配列の各次元ごとに 1 つ使用

例:

double some_method(
  boolean a,
  int b,
  java.math.BigDecimal c,
  byte [][] d,
  java.sql.ResultSet[] rs ) {
}

この例では、次のシグネチャーを得られます。

'(ZILjava/math/BigDecimal;[[B[Ljava/sql/ResultSet;)D'

次のプロシージャーは、Java メソッドへのインターフェイスを作成するものです。この Java メソッドはいかなる値も返しません (V)。

CREATE PROCEDURE insertfix() 
EXTERNAL NAME 'JDBCExample.InsertFixed()V' 
LANGUAGE JAVA;

次のプロシージャーは、String ([Ljava/lang/String;) 入力引数を持つ Java メソッドへのインターフェイスを作成するものです。この Java メソッドはいかなる値も返しません (V)。

CREATE PROCEDURE InvoiceMain( IN arg1 CHAR(50) )
EXTERNAL NAME 'Invoice.main([Ljava/lang/String;)V'
LANGUAGE JAVA;

次のプロシージャーは、Java メソッド Invoice.init へのインターフェイスを作成するものです。この Java メソッドは、文字列引数 (Ljava/lang/String;)、double (D)、別の文字列引数 (Ljava/lang/String;)、別の double (D) を受け取り、値を返しません (V)。

CREATE PROCEDURE init( IN arg1 CHAR(50),
                       IN arg2 DOUBLE, 
                       IN arg3 CHAR(50), 
                       IN arg4 DOUBLE) 
EXTERNAL NAME 'Invoice.init(Ljava/lang/String;DLjava/lang/String;D)V'
LANGUAGE JAVA

次に示す Java の例は、文字列を受け取り、それをデータベースサーバーメッセージウィンドウに書き込む関数 main を含んでいます。また、Java 文字列を返す関数 whoAreYou も含んでいます。



import java.io.*;

public class Hello
{
    public static void main( String[] args )
    {
        System.out.print( "Hello" );
               for ( int i = 0; i  < args.length; i++ )
                   System.out.print( " " + args[i] );
        System.out.println();
    }
    public static String whoAreYou()
    {
        return( "I am SQL Anywhere." );
    }
}

上記の Java コードは、Hello.java ファイルにあり、Java コンパイラーを使用してコンパイルします。生成されるクラスファイルは次のようにデータベースにロードされます。

INSTALL JAVA 
NEW 
FROM FILE 'Hello.class';

Hello クラスの main メソッドへのインターフェイスとなるストアドプロシージャーは、Interactive SQL を使用して次のように作成されます。

CREATE PROCEDURE HelloDemo( IN name LONG VARCHAR ) 
EXTERNAL NAME 'Hello.main([Ljava/lang/String;)V'
LANGUAGE JAVA;

main の引数は java.lang.String の配列として記述されています。Interactive SQL で次の SQL 文を実行することでインターフェイスをテストします。

CALL HelloDemo('SQL Anywhere');

メッセージは、データベースサーバーメッセージウィンドウに表示されます。System.out への出力はすべてサーバーメッセージウィンドウにリダイレクトされます。

Hello クラスの whoAreYou メソッドへのインターフェイスとなる関数は、Interactive SQL を使用して次のように作成されます。

CREATE FUNCTION WhoAreYou()
RETURNS LONG VARCHAR
EXTERNAL NAME 'Hello.whoAreYou(V)Ljava/lang/String;'
LANGUAGE JAVA;

関数 whoAreYou は java.lang.String を返すものとして記述されています。Interactive SQL で次の SQL 文を実行することでインターフェイスをテストします。

SELECT WhoAreYou();

Interactive SQL の [結果] ウィンドウの応答を確認してください。

Java 外部環境が開始されなかった理由をトラブルシューティングする場合、つまり、Java 呼び出しが行われたときにアプリケーションが「メインスレッドが見つからない」というエラーを受け取った場合、DBA は次のことを確認する必要があります。

  • Java VM のビット数がデータベースサーバーと異なる場合、VM と同じビット数のクライアントライブラリがデータベースサーバーコンピューターにインストールされていることを確認します。

  • sajdbc.jar 共有オブジェクトと dbjdbc12/libdbjdbc12 共有オブジェクトのソフトウェアビルドが同じであることを確認します。

  • データベースサーバーコンピューターに複数の sajdbc.jar がある場合は、すべて同じソフトウェアバージョンに同期されていることを確認します。

  • データベースサーバーコンピューターが非常にビジーである場合、タイムアウトが原因でエラーがレポートされる可能性があります。

 参照