6 Oracle Javaデータ・カートリッジ

Oracle Continuous Query Language (CQL)の拡張機能であるOracle Javaデータ・カートリッジの使用方法を説明します。Oracle CQLを使用して、Oracle Stream ExplorerアプリケーションでJavaクラスを操作するCQLコードを記述できます。

この章では、Oracle Javaデータ・カートリッジが公開する型、メソッド、フィールドおよびコンストラクタについて説明します。これらの型、メソッド、フィールドおよびコンストラクタを、Oracle CQLのネイティブ型と同様に、Oracle CQLの問合せおよびビューで使用できます。

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

6.1 Oracle Javaデータ・カートリッジについて

Oracle Javaデータ・カートリッジは、Oracle Stream ExplorerアプリケーションでJavaクラスを操作するOracle CQL問合せおよびビューを記述できるようにする組込みJavaカートリッジです。

6.1.1 データ・カートリッジ名

Oracle Javaデータ・カートリッジでは、カートリッジID com.oracle.cep.cartrdiges.javaを使用します。

Oracle Javaデータ・カートリッジはデフォルトのOracle Stream Analyticsデータ・カートリッジです。

デフォルトのJavaパッケージ名配下の型またはjava.langシステム・パッケージ配下の型の場合、次のように、Oracle CQL問合せでパッケージ名またはデータ・カートリッジ名で修飾せずにそのJava型を参照できます。

<query id="q1"><![CDATA[
    select String(“foo") …
></query>

注意:

Oracle Javaデータ・カートリッジの型名を単純化するには、Oracle Fusion Middleware Oracle Stream Analytics Oracle CQL言語リファレンスで説明しているエイリアスを使用できます。

詳細は、クラスのロードを参照してください。

6.1.2 クラスのロード

Oracle Javaデータ・カートリッジでは、Oracle CQL問合せが参照するJavaクラスのロードについて、次のポリシーをサポートしています。

詳細は、次を参照してください。

6.1.2.1 アプリケーション・クラス・スペース・ポリシー

これは、デフォルトのクラス・ローディング・ポリシーです。

このモードでは、Oracle Javaデータ・カートリッジはJavaクラスの検索時に、有効範囲内のアプリケーションのクラス・スペースを使用します。

これは、型がローカル名によってのみ指定されている場合、すなわち識別子が1つで、他の識別子がパッケージで使用されていない場合にのみ適用できます。つまり、次のようになります。

select String(“foo") …

次の場合には適用できません。

select java.lang.String(“foo") …

この場合、手順は次のようになります。

  • 通常どおりに、アプリケーションのクラス・スペースを使用して、1つの識別子(ID1と呼びます)で定義されたクラスをロードします。これに失敗した場合、

  • アプリケーションで、パッケージとは関係なく、バンドルの内部クラス・パス内で名前がID1と一致するクラスが定義されているかどうかを確認します。これに失敗した場合、

  • アプリケーションでImport-Package MANIFESTヘッダー文が指定されているかどうかを確認します。これとID1を使用して、Javaクラスをロードできます。

例については、「クラスのロード例」を参照してください。

6.1.2.2 自動インポートなしクラス・スペース・ポリシー

これは、オプションのクラス・ローディング・ポリシーです。このポリシーを使用するには、次のようにOracle Stream ExplorerアプリケーションにMANIFESTヘッダー・エントリを含める必要があります。

OCEP_JAVA_CARTRIDGE_CLASS_SPACE: APPLICATION_NO_AUTO_IMPORT_CLASS_SPACE

このモードはアプリケーション・クラス領域ポリシーと似ていますが、Oracle Event ProcessingによってパッケージがID1に組み合されない点が異なります。

詳細は、「アプリケーション・クラス・スペース・ポリシー」を参照してください。

6.1.2.3 サーバー・クラス・スペース・ポリシー

これは、オプションのクラス・ローディング・ポリシーです。このポリシーを使用するには、次のようにOracle Stream ExplorerアプリケーションにMANIFESTヘッダー・エントリを含める必要があります。

OCEP_JAVA_CARTRIDGE_CLASS_SPACE: SERVER_CLASS_SPACE

Oracle CQL問合せは、クラス・パッケージがアプリケーションまたはバンドルにインポートされているかにかかわらず、エクスポートされたあらゆるJavaクラスを参照できます。

また、問合せでは、ランタイムJDKクラスを含む、OSGiフレームワークの親クラス・ローダーに表示されるすべてのクラスにアクセスできます。

つまり、Oracle CQLアプリケーションでは、他のOracle Stream Explorerアプリケーションで定義されたクラス(エクスポートされている場合)を参照するOracle CQL問合せを使用できます。これにより、新しいJavaライブラリを提供することが唯一の目的であるJavaベース・カートリッジの作成が容易になります。

注意:

参照できるJavaクラスはOracle Stream Explorerアプリケーションの内部クラスパスにあるJavaクラス(エクスポートされている場合)のみであり、このアプリケーション内のプロセッサが当該Oracle CQL問合せを定義している場合でも参照可能です。

例については、「クラスのロード例」を参照してください。

6.1.2.4 クラスのロード例

図6-1の例では、B2がエクスポートするパッケージpackage2B1がインポートしています。

図6-1 Oracle Stream Analytics Event Processingアプリケーションの例

図6-1の説明が続きます
「図6-1 Oracle Stream Analytics Event Processingアプリケーションの例」の説明

表6-1は、アプリケーション・クラス領域またはサーバー・クラス領域で実行されているかによって、2つの異なるアプリケーションがアクセスできるクラスをまとめています。

表6-1 クラスのロード・ポリシー別のクラス・アクセシビリティ

クラスのロード・ポリシー アプリケーションB1 アプリケーションB2

アプリケーション・クラス・スペース

  • mypackage1.A

  • myprivatepackage1.B

  • package2.C

  • package2.C

  • privatepackage2.D

サーバー・クラス・スペース

  • package2.C

  • package2.C

アプリケーションB1では、Oracle CQL問合せでJavaクラスA、BおよびCのいずれも使用できます。

select A …
select B …
select C …

しかし、アプリケーションB2では、Oracle CQL問合せでJavaクラスAおよびBは使用できません。JavaクラスCおよびDのみ使用できます。

select C …
select D …

6.1.3 メソッド解決

JavaメソッドにアクセスするOracle CQL式は、次のアルゴリズムを使用してメソッドを解決します。

  1. すべてのパラメータは、「データ型マッピング」に説明されているように、Java型に変換されます。

    たとえば、Oracle CQL INTEGERはJavaプリミティブintに変換されます。

  2. 標準のJavaメソッド解決ルールが、Java言語仕様の第3版、15.12項「Method Invocation Expressions」に説明されているとおりに適用されます。

注意:

可変arityメソッドはサポートされていません。詳細は、Java言語仕様の第3版、12.12.2.4項を参照してください。

例として、次のOracle CQL式を考えてみます。

attribute.methodA(10)

attributeは、オーバーロードされた次のメソッドを定義する型mypackage.MyTypeです。

  • methodA(int)

  • methodA(Integer)

  • methodA(Object)

  • methodA(long)

リテラル10はプリミティブ型intであるため、優先順位は次のとおりです。

  • methodA(int)

  • methodA(long)

  • methodA(Integer)

  • methodA(Object)

詳細は、「クラスのロード」を参照してください。

6.1.4 データ型マッピング

Oracle Javaデータ・カートリッジは、Oracle CQLネイティブ・データ型とJavaデータ型間に固定算術マッピングを適用します。

  • 表6-2は、Oracle CQLネイティブ・データ型とJavaデータ型間のマッピングの一覧です。

  • 表6-3はJavaデータ型とOracle CQLネイティブ・データ型間のマッピングの一覧です。

表6-2 Oracle Javaデータ・カートリッジ: Oracle CQLからJavaデータ型へのマッピング

Oracle CQLネイティブ・データ型 Javaデータ型

BIGINT

long

BOOLEAN

boolean

BYTE

byte[]

CHAR

java.lang.String

DOUBLE

double

FLOAT

float

INTEGER

int

INTERVAL

long

INTERVAL_DAY

long, java.lang.String

INTERVAL_DAY_TO_SECOND

java.lang.String

INTERVAL_YEAR

long, java.lang.String

INTERVAL_MONTH

long, java.lang.String

INTERVAL_YEAR_TO_MONTH

java.lang.String

XMLTYPE

java.lang.String

表6-3 Oracle Javaデータ・カートリッジ: Javaデータ型からOracle CQLへのマッピング

Javaデータ型 Oracle CQLネイティブ・データ型

long

BIGINT

boolean

BOOLEAN

byte[]

BYTE

java.lang.String

CHAR

double

DOUBLE

float

FLOAT

int

INTEGER

java.sql.Date

java.sql.Timestamp

INTERVAL

java.sql.SQLXML

XMLTYPE

他のすべてのJavaクラスは、複合型としてマップされます。

これらのデータ型マッピングの詳細は、次の項を参照してください。

6.1.4.1 Javaデータ型StringおよびOracle CQLデータ型CHAR

Oracle CQLデータ型のCHARjava.lang.Stringにマップされ、java.lang.StringはOracle CQLデータ型CHARにマップされます。すなわち、Oracle CQL CHARとして定義された属性のjava.lang.Stringメンバー・フィールドおよびメソッドにアクセスできます。たとえば、a1がOracle CQL CHAR型として宣言されている場合、次のような問合せを記述できます。

<query id="q1"><![CDATA[ 
    select a1.substring(1,2)
></query>
6.1.4.2 リテラル

Oracle CQL CHARリテラルであっても、リテラルのメンバー・フィールドおよびメソッドにはアクセスできません。たとえば、次のような問合せは使用できません

<query id="q1-forbidden"><![CDATA[ 
    select "hello".substring(1,2)
></query>
6.1.4.3 配列

Javaの配列はOracle CQLデータ・カートリッジの配列に変換され、Oracle CQLデータ・カートリッジの配列はJavaの配列に変換されます。これは、複合型と単純型の両方に適用されます。

データ・カートリッジのTABLE句を使用して、Oracle CQL問合せのFROM句内のデータ・カートリッジ関数から返された複数の行にアクセスできます。

詳細は、コレクションを参照してください。

6.1.4.4 コレクション

通常、Oracle Javaデータ・カートリッジはjava.util.Collectionインタフェースを実装するインスタンスをOracle CQL複合型に変換します。

Oracle CQL問合せは、java.util.Collectionのメンバーを介して繰り返すことができます。

データ・カートリッジのTABLE句を使用して、Oracle CQL問合せのFROM句内のデータ・カートリッジ関数から返された複数の行にアクセスできます。

詳細は、配列を参照してください。

6.1.5 Oracle Javaデータ・カートリッジのOracle CQL問合せサポート

Oracle Javaデータ・カートリッジ型は、SELECTおよびWHERE句内の式で使用できます。

Oracle Javaデータ・カートリッジ型は、ORDER BY句内の式では使用できません。

詳細は、Oracle Javaデータ・カートリッジの使用を参照してください。

6.2 Oracle Javaデータ・カートリッジの使用

Oracle Stream AnalyticsアプリケーションでのOracle Javaデータ・カートリッジの使用方法をまとめた共通のユース・ケースを説明します。

詳細は、Oracle Javaデータ・カートリッジのOracle CQL問合せサポートを参照してください。

6.2.1 Java APIを使用する問合せ方法

この手順は、Javaクラス(Address.java)として定義されたイベント・プロパティ型を持つタプル(Student)として定義された1つのイベント・タイプを使用するOracle Stream Explorerアプリケーションで、Oracle Javaデータ・カートリッジを使用する方法を説明しています。

Javaクラスを使用して問合せするには:

  1. Address.javaクラスを実装します。
    package test;
    
    class Address {
        String street;
        String state;
        String city;
        String [] phones;
    }
    

    この例では、Address.javaクラスがこのアプリケーションに属すると仮定します。

    Address.javaクラスが別のOracle Stream Explorerアプリケーションに属していた場合、親アプリケーションにエクスポートする必要があります。詳細は、「エクスポートしたJavaクラスを使用する問合せ方法」を参照してください。

  2. イベント・タイプ・リポジトリを定義します。
    <event-type-repository>
        <event-type name="Student">
            <properties>
                <property name="name" type="char"/>
                <property name="address" type="Address"/>
            </properties>
        </event-type>
    
        <event-type name="Address">
            <class-name>test.Address</class-name>
        </event-type>
    <event-type-repository>
    

    test.Addressクラスは、このアプリケーションに属しているため、イベント・タイプ・リポジトリで宣言できます。これにより、自動的にこのアプリケーション内でクラスに対してグローバルにアクセスできるようになります。パッケージをエクスポートする必要はありません。

  3. アダプタがStudentイベントをStudentStreamチャネルに提供していると想定します。
    <channel id="StudentStream" event-type="Student"/>
    
  4. StudentStreamは、Oracle CQL問合せq1でプロセッサに接続されます。
    <processor> 
        <rules>
            <query id="q1"><![CDATA[ 
                select 
                    name, 
                    address.street as street, 
                    address.phones[0] as primary_phone 
                from 
                    StudentStream
            ></query>
        </rules>
    </processor>
    

    Oracle Javaデータ・カートリッジでは、標準のJava APIを使用してOracle CQL問合せからaddressイベント・プロパティにアクセスできます。

6.2.2 エクスポートしたJavaクラスを使用する問合せ方法

この手順は、Javaクラス(Address.java)として定義されたイベント・プロパティ型を持つタプル(Student)として定義された1つのイベント・タイプを使用するOracle Stream Analyticsアプリケーションで、Oracle Javaデータ・カートリッジを使用する方法を説明しています。この手順では、Address.javaクラスは別のOracle Stream Analyticsアプリケーションに属します。親アプリケーションでエクスポートされ、同じOracle Stream Analyticsサーバーにデプロイされた別のOracle Stream Analyticsアプリケーションにアクセス可能になります。

Javaクラスを使用して問合せするには:

  1. Address.javaクラスを実装します。
    package test;
    
    class Address {
        String street;
        String state;
        String city;
        String [] phones;
    }
    
  2. Address.javaクラスを含むtestパッケージをエクスポートします。

    詳細は、『Oracle Fusion Middleware Oracle Stream Analyticsによるイベント処理用アプリケーションの開発』を参照してください。

    testパッケージは、このOracle Stream Analyticsアプリケーションの一部である場合も、このアプリケーションと同じOracle Stream Analyticsサーバーにデプロイされた別のOracle Stream Analyticsアプリケーションの一部である場合もあります。

  3. イベント・タイプ・リポジトリを定義します。
    <event-type-repository>
        <event-type name="Student">
            <property name="name" type="char"/>
            <property name="address" type="Address"/>
        </event-type>
    <event-type-repository>
    
  4. アダプタがStudentイベントをStudentStreamチャネルに提供していると想定します。
    <channel id="StudentStream" event-type="Student"/>
    
  5. StudentStreamは、Oracle CQL問合せq1でプロセッサに接続されます。
    <processor> 
        <rules>
            <query id="q1"><![CDATA[ 
                select 
                    name, 
                    address.street as street, 
                    address.phones[0] as primary_phone 
                from 
                    StudentStream
            ></query>
        </rules>
    </processor>
    

    Oracle Javaデータ・カートリッジでは、標準のJava APIを使用してOracle CQL問合せからaddressイベント・プロパティにアクセスできます。

6.2.3 Javaキャスト関数

JavaカートリッジではJavaキャスト関数が使用可能で、Java拡張可能型から別のJava拡張可能型へのキャストが可能です。ただし、キャスト元からキャスト先を割り当てることができる必要があります。この関数を使用するには、Javaカートリッジがインストールされている必要があります。

構文

T cast@java(l-value, class-literal<T>)

パラメータ

l-value: キャストするデータを持つイベント属性です。l-valueTから割り当てることができない場合、Java Cartridgeはキャスト関数呼出し時にRuntimeInvocationExceptionをスローします。

class-literal<T>: キャスト先のクラス名です。たとえば、intlongにキャストする場合、class-literal<T>Long.classです。

次のクラス階層を考慮します。

public class Parent 
{
...
}
 
public class Child extends Parent
{
...
}

次の例では、Child型のオブジェクトがキャストされます。

cast@java(S.parent, Child.class)