Todos os produtos
Search
Central de documentação

MaxCompute:Desenvolvimento de UDFs em Java

Última atualização: Jun 26, 2026

Se as funções integradas do MaxCompute não atenderem às suas necessidades, use o fluxo de trabalho descrito neste tópico para criar uma função definida pelo usuário (UDF) em ferramentas de desenvolvimento como IntelliJ IDEA (Maven) ou MaxCompute Studio. Em seguida, chame a UDF no MaxCompute para dar suporte a diversos casos de uso. Este tópico descreve como escrever uma UDF em Java.

Limites rígidos

Acesso à Internet — Por padrão, as UDFs não têm acesso à Internet. Para ative esse acesso, envie uma solicitação de conexão de rede. Após a aprovação, a equipe de suporte técnico do MaxCompute entrará em contato para estabelecer a conexão. Para mais detalhes, consulte Network Connection Request FormProcesso de conexão de rede.

Acesso à VPC — As UDFs não acessam recursos em uma virtual private cloud (VPC) por padrão. Para permitir o acesso à VPC, estabeleça uma conexão de rede entre o MaxCompute e a VPC. Para mais detalhes, consulte Usar UDFs para acessar recursos em VPCs.

Tipos de tabela não suportados — UDFs, UDAFs e UDTFs não leem dados dos seguintes tipos de tabela:

  • Tabelas com evolução de schema

  • Tabelas com tipos de dados complexos

  • Tabelas com tipos de dados JSON

  • Tabelas transacionais

Observações de uso

Antes de escrever uma UDF em Java, compreenda a estrutura do código da UDF e os mapeamentos entre os tipos de dados da UDF Java e os do MaxCompute. Para obter mais informações sobre esses mapeamentos, consulte Apêndice: Tipos de dados.

Ao desenvolver sua UDF em Java, observe os pontos abaixo:

  • Evite incluir classes com o mesmo nome, mas lógicas diferentes, em arquivos JAR de UDF distintos. Por exemplo, suponha que UDF1 e UDF2 correspondam aos arquivos de recurso udf1.jar e udf2.jar, e ambos contenham uma classe chamada com.aliyun.UserFunction.class, porém com implementações diferentes. Se você chamar UDF1 e UDF2 na mesma instrução SQL, o MaxCompute carregará aleatoriamente uma das classes. Isso pode gerar resultados de execução inesperados ou até falhas de compilação.

  • Em uma UDF Java, os tipos de dados dos parâmetros de entrada e dos valores de retorno devem ser tipos de objeto (por exemplo, String, Long), e não tipos primitivos (como int, long).

  • Valores NULL no SQL são mapeados como NULL em Java. Tipos primitivos do Java não representam valores NULL do SQL e, portanto, não são permitidos.

Fluxo de trabalho de desenvolvimento de UDF

O desenvolvimento de uma UDF envolve várias etapas: preparação do ambiente, escrita do código, upload do arquivo JAR, registro da função e depuração. As seções a seguir demonstram esse fluxo usando MaxCompute Studio, DataWorks e odpscmd.

Uso do MaxCompute Studio

O exemplo a seguir mostra como desenvolver e chamar uma UDF em Java que converte caracteres para minúsculas no MaxCompute Studio.

  1. Prepare o ambiente.

    Para desenvolver e depurar uma UDF no MaxCompute Studio, instale o MaxCompute Studio e conecte-o a um projeto do MaxCompute. Para mais informações, consulte os tópicos a seguir:

    1. Instalar o MaxCompute Studio

    2. Conectar a um projeto do MaxCompute

    3. Criar um módulo Java do MaxCompute

  2. Escreva o código da UDF.

    1. No explorador Project, clique em com o botão direito no diretório de source code do módulo (src > main > java) e selecione New > MaxCompute Java.新建Java Class

    2. Na caixa de diálogo Create new MaxCompute java class, clique em UDF, insira o nome da classe no campo Name e pressione Enter.

      选择类型填写名称

      O campo Name define o nome da MaxCompute Java Class a ser criada. Caso ainda não tenha criado um pacote, insira packagename.classname para criá-lo automaticamente. Neste exemplo, a Java Class recebe o nome Lower.

    3. Desenvolva o código da UDF no editor. 代码编辑区域 Exemplo:

      package com.aliyun.odps.udf.example;
      import com.aliyun.odps.udf.UDF;
      public final class Lower extends UDF {
          public String evaluate(String s) {
              if (s == null) { 
                 return null; 
              }
                 return s.toLowerCase();
          }
      }
      Nota

      Para depurar a UDF Java localmente, consulte Desenvolver e depurar UDFs.

  3. Faça o upload e registre a UDF.

    Clique em com o botão direito no arquivo Java da UDF e selecione Deploy to server.... Na caixa de diálogo Package a jar, submit resource and register function, configure os parâmetros e clique em OK.注册UDF

    • MaxCompute project: Nome do projeto do MaxCompute ao qual a UDF pertence. Como a UDF foi escrita no projeto conectado, mantenha o valor padrão.

    • Resource file: Caminho do arquivo de recurso do qual a UDF depende. Mantenha o valor padrão.

    • Resource name: Recurso necessário para a UDF. Mantenha o valor padrão.

    • Function name: Nome usado para chamar a UDF nas instruções SQL. Exemplo: Lower_test.

  4. Depure a UDF.

    No painel de navegação à esquerda, clique em Project Explore. Clique em com o botão direito no projeto do MaxCompute desejado e selecione Open Console. No console, insira a instrução SQL que chama a UDF e pressione Enter para executá-la. 调用UDF Exemplo:

    select lower_test('ABC');

    O resultado retornado será semelhante ao seguinte:

    +-----+
    | _c0 |
    +-----+
    | abc |
    +-----+

Uso do DataWorks

  1. Prepare o ambiente.

    Para desenvolver e depurar uma UDF no DataWorks, ative o serviço e vincule um projeto do MaxCompute a ele. Para mais informações, consulte Usar o DataWorks.

  2. Escreva o código da UDF.

    Use qualquer ferramenta de desenvolvimento Java para escrever o código e empacotá-lo em um arquivo JAR. Exemplo:

    package com.aliyun.odps.udf.example;
    import com.aliyun.odps.udf.UDF;
    public final class Lower extends UDF {
        public String evaluate(String s) {
            if (s == null) { 
               return null; 
            }
               return s.toLowerCase();
        }
    }
  3. Faça o upload e registre a UDF.

    Envie o código empacotado para o DataWorks e registre a função. Para mais detalhes, veja os tópicos abaixo:

    1. Criar e usar recursos do MaxCompute

    2. Criar e usar uma função do MaxCompute

  4. Depure a UDF.

    Após registrar a UDF, crie um nó ODPS SQL e execute um comando SQL nesse nó para depurá-la. Para saber como criar um nó ODPS SQL, consulte Criar um nó ODPS SQL. Abaixo está um exemplo de comando de depuração.

    select lower_test('ABC');

Uso do odpscmd

  1. Prepare o ambiente.

    Para desenvolver e depurar uma UDF com o odpscmd, instale o cliente e configure sua conexão com um projeto do MaxCompute. Para mais informações, consulte Usar o cliente do MaxCompute (odpscmd).

  2. Escreva o código da UDF.

    Use qualquer ferramenta de desenvolvimento Java para escrever o código e empacotá-lo em um arquivo JAR. Exemplo:

    package com.aliyun.odps.udf.example;
    import com.aliyun.odps.udf.UDF;
    public final class Lower extends UDF {
        public String evaluate(String s) {
            if (s == null) { 
               return null; 
            }
               return s.toLowerCase();
        }
    }
  3. Faça o upload e registre a UDF.

    Use o odpscmd para enviar o código empacotado e registrar a função. Consulte os tópicos a seguir para mais detalhes:

    1. ADD JAR

    2. CREATE FUNCTION

  4. Depure a UDF.

    Depois de registrar a UDF, escreva e execute um comando SQL para testá-la. Veja abaixo um exemplo de comando de depuração.

    select lower_test('ABC');

Chamada de UDFs

Após desenvolver uma UDF em Java conforme descrito no Fluxo de trabalho de desenvolvimento de UDF anterior, chame-a no MaxCompute SQL. Os métodos disponíveis são:

  • Dentro de um projeto — Chame a UDF diretamente, assim como qualquer função integrada.

  • Entre projetos — Para usar uma UDF do projeto B dentro do projeto A, referencie-a com o prefixo do projeto:

    select B:udf_in_other_project(arg0, arg1) as res from table_t;

    Para configurar o compartilhamento entre projetos, consulte Acesso a recursos entre projetos baseado em pacotes.

Exemplos de UDF

Apêndice: Estrutura do código da UDF

Uma UDF em Java é composta pelas seguintes partes:

  • Pacote Java: Opcional.

    Agrupe suas classes Java em um pacote para facilitar a localização e a reutilização.

  • Herança da classe UDF: Obrigatória.

    A classe base necessária é com.aliyun.odps.udf.UDF. Se precisar de outras classes de UDF ou tipos de dados complexos, adicione as classes correspondentes do SDK do MaxCompute. Por exemplo, a classe para o tipo de dados STRUCT é com.aliyun.odps.data.Struct.

  • Anotação @Resolve: Opcional.

    O formato é @Resolve(<signature>), onde signature define os tipos de dados dos parâmetros de entrada e do valor de retorno. Ao usar o tipo STRUCT em uma UDF, a reflexão não recupera nomes e tipos de campos de com.aliyun.odps.data.Struct. Nesse cenário, use a anotação @Resolve para obtê-los. Se a UDF usar STRUCT, adicione a anotação @Resolve à classe da UDF. Essa anotação afeta apenas as sobrecargas cujos parâmetros ou valores de retorno contenham com.aliyun.odps.data.Struct. Exemplo: @Resolve("struct<a:string>,string->string"). Para um exemplo detalhado, consulte Exemplo de UDF: Tipos de Dados Complexos.

  • Classe Java personalizada: Obrigatória.

    Representa a unidade que organiza o código da UDF, definindo variáveis e métodos que implementam a lógica de negócio.

  • Método evaluate: Obrigatório.

    Sua classe Java personalizada deve incluir um método evaluate público e não estático. Os tipos de dados de seus parâmetros de entrada e valor de retorno definem a assinatura SQL da UDF.

    É possível implementar múltiplos métodos evaluate. Durante a chamada da UDF, o MaxCompute seleciona o método evaluate correto com base nos tipos dos argumentos.

    Ao escrever uma UDF em Java, use tipos Java ou tipos Java Writable. Para ver os mapeamentos detalhados entre tipos de dados do MaxCompute e Java, consulte Apêndice: Tipos de dados.

  • Inicialização e limpeza da UDF: Opcional. Implemente essas rotinas usando void setup(ExecutionContext ctx) e void close(). O método void setup(ExecutionContext ctx) é chamado uma única vez antes do método evaluate e serve para inicializar recursos ou objetos membros necessários à computação. Já o método void close() é executado uma vez após todas as chamadas ao evaluate serem concluídas e serve para tarefas de limpeza, como fechar arquivos.

Os exemplos abaixo ilustram dois tipos de UDFs.

  • Uso de tipos Java

    // Organize the Java class in the org.alidata.odps.udf.examples package.
    package org.alidata.odps.udf.examples;  
    // Inherit the UDF class.
    import com.aliyun.odps.udf.UDF;         
    // Define a custom Java class.
    public final class Lower extends UDF { 
    // The evaluate method defines the UDF's logic. It takes a String and returns a String.
        public String evaluate(String s) { 
            if (s == null) { 
            return null; 
        } 
            return s.toLowerCase(); 
      } 
    }
  • Uso de tipos Java Writable

    // Organize the Java class in the com.aliyun.odps.udf.example package.
    package com.aliyun.odps.udf.example;
    // Add the required classes for the Java Writable type.
    import com.aliyun.odps.io.Text;
    // Inherit the UDF class.
    import com.aliyun.odps.udf.UDF;
    // Define a custom Java class.
    public class MyConcat extends UDF {
      private Text ret = new Text();
    // Define the evaluate method. `Text` specifies the data type of the input parameters, and the `return` value is also a Text object.
      public Text evaluate(Text a, Text b) {
          if (a == null || b == null) {
          return null;
        }
          ret.clear();
          ret.append(a.getBytes(), 0, a.getLength());
          ret.append(b.getBytes(), 0, b.getLength());
          return ret;
      }
    }

O MaxCompute também suporta UDFs desenvolvidas para sua versão compatível com Hive. Para mais informações, consulte Compatibilidade com UDFs do Hive.

Apêndice: Tipos de dados

Mapeamentos de tipos de dados

Para garantir consistência entre os tipos usados em uma UDF Java e aqueles suportados pelo MaxCompute, use os mapeamentos a seguir.

Nota

Os tipos de dados suportados variam conforme a edição de tipos de dados do MaxCompute. A partir da versão 2.0, novos tipos foram adicionados, incluindo tipos complexos como ARRAY, MAP e STRUCT. Para mais detalhes sobre as edições de tipos de dados, consulte Edições de tipos de dados.

Tipo do MaxCompute

Tipo Java

Tipo Java Writable

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

O tipo Java byte[] não consta na lista de tipos suportados. Se você usar byte[] como parâmetro de entrada ou valor de retorno de um método evaluate, o erro ODPS-0130071 será reportado. Para processar dados binários em uma UDF, use os tipos Java correspondentes ao tipo BINARY do MaxCompute: com.aliyun.odps.data.Binary para o tipo Java padrão, ou com.aliyun.odps.io.BytesWritable para o tipo Writable. Alternativamente, converta os dados binários para uma string codificada em Base64 e use o tipo String como valor de retorno.

Compatibilidade com UDFs do Hive

Caso seu projeto do MaxCompute use a edição de tipos de dados 2.0, o sistema suporta UDFs no estilo Hive. Assim, é possível usar diretamente UDFs do Hive desenvolvidas em versões compatíveis com o MaxCompute.

A versão compatível do Hive é a 2.1.0, correspondente ao Hadoop 2.7.2. Se sua UDF foi compilada em uma versão diferente do Hive ou Hadoop, recompile o arquivo JAR usando Hive 2.1.0 ou Hadoop 2.7.2.

Para um exemplo detalhado de uso de UDFs do Hive no MaxCompute, consulte Exemplo de UDF: Compatibilidade com Hive.