ヘッダーをスキップ
Oracle Database Java開発者ガイド
10gリリース2(10.2)
B19189-01
  目次へ
目次
索引へ
索引

前へ
前へ
次へ
次へ
 

3 Oracle DatabaseでのJavaメソッドのコール

この章では、Oracle Database内でJavaメソッドをコールする方法の概要および例を示します。この章の内容は、次のとおりです。

3.1 Javaメソッドの起動

Javaアプリケーションのタイプによって、クライアントがJavaメソッドをコールする方法が決まります。次の各項では、データベースにロードしてクライアントによりアクセス可能なJavaクラスの作成に使用できる各Java Application Programming Interface(API)について説明します。

3.1.1 Javaストアド・プロシージャの利用

Javaストアド・プロシージャは、PL/SQLストアド・プロシージャと同じ方法で実行できます。Oracle Databaseでは、Javaストアド・プロシージャは、トリガーまたはSQLデータ操作言語(DML)コールの結果としてコールされることが一般的なため、通常はデータベース操作の結果として実行されます。

Javaストアド・プロシージャをコールするには、コール仕様を使用して公開する必要があります。次の例は、文字列を戻す簡単なJavaストアド・プロシージャを作成、解決、ロードおよび公開する方法を示しています。

  1. クラスHelloを次のように定義します。

    public class Hello
    {
      public static String world()
      {
        return "Hello world";
      }
    }
    
    

    ファイルをHello.javaファイルとして保存します。

  2. クライアント・システムで、標準Javaコンパイラを使用して、次のようにクラスをコンパイルします。

    javac Hello.java
    
    

    CLASSPATHは、javacコマンドを使用してコマンドラインで指定することをお薦めします。特に、シェル・スクリプトまたはMakeファイルの作成時はこの方法をお薦めします。Javaコンパイラによって、Javaバイナリ・ファイル(この例の場合はHello.class)が生成されます。

    このJavaコードの実行場所を決定する必要があります。クライアント・システムでHello.classを実行すると、Hello.classの実行に必要なすべてのサポートされるコア・クラスがCLASSPATHで検索されます。この結果、次のいずれかで依存クラスが検索されます。

    • 1つ以上のディレクトリ内の個々のファイル。このディレクトリはCLASSPATHで指定されます。

    • .jarまたは.zipファイル内。このファイルを含むディレクトリはCLASSPATHで指定されます。

  3. Helloクラスに使用するリゾルバを決定します。

    この例の場合、Hello.classをサーバーにロードします。このファイルは、サーバーでJavaスキーマ・オブジェクトとしてデータベースに格納されます。world()メソッドをコールすると、OracleのJava仮想マシン(JVM)では、リゾルバを使用して、Stringなどの必要なサポート・クラスを検索します。この場合、Oracle JVMでは、デフォルトのリゾルバを使用します。デフォルトのリゾルバは、最初に現行スキーマ内、次にPUBLICスキーマ内でクラスを検索します。java.langパッケージなど、すべてのコア・クラス・ライブラリはPUBLIC内にあります。別のリゾルバを指定する必要がある場合があります。loadjavaの使用時に解決を強制的に実行すると、実行時以前に問題をトレースできます。

  4. loadjavaを使用して、サーバー上にクラスをロードします。ユーザー名とパスワードを指定する必要があります。loadjavaコマンドを次のように実行します。

    loadjava -user scott/tiger Hello.class
    
    
  5. コール仕様を使用してストアド・プロシージャを公開します。

    Java staticメソッドをSQLコールでコールするには、コール仕様を使用してメソッドを公開する必要があります。コール仕様では、メソッドで使用する引数およびメソッドで戻されるSQL型が定義されます。

    SQL*Plusでは、次のようにデータベースに接続し、Hello.world()に対するトップレベルのコール仕様を定義します。

    SQL> CONNECT scott/tiger
    connected
    SQL> CREATE OR REPLACE FUNCTION helloworld RETURN VARCHAR2 AS
      2  LANGUAGE JAVA NAME 'Hello.world () return java.lang.String';
      3  /
    Function created.
    
    
  6. ストアド・プロシージャを次のようにコールします。

    SQL> VARIABLE myString VARCHAR2(20);
    SQL> CALL helloworld() INTO :myString;
    Call completed.
    SQL> PRINT myString;
    
    MYSTRING
    ---------------------------------------
    Hello world
    
    SQL>
    
    

    call helloworld() into :myString文によって、Oracle Databaseでトップレベルのコールが実行されます。SQLおよびPL/SQLでは、作成言語がJava、PL/SQLまたは他の言語のいずれであるかによってストアド・プロシージャが区別されることはありません。コール仕様は、言語間コールを一貫した方法で結び付ける手段です。コール仕様は、トリガーまたはSQLコールやPL/SQLコールでコールされるエントリ・ポイントのみに必要です。さらに、JDeveloperを使用してコール仕様を自動的に作成することもできます。

3.1.2 JNIサポートの利用

Javaネイティブ・インタフェース(JNI)は、Javaネイティブ・メソッドの作成、およびJVMのネイティブ・アプリケーションへの埋込みを行うための標準プログラミング・インタフェースです。JNIの主要目的は、プラットフォーム固有のネイティブ・ライブラリを使用するJavaアプリケーションのバイナリ互換性を提供することです。

Oracle Databaseでは、JavaアプリケーションにおけるJNIの使用はサポートされていません。JNIを使用する場合、アプリケーションが100パーセントPure Javaではないため、ネイティブ・メソッドをプラットフォーム間で移植する必要があります。ネイティブ・メソッドを使用すると、サーバーのクラッシュ、セキュリティ違反およびデータ破損などの問題が発生する可能性があります。

3.1.3 SQLJおよびJDBCを使用したデータベースの問合せ

SQLJおよびJava Database Connectivity(JDBC)プロトコルを使用して、Javaクライアントからデータベースを問い合せることができます。この2つのプロトコルでは、指定したユーザー名とパスワードでデータベースとのセッションが確立され、データベースに対するSQL問合せが実行されます。次の表に、プロトコルとその説明を示します。

プロトコル 説明
JDBC 比較的複雑または動的なSQL問合せの場合に、このプロトコルを使用します。JDBCでは、セッションの確立、問合せの作成などをユーザーが実行する必要があります。
SQLJ 簡単で静的なSQL問合せの場合に、このプロトコルを使用します。SQLJは、通常、既知の列名を持つ既知の表に対して実行されます。

この項の内容は、次のとおりです。

3.1.3.1 JDBC

JDBCは、Sun社によって開発された業界標準のAPIであり、SQL文をJavaメソッドの引数として埋め込むことができます。JDBCはX/OpenのSQL Call Level Interface(CLI)に基づき、SQL92エントリ・レベル標準に準拠しています。 オラクル社などの各ベンダーは、標準のjava.sqlパッケージのインタフェースを実装することによって、独自のJDBC実装を作成しています。Oracleには、これらの標準インタフェースを実装する次のJDBCドライバが用意されています。

  • JDBC Thinドライバ。クライアント側のアプリケーションまたはアプレットに使用でき、Oracleクライアントのインストールを必要としない100パーセントPure Javaのソリューションです。

  • JDBC Oracle Call Interface(OCI)ドライバ。クライアント側のアプリケーションに使用するドライバで、Oracleクライアントのインストールが必要です。

  • サーバー側JDBCドライバ。Oracle Databaseに埋め込まれています。

JDBCを使用する場合は、次のタスクを順番に実行します。

  1. 目的のSQL操作に使用する文オブジェクトを作成します。

  2. SQL操作にバインドするローカル変数を代入します。

  3. 操作を実行します。

多くのアプリケーションではこの方法で十分ですが、複雑な文の場合は作業が煩雑になります。動的なSQL操作の場合は、実行時まで操作内容がわからないため、JDBCを使用する必要があります。ただし、典型的なアプリケーションでは、このSQL操作はあまり採用されていません。

3.1.3.2 SQLJ

SQLJには、1回の手順で静的なSQL操作をJavaソース・コードに直接埋め込む業界標準の方法が用意されているため、JDBCのような複数の手順は不要です。Oracle SQLJは、米国規格協会(ANSI)規格X3H2-98-320に準拠しています。

SQLJは、標準のSQLJプログラミング構文をサポートするプリコンパイラであるトランスレータとランタイム・コンポーネントで構成されています。SQLJソース・コードを.sqljファイルに作成した後、トランスレータを使用して処理します。トランスレータでは、SQLJソース・コードが標準Javaソース・コードに変換され、SQL操作がSQLJランタイム・コールに変換されます。Oracle DatabaseのSQLJ実装では、トランスレータがJavaコンパイラをコールして、Javaソース・コードをコンパイルします。SQLJアプリケーションを実行すると、SQLJランタイムがJDBCをコールして、データベースと通信します。

SQLJを使用すると、実行時前にSQL文のエラーを捕捉できます。JDBCコードは、Pure Javaであるため、直接コンパイルされます。コンパイラでは、SQLエラーを検出できません。これに対して、トランスレータでは、SQLJコードの変換時に、埋め込まれているSQL文のセマンティクスおよび構文を解析するため、SQLエラーが開発時に捕捉されます。したがって、アプリケーションの実行時にエンド・ユーザーによってエラーが捕捉されることはありません。

3.1.3.3 JDBCとSQLJの比較例

次は、単純な操作を実行するJDBCコードとSQLJコードの例です。

JDBC:

// Assume you already have a JDBC Connection object conn
// Define Java variables
String name;
int id=37115;
float salary=20000;

// Set up JDBC prepared statement.
PreparedStatement pstmt = conn.prepareStatement
("SELECT ename FROM emp WHERE empno=? AND sal>?");
pstmt.setInt(1, id);
pstmt.setFloat(2, salary);

// Execute query; retrieve name and assign it to Java variable.
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
  name=rs.getString(1);
  System.out.println("Name is: " + name);
}

// Close result set and statement objects.
rs.close()
pstmt.close();

JDBC接続connがすでに確立されていると仮定しています。次の手順を実行する必要があります。

  1. Javaの変数nameidおよびsalaryを定義します。

  2. PreparedStatementインスタンスを作成します。

    SQL文内の値を動的に設定する必要がある場合はいつでも、プリコンパイルされたSQL文を使用できます。異なる変数値を設定して、同じプリコンパイルされたSQL文を繰返し使用できます。プリコンパイルされたSQL文中の疑問符(?)は、Java変数用のプレースホルダです。前述の例では、これらの変数には、pstmt.setInt()およびpstmt.setFloat()メソッドを使用して値が割り当てられます。最初の「?」は、int変数idを参照し、値は37115に設定されます。2番目の「?」は、float変数salaryを参照し、値は20000に設定されます。

  3. 問合せを実行し、データをResultSetオブジェクトに戻します。

  4. ResultSetオブジェクトから目的のデータを取り出し、出力します。この例では、ename列です。この例では1行のみですが、通常結果セットには複数行のデータが含まれます。

SQLJ:

String name;
int id=37115;
float salary=20000;
#sql {SELECT ename INTO :name FROM emp WHERE empno=:id AND sal>:salary};
System.out.println("Name is: " + name);

SQLJでは、SQL文を直接Javaコードに埋め込めることに加え、バインド式とも呼ばれる、SQL文で直接使用できるJavaホスト式をサポートしています。最も単純なホスト式は、この例のような単純な変数です。ただし、比較的複雑な式も使用できます。ホスト式の前には、コロン(:)を置きます。この例で使用されているJavaホスト式は、nameidおよびsalaryです。SQLJではホスト式をサポートしているため、単一行のデータのみを戻す場合は、結果セットなどは不要です。


注意:

SQLJ文は宣言も含めすべて、#sqlトークンで始まります。

3.1.3.4 完全なSQLJの例

この項では、単純なSQLJプログラムの完全な例を示します。

import java.sql.*;
import sqlj.runtime.ref.DefaultContext;
import oracle.sqlj.runtime.Oracle;

#sql ITERATOR MyIter (String ename, int empno, float sal);

public class MyExample
{
  public static void main (String args[]) throws SQLException
  {
    Oracle.connect("jdbc:oracle:thin:@oow11:5521:sol2", "scott", "tiger");
    #sql { INSERT INTO emp (ename, empno, sal) VALUES ('SALMAN', 32, 20000) };
    MyIter iter;
    #sql iter={ SELECT ename, empno, sal FROM emp };
    while (iter.next())
    {
      System.out.println(iter.ename()+" "+iter.empno()+" "+iter.sal());
    }
  }
}

この例では、次の手順を実行します。

  1. イテレータを宣言します。

    SQLJでは、イテレータと呼ばれる強い型指定のJDBC結果セットが使用されます。イテレータには、特定のデータ型に使用される特定数の列があります。この例のように、イテレータを使用する前に、イテレータの型を定義する必要があります。

    #sql ITERATOR MyIter (String ename, int empno, float sal);
    
    

    この宣言によって、SQLJではイテレータ・クラス、MyIterが作成されます。MyIter型のイテレータでは、Java Stringにマップされる最初の列の結果、Java intにマップされる2番目の列の結果、およびJava floatにマップされる3番目の列の結果を格納できます。この定義では、3つの列にenameempnoおよびsalという名前が付けられ、データベース内の参照表の列名と照合されます。MyIterは、名前付きイテレータです。

  2. データベースに接続します。

    Oracle.connect("jdbc:oracle:thin:@oow11:5521:sol2","scott", "tiger");
    
    

    SQLJには、Oracleクラスがあり、そのconnect()メソッドを使用して次の重要なタスクが実行されます。

    1. データベースにアクセスするためにSQLJが使用するOracle JDBCドライバ(この場合は、JDBC Thinドライバ)を登録します。

    2. 指定のURLにある指定したスキーマ(この例では、パスワードtigerを持つユーザーscott)のデータベース接続をオープンします。この例の場合、URLは、ホストoow11、ポート5521およびSID so12を指し示します。

    3. この接続をSQLJ文のデフォルト接続として確立します。JDBC文では接続オブジェクトを明示的に指定する必要がありますが、SQLJ文ではデフォルト接続を暗黙的に使用するか、または必要に応じて別の接続を指定できます。

  3. SQL文を処理します。次の操作が実行されます。

    1. emp表に次の行が挿入されます。

      #sql {INSERT INTO emp (ename, empno, sal) VALUES ('SALMAN', 32, 20000)};
      
      
    2. 次のイテレータがインスタンス化および移入されます。

      MyIter iter;
      #sql iter={SELECT ename, empno, sal FROM emp};
      
      
  4. イテレータ内に移入されたデータにアクセスします。

    while (iter.next())
    {
      System.out.println(iter.ename()+" "+iter.empno()+" "+iter.sal());
    }
    
    

    next()メソッドはすべてのイテレータに共通で、JDBC結果セットのnext()メソッドと同じ役割を果たします。残りの行がある場合はtrueを戻し、次の行のデータに移動します。列名と名前が一致するイテレータのアクセッサ・メソッドをコールすることで、各行のデータにアクセスできます。これは、すべての名前付きイテレータ共通の特性です。この例では、メソッドename()empno()およびsal()を使用してデータにアクセスします。

3.1.3.5 SQLJの強い型指定

SQLJでは、結果セットではなく、イテレータのような強い型指定を使用します。これによって、変換時にSQL命令をデータベースに照合してチェックできます。たとえば、SQLJでは、データベースに接続し、問合せ対象のデータベース表と照合して各自のイテレータをチェックできます。トランスレータでは、イテレータとデータベース表の一致が確認されるため、変換時にSQLエラーを捕捉できます。確認されない場合、エラーはアプリケーションの実行時まで捕捉されません。さらに、スキーマを後で変更した場合、トランスレータを再実行することによって、変更内容がアプリケーションに影響を与えるかどうかを確認できます。

3.1.3.6 SQLJプログラムの変換

Oracle JDeveloperなどの統合開発環境(IDE)では、作成時に、SQLJプログラムを変換、コンパイルおよびカスタマイズできます。Oracle JDeveloperは、Microsoft社のWindowsに対応したJavaプログラミング用のビジュアル開発環境です。IDEを使用しない場合は、フロントエンドのSQLJユーティリティsqljを使用します。このユーティリティは次のように実行できます。

%sqlj MyExample.sqlj

SQLJトランスレータでは、SQL操作の構文とセマンティクスがチェックされます。オンライン・チェックを使用して、操作をデータベースに照合してチェックできます。このチェックを実行する場合は、トランスレータ・オプションの設定に、サンプル・データベース・スキーマを指定する必要があります。スキーマのデータは、プログラムで最終的に実行されるスキーマのデータと同一である必要はありません。ただし、表には対応する名前とデータ型を持つ列が含まれている必要があります。次の例のように、ユーザー・オプションを使用してオンライン・チェックを使用可能にし、スキーマのユーザー名、パスワードおよびURLを指定します。

%sqlj -user=scott/tiger@jdbc:oracle:thin:@oow11:5521:sol2 MyExample.sqlj

3.1.3.7 サーバー上でのSQLJプログラムの実行

クライアント上では多くのSQLJアプリケーションが実行されます。ただし、SQLJは、通常サーバー上で実行するSQL集中型のストアド・プロシージャのプログラミングに優れた効果を発揮します。

クライアント側SQLJプログラムとサーバー側SQLJプログラムの作成に違いはほとんどありません。SQLJランタイム・パッケージはサーバー上で自動的に使用できます。ただし、次のことを考慮する必要があります。

  • サーバー上でコードを実行する場合、明示的なデータベース接続はありません。暗黙的な接続が1つあるのみです。通常の接続コードは必要ありません。既存のクライアント側アプリケーションを移植する場合、接続コードは無視されるため、コードを削除する必要はありません。

  • サーバー側JDBC内部ドライバは、自動コミット機能をサポートしていません。トランザクションの手動コミットおよびロールバックには、SQLJ構文を使用します。

  • サーバーでのデフォルトの出力デバイスは、ユーザー・スクリーンではなくトレース・ファイルです。配置されているサーバー・アプリケーションのSystem.outには書き込むことがないため、通常、これは開発時のみの問題です。

サーバーでSQLJプログラムを実行し、クライアント上にコードが作成されている場合は、次の2つのオプションがあります。

  • クライアント上のSQLJソース・コードを変換し、Javaのクラスやリソースなどの個々のコンポーネントをサーバー上にロードします。この場合、最初にクラスやリソースを.jarファイルにまとめてから、サーバー上にロードすると簡単です。

  • 埋め込まれているトランスレータで変換するSQLJソース・コードをサーバー上にロードします。

いずれの場合も、loadjavaユーティリティを使用してサーバーにファイル(複数可)をロードします。

3.1.3.8 サーバー上で実行するためのクライアント・アプリケーションの変換

既存のSQLJクライアント側アプリケーションを変換してサーバー上で実行するには、そのアプリケーションがクライアント上で変換された後、次の手順を実行します。

  1. アプリケーション・コンポーネント用の.jarファイルを作成します。

  2. loadjavaユーティリティを使用して、.jarファイルをサーバーにロードします。

  3. サーバーでアプリケーション用のSQLラッパーを作成します。たとえば、前述のMyExampleアプリケーションをサーバー上で実行するには、次の文を実行します。

    CREATE OR REPLACE PROCEDURE sqlj_myexample AS LANGUAGE JAVA NAME `MyExample.main(java.lang.String[])';
    
    

これで、他のストアド・プロシージャと同様に、sqlj_myexampleを実行できます。

3.1.3.9 PL/SQLとの対話

Oracle JDBCドライバはすべて、Oracle SQLおよびPL/SQLとシームレスに通信します。SQLJとPL/SQLが相互に運用されることに注意してください。PL/SQLストアド・プロシージャを再作成せずに、SQLJを使用して通信を開始できます。Oracle SQLJには、PL/SQLストアド・プロシージャをコールするための構文が含まれています。また、SQLJ文に無名PL/SQLブロックを埋め込むこともできます。

3.2 サーバー・アプリケーションのデバッグ

Oracle Databaseには、jdbデバッガを使用する開発者にとって便利なデバッグ機能が提供されています。 提供されるインタフェースは、Java Debug Wire Protocol(JDWP)です。このインタフェースは、Java Development Kit(JDK)のバージョン1.4以降でサポートされています。

次の新機能がJDWPプロトコルでサポートされています。

Oracle JDeveloperは、ユーザーが使いやすいようにこれらのデバッグ機能と統合されています。その他の独立系IDEベンダーは、Oracle Databaseと独自のデバッガを統合できます。


関連項目:

『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』および『Oracle Databaseアプリケーション開発者ガイド-基礎編』

3.3 サーバー上での実行を識別する方法

サーバーとクライアントで異なる方法で実行するJavaコードを作成する場合があります。通常、このようなJavaコードの作成はお薦めしません。実際には、JDBCおよびSQLJでは、サーバーとクライアントで使用するドライバが異なる場合でも、この問題を回避する移植可能なコードを作成できます。

コードがサーバーで実行されているかどうかを確認する必要がある場合は、次のようにSystem.getProperty()メソッドを使用します。

System.getProperty ("oracle.jserver.version")

getProperty()メソッドから戻される結果は、次のとおりです。

3.4 サーバー上の出力のリダイレクト

System.outおよびSystem.errの出力先は、現行のトレース・ファイルです。出力をSQL*Plusのテキスト・バッファにリダイレクトするには、次のように指定します。

SQL> SET SERVEROUTPUT ON
SQL> CALL dbms_java.set_output(2000);

最小(デフォルト)バッファ・サイズは2,000バイトで、最大サイズは1,000,000バイトです。次の例では、バッファ・サイズを5,000バイトに増やしています。

SQL> SET SERVEROUTPUT ON SIZE 5000
SQL> CALL dbms_java.set_output(5000);

出力は、コール終了時に行われます。

3.5 Javaストアド・プロシージャの直接コールのサポート

Oracle Database 10gでは、Javaストアド・プロシージャおよびファンクションをコールするための新機能が導入されました。Oracle Database 10gより前のリリースでは、データベース・クライアントからJavaストアド・プロシージャおよびファンクションをコールするには、関連するPL/SQLラッパーをJDBCでコールする必要がありました。各ラッパーは、SQLシグネチャおよびJava実装とともに手動で公開する必要がありました。この方法には次のデメリットがあります。

これらの問題を解決するために、static Javaストアド・プロシージャおよびファンクションの直接コール用に、簡易APIが実装されています。この新機能は一般的なアプリケーションにも役立ちますが、特にWebサービスに役立ちます。

簡易APIのクラスはoracle.jpub.reflectパッケージに格納されています。このパッケージをクライアント側のコードにインポートします。

次に、API用のJavaインタフェースを示します。

public class Client
{
  public static String getSignature(Class[]);
  public static Object invoke(Connection, String, String, String, Object[]);
  public static Object invoke(Connection, String, String, Class[], Object[]);
}

例として、サーバーで次のメソッドをコールするとします。

public String oracle.sqlj.checker.JdbcVersion.to_string();

このメソッドは次のようにコールできます。

Connection conn = ...;
String serverSqljVersion = (String)
Client.invoke(conn, "oracle.sqlj.checker.JdbcVersion","to_string", new Class[]{}, new Object[]{});

Class[]配列はメソッドのパラメータ・タイプ用で、Object[]配列はパラメータの値用です。この場合、to_stringにはパラメータがないため、配列は空です。

次の点に注意してください。

3.5.1 ネイティブなJavaインタフェースの使用

Oracle Database 10gには、サーバー側Javaコードをコールする新機能である、ネイティブなJavaインタフェースが導入されています。これは、簡略化されたアプリケーション統合です。つまり、クライアント側および中間層のJavaアプリケーションは、PL/SQLラッパーを定義しないでデータベース内のJavaを直接コールできます。ネイティブなJavaインタフェースでは、サーバー側Javaクラスのリフレクション機能が使用されます。

以前のリリースでは、データベース・クライアントからJavaストアド・プロシージャおよびファンクションをコールするには、関連するPL/SQLラッパーをJava Database Connectivity(JDBC)でコールする必要がありました。各ラッパーは、SQLシグネチャおよびJava実装とともに手動で公開する必要がありました。この方法には次のデメリットがあります。

  • シグネチャで許可されるJava型は、相当する型がSQLにある場合のみでした。

  • Javaで発行された例外が正しく戻されません。

JPublisherの-javaオプションは、これらのデメリットを回避するための機能を提供します。関連付けられたPL/SQLラッパーに対するJDBCコールの不具合を解決するために、-javaオプションでは、static Javaメソッドを直接起動するAPIを使用します。この機能は、Webサービスにも役立ちます。

この-javaオプションの機能は、-sqlオプションの機能と似ています。クライアント側Javaクラスを作成して、サーバー側のSQLオブジェクトやPL/SQLパッケージにアクセスするのではなく、クライアント側Javaスタブ・クラスを作成して、サーバー側Javaクラスにアクセスします。クライアント側のスタブ・クラスでは、サーバー側のクラスをミラー化するJPublisherコードが使用され、次の機能が含まれます。

  • サーバー・クラスのpublic staticメソッドに対応するメソッド。

  • 2つのコンストラクタ。1つはJDBC接続を取得するコンストラクタ、もう1つはJPublisherのデフォルトの接続コンテキスト・インスタンスを取得するコンストラクタです。

このスタブ・クラスは、実行時に、JDBC接続を使用してインスタンス化されます。スタブ・クラスのメソッドのコールは、結果としてサーバー側クラスの対応するメソッドのコールとなります。これらの公開されたメソッドで使用されるすべてのJava型は、プリミティブ型、またはシリアライズ可能型である必要があります。

図3-1に、staticサーバー側Javaメソッドを直接起動するクライアント側スタブAPIの例を示します。JPublisherでは、スタブ生成が透過的に処理されます。

図3-1 ネイティブJavaインタフェース

ネイティブJavaインタフェース
画像の説明

次のように、-javaオプションを使用してサーバー側Javaクラスを公開できます。

-java=className

次のAPIを使用したoracle.sqlj.checker.JdbcVersionサーバー側Javaクラスについて考えます。

public class oracle.sqlj.checker.JdbcVersion
{
 ...
 public java.lang.String toString();
 public static java.lang.String to_string();
 ...
}

例として、サーバーで次のメソッドをコールするとします。

public String oracle.sqlj.checker.JdbcVersion.to_string();

次のコマンドを使用して、JPublisherによりクライアント側の起動用にJdbcVersionを公開します。

% jpub -sql=scott/tiger -java=oracle.sqlj.checker.JdbcVersion:JdbcVersion Client

このコマンドで生成されるクライアント側JavaクラスJdbcVersionClientには、次のAPIが含まれます。

public class JdbcVersionClient
{
 ...
 public java.lang.String toString(long _handle);
 public java.lang.String to_string();
 ...
}

すべての静的メソッドが、クライアント側のコードに含まれるインスタンス・メソッドにマップされます。 サーバー側のクラスに含まれるインスタンス・メソッド(toString()など)は、追加ハンドルが含まれるメソッドにマップされます。 ハンドルは、サーバーのoracle.sqlj.checker.JdbcVersionのインスタンスを表します。 ハンドルは、サーバー側でのインスタンス・メソッドのコールに使用されます。


関連項目:

『Oracle Database JPublisher ユーザーズ・ガイド』