Todos los productos
Search
Centro de documentos

MaxCompute:UDTF de Java

Última actualización: Sep 04, 2026

Escribir una función de tabla definida por el usuario (UDTF) en Java es una forma eficaz de gestionar tareas complejas de procesamiento de datos e implementar lógica personalizada. Al aprovechar las funciones del lenguaje Java, puede satisfacer mejor requisitos específicos de procesamiento de datos, lo que mejora tanto la eficiencia del desarrollo como el rendimiento del procesamiento. Este tema describe la estructura del código, el uso y ejemplos de las UDTF de Java.

Estructura del código de UDTF

Puede escribir código de UDTF en Java mediante IntelliJ IDEA (Maven) o MaxCompute Studio. El código debe incluir los siguientes componentes:

  • Paquete de Java: opcional.

    Puede organizar sus clases de Java en un paquete para facilitar su búsqueda y uso.

  • Extender la clase UDTF: obligatorio.

    Las clases requeridas son com.aliyun.odps.udf.UDTF, com.aliyun.odps.udf.annotation.Resolve (para la anotación @Resolve) y com.aliyun.odps.udf.UDFException (para los métodos en la clase de Java). Si necesita usar otras clases UDTF o tipos de datos complejos, agregue las clases necesarias según MaxCompute UDF overview.

  • Clase de Java personalizada: obligatoria.

    Esta es la unidad organizativa del código de la UDTF. Define las variables y los métodos que implementan su lógica de negocio.

  • Anotación @Resolve: obligatoria.

    El formato es @Resolve(<signature>). signature es una firma de función que define los tipos de datos de los parámetros de entrada y del valor de retorno. Una UDTF no puede obtener la firma de la función mediante reflexión y debe usar la anotación @Resolve para especificarla; por ejemplo, @Resolve("smallint->varchar(10)"). Para obtener más información sobre la anotación @Resolve, consulte @Resolve annotation.

  • Implementar métodos en la clase de Java: obligatorio.

    La implementación de la clase de Java incluye los siguientes cuatro métodos. Puede elegir implementarlos según sus necesidades.

    API

    Descripción

    public void setup(ExecutionContext ctx) throws UDFException

    Método de inicialización. MaxCompute invoca su lógica de inicialización personalizada antes de que la UDTF comience a procesar los datos de entrada. El método setup se llama una vez por cada worker.

    public void process(Object[] args) throws UDFException

    La función process se invoca una vez por cada registro en una consulta SQL. Los parámetros de la función process son los parámetros de entrada especificados para la UDTF en la instrucción SQL. Los parámetros de entrada se pasan como una matriz Object[], y la salida se genera mediante la función forward. Debe llamar a la función forward dentro de la función process para determinar la salida.

    Nota

    Si no se llama a forward desde el método process o close, se pueden perder datos. Por ejemplo, si un hilo en segundo plano ejecuta una llamada a forward, debe asegurarse de que el método process no finalice hasta que la llamada a forward se complete, a fin de evitar la pérdida de datos.

    public void close() throws UDFException

    Método de finalización de la UDTF. Se invoca solo una vez, después de procesar el último registro.

    public void forward(Object …o) throws UDFException

    Llame al método forward para generar datos de salida; cada llamada a forward produce un registro. Cuando invoca una UDTF en una consulta SQL, puede usar la cláusula as para cambiar el nombre de la salida de forward.

    Al escribir una UDTF de Java, puede usar tipos de Java o tipos Writable de Java. Para consultar la asignación detallada entre los tipos de datos compatibles con MaxCompute y los tipos de datos de Java, consulte Data types.

A continuación se muestra un ejemplo de UDTF.

// Organize the defined Java class in the org.alidata.odps.udtf.examples package.
package org.alidata.odps.udtf.examples;
// Extend the UDTF class.
import com.aliyun.odps.udf.UDTF;
import com.aliyun.odps.udf.UDTFCollector;
import com.aliyun.odps.udf.annotation.Resolve;
import com.aliyun.odps.udf.UDFException;
// Custom Java class.
//@Resolve annotation.
@Resolve("string,bigint->string,bigint")
public class MyUDTF extends UDTF {     
     // Implement the methods of the Java class.
     @Override
     public void process(Object[] args) throws UDFException {
         String a = (String) args[0];
         Long b = (Long) args[1];
         for (String t: a.split("\\s+")) {
         forward(t, b);
       }
     }
   }

Limitaciones

  • Acceso a Internet: Las UDF no tienen acceso a Internet de forma predeterminada. Para habilitar el acceso a Internet, complete el formulario de solicitud de conexión de red. Tras la aprobación, el equipo de soporte técnico de MaxCompute se pondrá en contacto con usted para establecer la conexión. Para obtener más detalles, consulte Network connection process.

  • No se permiten otras columnas en la misma instrucción SELECT: Una instrucción SELECT que invoque una UDTF no puede hacer referencia a otras columnas ni expresiones. La siguiente instrucción no es válida:

    -- Invalid: mixes a UDTF with another column
    select value, user_udtf(key) as mycol ...
  • No se permite anidamiento: Las UDTF no se pueden anidar dentro de otras UDTF. La siguiente instrucción no es válida:

    -- Invalid: user_udtf2 is nested inside user_udtf1
    select user_udtf1(user_udtf2(key)) as mycol...;
  • Incompatibilidad con GROUP BY, DISTRIBUTE BY y SORT BY: Una UDTF no puede aparecer en la misma instrucción SELECT que estas cláusulas. La siguiente instrucción no es válida:

    -- Invalid: UDTF used with GROUP BY
    select user_udtf(key) as mycol ... group by mycol;

Consideraciones

Al escribir una UDTF de Java, tenga en cuenta lo siguiente:

  • Evite definir clases con el mismo nombre pero diferente lógica de implementación en distintos paquetes JAR de UDTF. Por ejemplo, suponga que UDTF1 y UDTF2 corresponden a los recursos de paquetes JAR udtf1.jar y udtf2.jar, respectivamente. Si ambos paquetes JAR contienen una clase llamada com.aliyun.UserFunction.class con lógicas diferentes, MaxCompute cargará aleatoriamente una de las clases cuando se invoquen UDTF1 y UDTF2 en la misma instrucción SQL. Esto puede provocar resultados inesperados o fallos de compilación.

  • Los parámetros de entrada y los valores de retorno deben usar tipos de objeto de Java, como String y Long, en lugar de tipos primitivos.

  • Esto se debe a que los valores NULL de SQL se pasan como null de Java, lo cual no puede representarse con tipos primitivos.

Anotación @Resolve

El formato de la anotación @Resolve es el siguiente.

@Resolve(<signature>)

La cadena signature especifica los tipos de datos de los parámetros de entrada y los valores de retorno de la UDTF. Durante el análisis de la consulta, MaxCompute valida las invocaciones con base en esta firma y reporta un error si detecta una discrepancia de tipos. El formato es el siguiente.

'arg_type_list -> type_list'

Donde:

  • type_list: representa los tipos de datos de los valores de retorno. Una UDTF puede devolver varias columnas. Los tipos de datos compatibles son BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), tipos de datos complejos (ARRAY, MAP, STRUCT) y tipos de datos complejos anidados.

  • arg_type_list: representa los tipos de datos de los parámetros de entrada. Se pueden especificar varios parámetros de entrada separados por comas (,). Los tipos de datos compatibles son BIGINT, STRING, DOUBLE, BOOLEAN, DATETIME, DECIMAL, FLOAT, BINARY, DATE, DECIMAL(precision,scale), CHAR, VARCHAR, tipos de datos complejos (ARRAY, MAP, STRUCT) y tipos de datos complejos anidados.

    arg_type_list también admite un asterisco (*) o una cadena vacía ('').

    • Si arg_type_list es un asterisco (*), indica que la función acepta cualquier cantidad de parámetros de entrada.

    • Si arg_type_list es una cadena vacía (''), indica que la función no tiene parámetros de entrada.

    Para obtener más información sobre la sintaxis extendida de la anotación Resolve, consulte Dynamic parameters for UDAFs and UDTFs.

La siguiente tabla muestra ejemplos de anotaciones @Resolve válidas.

Ejemplo

Descripción

@Resolve('bigint,boolean->string,datetime')

Los tipos de los parámetros de entrada son BIGINT y BOOLEAN. Los tipos de los valores de retorno son STRING y DATETIME.

@Resolve('*->string, datetime')

La función acepta cualquier cantidad de parámetros de entrada. Los tipos de los valores de retorno son STRING y DATETIME.

@Resolve('->double, bigint, string')

La función no tiene parámetros de entrada. Los tipos de los valores de retorno son DOUBLE, BIGINT y STRING.

@Resolve("array<string>,struct<a1:bigint,b1:string>,string->map<string,bigint>,struct<b1:bigint>")

Los tipos de los parámetros de entrada son ARRAY, STRUCT y STRING. Los tipos de los valores de retorno son MAP y STRUCT.

Tipos de datos

Los tipos de datos compatibles con MaxCompute varían según la edición de tipos de datos. A partir de MaxCompute 2.0, hay tipos de datos adicionales disponibles, incluidos tipos complejos como ARRAY, MAP y STRUCT. Para obtener más información, consulte Data type editions.

Al escribir una UDTF de Java, asegúrese de que los tipos de datos que utilice se asignen correctamente a los compatibles con MaxCompute. La siguiente tabla describe estas asignaciones.

Tipo de MaxCompute

Tipo de Java

Tipo Writable de Java

TINYINT

java.lang.Byte

ByteWritable

SMALLINT

java.lang.Short

ShortWritable

INT

java.lang.Integer

IntWritable

BIGINT

java.lang.Long

LongWritable

FLOAT

java.lang.Float

FloatWritable

DOUBLE

java.lang.Double

DoubleWritable

DECIMAL

java.math.BigDecimal

BigDecimalWritable

BOOLEAN

java.lang.Boolean

BooleanWritable

STRING

java.lang.String

Text

VARCHAR

com.aliyun.odps.data.Varchar

VarcharWritable

BINARY

com.aliyun.odps.data.Binary

BytesWritable

DATE

java.sql.Date

DateWritable

DATETIME

java.util.Date

DatetimeWritable

TIMESTAMP

java.sql.Timestamp

TimestampWritable

INTERVAL_YEAR_MONTH

N/A

IntervalYearMonthWritable

INTERVAL_DAY_TIME

N/A

IntervalDayTimeWritable

ARRAY

java.util.List

N/A

MAP

java.util.Map

N/A

STRUCT

com.aliyun.odps.data.Struct

N/A

Nota

Para usar tipos Writable de Java en los valores de entrada o retorno de la UDTF, su proyecto de MaxCompute debe utilizar la edición de tipos de datos de MaxCompute 2.0.

Uso

Después de desarrollar una UDTF de Java siguiendo development process, puede invocarla en MaxCompute SQL.

  • Usar una UDF en un proyecto de MaxCompute: el método es similar al de usar built-in functions. Puede utilizar una función definida por el usuario de la misma manera que usa una función integrada.

  • Usar una UDF entre proyectos: utilice una UDF del Proyecto B en el Proyecto A. La siguiente instrucción muestra un ejemplo: select B:udf_in_other_project(arg0, arg1) as res from table_t;. Para obtener más información sobre el uso compartido entre proyectos, consulte Cross-project resource access based on packages.

Para obtener un tutorial completo sobre cómo desarrollar e invocar una UDTF de Java mediante MaxCompute Studio, consulte Usage example.

Ejemplo de uso

El siguiente procedimiento le guía paso a paso para desarrollar e invocar una UDTF de Java mediante MaxCompute Studio:

  1. Prepare el entorno.

    Antes de poder desarrollar y depurar una UDF en MaxCompute Studio, instale MaxCompute Studio y conéctelo a un proyecto de MaxCompute. Para obtener más información, consulte los siguientes temas:

    1. Install MaxCompute Studio

    2. Connect to a MaxCompute project

    3. Create a MaxCompute Java module

  2. Escriba el código de la UDTF.

    1. En el explorador Project, haga clic con el botón derecho en el directorio de código fuente del módulo (src > main > java) y seleccione New > MaxCompute Java.

    2. En el cuadro de diálogo Create new MaxCompute java class, haga clic en UDTF, introduzca un Name y presione Enter. Por ejemplo, asigne el nombre MyUDTF a la clase de Java.

      Name es el nombre de la clase de Java de MaxCompute que se va a crear. Si aún no se ha creado un paquete, puede introducir packagename.classname aquí para generar automáticamente un paquete.

    3. En el editor de código, introduzca el siguiente código. Este es un ejemplo de código de UDTF.

      package org.alidata.odps.udtf.examples;
      import com.aliyun.odps.udf.UDTF;
      import com.aliyun.odps.udf.UDTFCollector;
      import com.aliyun.odps.udf.annotation.Resolve;
      import com.aliyun.odps.udf.UDFException;
      // TODO define input and output types, e.g., "string,string->string,bigint".
         @Resolve("string,bigint->string,bigint")
         public class MyUDTF extends UDTF {
           @Override
           public void process(Object[] args) throws UDFException {
             String a = (String) args[0];
             Long b = (Long) args[1];
             for (String t: a.split("\\s+")) {
               forward(t, b);
             }
           }
         }
  3. Ejecute y depure la UDTF localmente para asegurar que el código funcione como se espera.

    Para obtener más información sobre la depuración, consulte Run and debug a UDF locally.

    Haga clic con el botón derecho en el archivo MyUDTF en el árbol del proyecto y seleccione Run 'MyUDTF.main()'. En el cuadro de diálogo Run/Debug Configurations, establezca MaxCompute project en local, MaxCompute table en wc_in2, Table partition en p2=1,p1=2, Table columns en colc,colb, Download Record limit en 100 y Data Column Separator en |. Luego, haga clic en OK.

    Nota

    Puede usar los parámetros anteriores para la ejecución de ejemplo.

  4. Empaquete la UDTF en un paquete JAR, cárguelo en su proyecto de MaxCompute y registre la función. Para este ejemplo, asigne el nombre user_udtf a la función.

    Para obtener más información sobre el empaquetado, consulte Procedure.

    En el árbol del proyecto de IntelliJ IDEA, haga clic con el botón derecho en el archivo Java de la UDTF (por ejemplo, MyUDTF) y seleccione Deploy to server.... En el cuadro de diálogo Package a jar, submit resource and register function, seleccione el MaxCompute project de destino, confirme la ruta del Resource file, establezca Main class en la clase UDTF correspondiente (por ejemplo, org.alidata.odps.udtf.examples.MyUDTF), introduzca user_udtf en Function name, seleccione Force update if already exists y haga clic en OK para completar el despliegue.

  5. En el panel de navegación izquierdo de MaxCompute Studio, haga clic en Project Explorer. Haga clic con el botón derecho en el proyecto de MaxCompute de destino, inicie el cliente de MaxCompute y ejecute un comando SQL para invocar la UDTF recién creada.

    Suponga que la tabla de destino, my_table, contiene los siguientes datos:

    +------------+------------+
    | col0       | col1       |
    +------------+------------+
    | A B        | 1          |
    | C D        | 2          |
    +------------+------------+

    Ejecute el siguiente comando SQL para invocar la UDTF.

    select user_udtf(col0, col1) as (c0, c1) from my_table;

    Se devuelve el siguiente resultado.

    +----+------------+
    | c0 | c1         |
    +----+------------+
    | A  | 1          |
    | B  | 1          |
    | C  | 2          |
    | D  | 2          |
    +----+------------+

Documentación relacionada

Para obtener más ejemplos de uso de UDTF de Java, consulte Java UDTF examples.