Java UDF ハンドラーの作成

このトピックでは、ユーザー定義関数(UDF)のJavaハンドラーを記述する方法について説明します。Java UDF を記述するときは、Snowflakeが UDF ロジックとして実行するためのSnowflake用Javaコードを記述します。このJavaコードは UDF のハンドラーです。

UDF を CREATE FUNCTION で展開し、 UDF に名前を付け、 UDF が呼び出されたときに使用するハンドラーとしてJavaメソッドを指定します。SQL を使用した UDF の作成の詳細については、 UDF の作成 をご参照ください。

その他のサンプルコードについては、 Java UDF ハンドラーの例 をご参照ください。

このトピックの内容:

Javaでの UDF ハンドラーの記述

Java UDF ハンドラーを記述するときは、次の要件とガイドラインを使用します。

  • クラスを公開として定義します。

  • クラス内で、 UDF ハンドラーとして使用するパブリックメソッドを少なくとも1つ宣言します。

    インライン UDF の場合は、1つのハンドラーメソッドのみを宣言します。代わりに、クラスをステージングされたハンドラーとして JAR にパッケージ化する場合は、複数のハンドラーメソッドを宣言し、後で CREATE FUNCTION ステートメントの HANDLER 句を使用して、それぞれをハンドラーとして指定できます。

    インラインハンドラーとステージされたハンドラーの違いに関する詳細については、 ハンドラーコードのインラインまたはステージ上での保持 をご参照ください。

    必要に応じて、ハンドラーメソッドによって呼び出される他のメソッドを宣言できます。

    各ハンドラーメソッドについては、次の要件とガイドラインを使用します。

    • ハンドラーメソッドを静的または非静的のパブリックとして宣言します。

      メソッドが非静的である場合、クラスは引数なしのコンストラクターを宣言するか、コンストラクターを一切なしにする必要があります。

      Snowflakeは、クラスをインスタンス化するときにコンストラクターに引数を渡しません。コンストラクターがエラーをスローすると、エラーは例外メッセージとともにユーザーエラーとしてスローされます。

    • 適切な戻り型を指定します。

      戻り型は、 SQL-Java型マッピングテーブルJava Data Type 列で指定されたデータタイプの1つである必要があります。戻り型は、 CREATE FUNCTION ステートメントの RETURNS 句で指定された SQL データ型と互換性がある必要があります。

    • 各ハンドラーメソッド引数(存在する場合)が、 SQL-Java型マッピングテーブルJava Data Type 列で指定されたデータ型であることを確認します。

      Java変数のデータ型を選択するときは、Snowflakeから送信(およびSnowflakeに返信)される可能性のあるデータの可能な最大値と最小値を考慮に入れてください。

    • 所定のJavaクラスでメソッドをオーバーロードする場合、Snowflakeはクラス内のハンドラーメソッドを区別するために、その ではなく、メソッド引数の のみを使用することに留意してください。一部の SQL データ型は複数のJavaデータ型にマップでき、したがって複数のハンドラーメソッド署名にマップできる可能性があるため、データ型に基づいて解決することは実用的ではありません。

      たとえば、あるクラス内にある2つのJavaメソッドの名前と引数の数が同じで、データ型が異なる場合、これらのメソッドの1つをハンドラーとして使用する UDF を呼び出すと、次のようなエラーが生成されます。

      Cannot determine which implementation of handler "handler name" to invoke since there are multiple
      definitions with <number of args> arguments in function <user defined function name> with
      handler <class name>.<handler name>
      

      ウェアハウスが使用可能な場合は、 UDF の作成時にエラーが検出されます。それ以外の場合は、 UDF が呼び出されたときにエラーが発生します。

    • 各ハンドラーメソッドとそれが呼び出すメソッドで、Java UDFs に対するSnowflakeによる制約に準拠します。これらの制約の詳細については、 Snowflakeが課す制約内でのハンドラーの設計 をご参照ください。

クラスパスへの依存関係の追加

ハンドラーコードで外部 JAR ファイルにパッケージ化されたクラスが必要な場合は、ハンドラーで使用可能なSnowflake管理のクラスパスにこれらの依存関係を追加できます。次に、Java UDF ハンドラーに表示されるクラスパスに JAR ファイルを追加する方法について説明します。詳細については、 コードで依存関係を利用できるようにする方法 をご参照ください。

ファイルの整理

Javaコードをコンパイルして JAR ファイルを自分で作成する場合は、以下に示すようにファイルを整理できます。この例では、Javaのパッケージメカニズムの使用が予定されていることを前提としています。

  • developmentDirectory

    • packageDirectory

      • class_file1.java

      • class_file2.java

    • classDirectory

      • class_file1.class

      • class_file2.class

    • manifest_file.manifest(オプション)

    • jar_file.jar

    • put_command.sql

developmentDirectory

このディレクトリには、Java UDF の作成に必要なプロジェクト固有のファイルが含まれています。

packageDirectory

このディレクトリには、コンパイルしてパッケージに含める.javaファイルが含まれています。

class_file#.java

これらのファイルには、 UDF のJavaソースコードが含まれています。

class_file#.class

これらは、.javaファイルをコンパイルすることによって作成された.classファイルです。

manifest_file.manifest

.classファイル(およびオプションで依存関係 JAR ファイル)を JAR ファイルに結合するときに使用される、オプションのマニフェストファイル。

jar_file.jar

UDF コードを含んだ JAR ファイル。

put_command.sql

このファイルには、JAR ファイルをSnowflake ステージ にコピーするための SQL PUT コマンドが含まれています。

Javaコードのコンパイルと JAR ファイルの作成

コンパイルされたJavaコードを含んだ JAR ファイルを作成するには、

  • javacを使用して、.javaファイルを.classファイルにコンパイルします。

    バージョン11.xより新しいコンパイラを使用する場合は、「-release」オプションを使用して、ターゲットバージョンがバージョン11であることを指定できます。

  • .classファイルを JAR ファイルに配置します。複数のクラスファイル(およびその他の JAR ファイル)を JAR ファイルにパッケージ化できます。

    例:

    jar cf ./my_udf.jar MyClass.class
    
    Copy

    ハンドラークラスがパッケージに含まれている場合はマニフェストファイルが必要であり、そうでない場合はオプションです。次の例では、マニフェストファイルを使用しています。

    jar cmf my_udf.manifest ./my_udf.jar example/MyClass.class
    
    Copy

    すべての依存関係が含まれているjarファイルをビルドするには、maven-assembly-pluginでMavenの mvn package コマンドを使用できます。maven-assembly-pluginの詳細については、 Mavenの使用方法のページ をご参照ください。

    Snowflakeは、 標準のJavaライブラリ (例: java.util)を自動的に提供します。コードでこれらのライブラリを呼び出す場合は、 JAR ファイルに含める必要はありません。

    ライブラリで呼び出すメソッドは、Javaメソッドと同じSnowflakeによる制約に従う必要があります。これらの制約の詳細については、 Snowflakeが課す制約内でのハンドラーの設計 をご参照ください。

JAR ファイルのステージへのコピー

Snowflakeがハンドラーメソッドを含む JAR から読み取るには、 JAR を次に挙げる種類のステージのいずれかにコピーする必要があります。

  • ユーザーまたは名前付き内部ステージ。

    Snowflakeは現在、テーブルステージを使用して UDF ハンドラーを含む JAR ファイルを格納することをサポートしていません。内部ステージの詳細については、 ローカルファイルに対する内部ステージの選択 をご参照ください。

  • 外部ステージ。

JAR ファイルをホストするステージは、 UDF の 所有者 によって読み取り可能である必要があります。

通常、 PUT コマンドを使用して、名前付き内部ステージに JAR をアップロードします。Snowflake GUI を介して PUT コマンドを実行することはできないことに注意してください。 SnowSQL を使用して PUT を実行できます。.jarファイルをステージにコピーするための PUT コマンドの例については、 Java UDF ハンドラーの例 セクションをご参照ください。

ステージの作成の詳細については、 CREATE STAGE をご参照ください。

警告とベストプラクティス

JAR ファイルを削除または名前変更すると、 UDF を呼び出すことができなくなります。

JAR ファイルを更新する必要がある場合は、次を実行します。

  • UDF の呼び出しができない間に更新します。

  • 古い.jarファイルがまだステージにある場合、 PUT コマンドには OVERWRITE=TRUE 句を含める必要があります。

注釈

UDFs に関連して実行するユーザーには、アクションに必要な権限が割り当てられたロールが必要です。詳細については、 Granting Privileges for User-Defined Functions をご参照ください。