Erstellen eines Java-UDF-Handlers

Unter diesem Thema wird beschrieben, wie Sie den Java-Handler für eine benutzerdefinierte Funktion (UDF) schreiben. Wenn Sie eine Java-UDF erstellen, schreiben Sie Java-Code, den Snowflake als UDF-Logik ausführen soll. Dieser Java-Code ist der Handler der UDF.

Sie stellen die UDF mit CREATE FUNCTION bereit, geben der UDF einen Namen und geben die Java-Methode als Handler an, die beim Aufruf der UDF verwendet werden soll. Weitere Informationen zum Erstellen einer UDF mit SQL finden Sie unter Erstellen einer UDF.

Weitere Codebeispiele finden Sie unter Beispiele für Java-UDF-Handler.

Unter diesem Thema:

Schreiben des UDF-Handlers in Java

Beachten Sie beim Schreiben eines Java-UDF-Handlers die folgenden Anforderungen und Richtlinien.

  • Definieren Sie die Klasse als „public“.

  • Deklarieren Sie innerhalb der Klasse mindestens eine öffentliche Methode, die als UDF-Handler verwendet werden soll.

    Bei einer Inline-UDF deklarieren Sie nur eine einzige Handler-Methode. Wenn Sie aber beabsichtigen, die Klasse in eine JAR-Datei zu packen und die Datei als Handler in einem Stagingbereich bereitzustellen, können Sie mehrere Handler-Methoden deklarieren und später jede mit der HANDLER-Klausel einer CREATE FUNCTION-Anweisung als Handler spezifizieren.

    Weitere Informationen zum Unterschied zwischen einem Inline-Handler und einem Staging-Handler finden Sie unter Speichern von Handler-Code inline oder in einem Stagingbereich.

    Sie können bei Bedarf weitere Methoden deklarieren, die von der Handler-Methode aufgerufen werden.

    Beachten Sie die folgenden Anforderungen und Richtlinien bei jeder Handler-Methode:

    • Deklarieren Sie die Handler-Methode als „public“ (öffentlich), entweder statisch oder nicht-statisch.

      Wenn die Methode nicht statisch ist, muss Ihre Klasse auch einen Konstruktor mit null Argumenten oder überhaupt keinen Konstruktor deklarieren.

      Snowflake übergibt beim Instanziieren der Klasse keine Argumente an den Konstruktor. Wenn der Konstruktor einen Fehler auslöst, wird dieser Fehler zusammen mit der Ausnahmemeldung als Benutzerfehler ausgelöst.

    • Geben Sie einen geeigneten Rückgabetyp an.

      Der Rückgabetyp muss einer der in der Spalte Java Data Type der SQL-Java-Typzuordnungstabelle angegebenen Datentypen sein. Der Rückgabetyp muss mit dem SQL-Datentyp kompatibel sein, der in der RETURNS-Klausel der CREATE FUNCTION-Anweisung angegeben ist.

    • Stellen Sie sicher, dass jedes Argument der Handler-Methode (falls vorhanden) ein Datentyp ist, der in der Spalte Java Data Type der SQL-Java-Typzuordnungstabelle angegeben ist.

      Berücksichtigen Sie bei der Auswahl der Datentypen von Java-Variablen die maximal und minimal möglichen Werte der Daten, die von Snowflake gesendet (und an Snowflake zurückgegeben) werden könnten.

    • Wenn Sie eine Methode in einer bestimmten Java-Klasse überladen, denken Sie daran, dass Snowflake nur die Anzahl der Methodenargumente verwendet, nicht deren Typen, um die Handler-Methoden innerhalb einer Klasse zu unterscheiden. Das Auflösen auf Basis von Datentypen ist unpraktisch, da einige SQL-Datentypen mehr als einem Java-Datentyp und damit potenziell mehr als einer Handler-Methoden-Signatur zugeordnet werden können.

      Wenn beispielsweise zwei Java-Methoden einer Klasse den gleichen Namen, die gleiche Anzahl von Argumenten, aber unterschiedliche Datentypen haben, dann generiert der Aufruf einer UDF mit einer dieser Methoden als Handler einen Fehler, der in etwa wie folgt lautet:

      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>
      

      Wenn ein Warehouse vorhanden ist, wird der Fehler zum Zeitpunkt der Erstellung der UDF erkannt. Andernfalls tritt der Fehler beim Aufruf der UDF auf.

    • Achten Sie bei jeder Handler-Methode und den von ihr aufgerufenen Methoden auf die Einhaltung der Snowflake-bedingten Einschränkungen für Java-UDFs. Weitere Informationen zu diesen Einschränkungen finden Sie unter Entwerfen von Handlern unter Berücksichtigung der Snowflake-bedingten Einschränkungen.

Hinzufügen von Abhängigkeiten zum Klassenpfad

Wenn Ihr Handler-Code Klassen benötigt, die in externen JAR-Dateien verpackt sind, können Sie diese Abhängigkeiten dem von Snowflake verwalteten Klassenpfad hinzufügen, der für Ihren Handler verfügbar ist. Im Folgenden wird beschrieben, wie JAR-Dateien dem Klassenpfad hinzufügt werden, der für einen Java-UDF Handler sichtbar ist. Weitere Informationen dazu finden Sie unter Abhängigkeiten für Code zur Verfügung stellen.

Organisieren Ihrer Dateien

Wenn Sie vorhaben, den Java-Code zu kompilieren, um die JAR-Datei selbst zu erstellen, können Sie die Dateien wie unten gezeigt organisieren. Dieses Beispiel geht davon aus, dass Sie den Package-Mechanismus von Java verwenden möchten.

  • Entwicklungsverzeichnis

    • Paketverzeichnis

      • Klassendatei1.java

      • Klassendatei2.java

    • classDirectory

      • Klassendatei1.class

      • Klassendatei2.class

    • Manifestdatei.manifest (optional)

    • jar_Datei.jar

    • put_Befehl.sql

developmentDirectory

Dieses Verzeichnis enthält die projektspezifischen Dateien, die zum Erstellen Ihrer Java-UDF erforderlich sind.

packageDirectory

Dieses Verzeichnis enthält die .java-Dateien, die kompiliert und in das Paket aufgenommen werden sollen.

class_file#.java

Diese Dateien enthalten den Java-Quellcode der UDF.

class_file#.class

Dies sind die .class-Dateien, die durch Kompilieren der .java-Dateien erstellt werden.

manifest_file.manifest

Die optionale Manifestdatei, die beim Kombinieren der .class-Dateien (und optional der Abhängigkeits-JAR-Dateien) in der JAR-Datei verwendet werden.

jar_file.jar

Die JAR-Datei, die den UDF-Code enthält.

put_command.sql

Diese Datei enthält den SQL-Befehl PUT zum Kopieren der JAR-Datei in einen Snowflake-Stagingbereich.

Kompilieren des Java-Codes und Erstellen der JAR-Datei

So erstellen Sie eine JAR-Datei, die den kompilierten Java-Code enthält:

  • Verwenden Sie javac, um Ihre .java-Datei in eine .class-Datei zu kompilieren.

    Wenn Sie einen Compiler neuer als Version 11.x verwenden, können Sie mit der Option „–release“ angeben, dass die Zielversion Version 11 ist.

  • Legen Sie Ihre .class-Datei in eine JAR-Datei. Sie können mehrere Klassendateien (und andere JAR-Dateien) in Ihre JAR-Datei packen.

    Beispiel:

    jar cf ./my_udf.jar MyClass.class
    
    Copy

    Eine Manifestdatei ist erforderlich, wenn sich Ihre Handler-Klasse in einem Paket befindet, andernfalls ist sie optional. Im folgenden Beispiel wird eine Manifestdatei verwendet:

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

    Um die JAR-Datei mit allen enthaltenen Abhängigkeiten zu erstellen, können Sie den Maven-Befehl mvn package mit dem maven-assembly-plugin verwenden. Weitere Informationen zum maven-assembly-plugin finden Sie auf der Seite zur Maven-Nutzung.

    Snowflake stellt automatisch die Standard-Java-Bibliotheken (z. B. java.util) bereit. Wenn Ihr Code diese Bibliotheken aufruft, müssen Sie sie nicht in Ihre JAR-Datei aufnehmen.

    Die Methoden, die Sie in Bibliotheken aufrufen, müssen denselben Snowflake-bedingten Einschränkungen folgen wie Ihre Java-Methode. Weitere Informationen zu diesen Einschränkungen finden Sie unter Entwerfen von Handlern unter Berücksichtigung der Snowflake-bedingten Einschränkungen.

Kopieren der JAR-Datei in Ihren Stagingbereich

Damit Snowflake aus der JAR-Datei, die Ihre Handler-Methode enthält, lesen kann, müssen Sie die JAR-Datei in eine der folgenden Arten von Stagingbereich kopieren:

  • Ein Benutzer oder ein benannter interner Stagingbereich.

    Snowflake unterstützt derzeit nicht die Verwendung eines Tabellen-Stagingbereichs zur Speicherung einer JAR-Datei, die UDF-Handler enthält. Weitere Informationen zu internen Stagingbereichen finden Sie unter Auswahl eines internen Stagingbereichs für lokale Dateien.

  • Ein externer Stagingbereich.

Der Stagingbereich, der die JAR-Datei hostet, muss für den Eigentümer der UDF-Datei lesbar sein.

Normalerweise laden Sie die JAR-Datei mit dem Befehl PUT in einen benannten internen Stagingbereich hoch. Beachten Sie, dass Sie den Befehl PUT nicht über die Snowflake-GUI ausführen können. Sie können aber SnowSQL verwenden, um PUT auszuführen. Im Abschnitt Beispiele für Java-UDF-Handler finden Sie ein Beispiel für die Verwendung des PUT-Befehls zum Kopieren einer .jar-Datei in einen Stagingbereich.

Weitere Informationen zum Erstellen von Stagingbereichen finden Sie unter CREATE STAGE.

Beschränkungen und Best Practices

Wenn Sie die JAR-Datei löschen oder umbenennen, können Sie die UDF-Datei nicht mehr aufrufen.

Wenn Sie Ihre JAR-Datei aktualisieren müssen, gehen Sie wie folgt vor:

  • Aktualisieren Sie die Datei, wenn keine Aufrufe an die UDF erfolgen können.

  • Wenn sich die alte .jar-Datei noch im Stagingbereich befindet, muss der PUT-Befehl die OVERWRITE=TRUE-Klausel enthalten.

Bemerkung

Ein Benutzer, der Aktionen im Zusammenhang mit UDFs ausführt, muss über eine Rolle verfügen, der die für die Aktion erforderlichen Berechtigungen zugewiesen wurden. Weitere Informationen dazu finden Sie unter Granting Privileges for User-Defined Functions.