跳转至

Java SDK

The Java SDK for compute modules enables you to build deployed functions that integrate with Foundry. The SDK provides a builder pattern for function registration, authentication helpers, structured logging, and utilities for working with Foundry resources.

The Java SDK provides these key classes from the com.palantir.computemodules package:

Class/Package Purpose
ComputeModule Builder pattern for creating and starting modules
functions.Context Context object passed to every function (metadata, credentials)
auth.PipelinesAuth Retrieve pipeline tokens for Pipeline mode
auth.RefreshingOauthToken Auto-refreshing OAuth token wrapper for application permissions

Defining functions

ComputeModule builder

The ComputeModule builder is the main way to create and register functions:

import com.palantir.computemodules.ComputeModule;
import com.palantir.computemodules.functions.Context;

public class App {
    public static void main(String[] args) {
        ComputeModule.builder()
                .add(App::hello, String.class, String.class, "hello")
                .add(App::goodbye, Payload.class, Integer.class, "goodbye")
                .build()
                .start();
    }

    record Payload(String name) {}

    static String hello(Context context, String name) {
        return "Hello, " + name;
    }

    static Integer goodbye(Context context, Payload payload) {
        return payload.name.length();
    }
}

The .add() method parameters:

  1. Function reference (App::hello): Reference to the function to call
  2. Input type (String.class): Matches the second parameter type
  3. Output type (String.class): Matches the return type
  4. Endpoint name ("hello"): Public name for invoking the function

:::callout{theme="warning"} Important: Every function must receive Context as the first parameter and your payload type as the second parameter. :::

Defining input/output types

Java Records (recommended):

Records provide a concise way to define immutable data types:

public record Car(String brand, int doors) {}

public record CalculateInput(double x, double y, String operation) {}

public record CalculateOutput(double result, String operation) {}

Classes with @JsonProperty Annotations:

For more complex scenarios, use classes with Jackson annotations:

import com.fasterxml.jackson.annotation.JsonProperty;

public static class Car {
    @JsonProperty("brand")
    private String brand;

    @JsonProperty("doors")
    private int doors;

    Car() {} // Required for Jackson deserialization

    public String brand() { return brand; }
    public int doors() { return doors; }
}

Learn more about type systems and schema inference.

Authentication

Pipeline mode token

For Pipeline mode, retrieve the build2 token:

import com.palantir.computemodules.auth.PipelinesAuth;

String token = PipelinesAuth.retrievePipelineToken();

Application permissions (3PA)

Use RefreshingOauthToken to access Foundry resources with automatically refreshing tokens:

import com.palantir.computemodules.auth.RefreshingOauthToken;

String HOSTNAME = "myenrollment.palantirfoundry.com";

RefreshingOauthToken refreshingToken = new RefreshingOauthToken(
    HOSTNAME,
    List.of("api:datasets-read", "api:datasets-write")
);

// Token automatically refreshes before expiry
String token = refreshingToken.getToken();

The RefreshingOauthToken wrapper automatically handles token refreshing, ensuring your tokens remain valid throughout long-running operations.

Learn more about authentication modes.

Working with Foundry resources

Using the Ontology SDK (OSDK)

The Java SDK integrates with the Ontology SDK for working with Ontology objects. First, generate an OSDK for Java in Developer Console, then:

import com.palantir.computemodules.client.config.EnvVars;
import com.palantir.foundry.your_osdk_package.FoundryClient;
import com.palantir.foundry.your_osdk_package.objects.Employee;
import com.palantir.osdk.api.Auth;
import com.palantir.osdk.api.auth.ConfidentialClientAuth;
import com.palantir.osdk.internal.api.FoundryConnectionConfig;
import java.util.List;

static String returnObject() {
    Auth auth = ConfidentialClientAuth.builder()
            .clientId(EnvVars.Reserved.CLIENT_ID.get())
            .clientSecret(EnvVars.Reserved.CLIENT_SECRET.get())
            .build();

    FoundryClient client = FoundryClient.builder()
            .auth(auth)
            .connectionConfig(FoundryConnectionConfig.builder()
                    .foundryUri("https://" + System.getenv("FOUNDRY_URL"))
                    .build())
            .build();

    List<Employee> objects = client.ontology().objects().Employee().fetchStream().toList();
    return objects.get(0).toString();
}

:::callout{theme="neutral"} The CLIENT_ID and CLIENT_SECRET environment variables are automatically set when using application permissions. You can access them using EnvVars.Reserved.CLIENT_ID.get() and EnvVars.Reserved.CLIENT_SECRET.get(), or directly with System.getenv(). :::

Learn more about OSDK integration.

Logging

The SDK automatically configures logging when start() is called. It outputs to STDOUT using SLS (service.1) JSON layout and automatically includes session_id, job_id, and pid in every log line.

Use SafeLogger for structured, secure logging:

import com.palantir.logsafe.SafeArg;
import com.palantir.logsafe.logger.SafeLogger;
import com.palantir.logsafe.logger.SafeLoggerFactory;

public class App {
    private static final SafeLogger log = SafeLoggerFactory.get(App.class);

    static String hello(Context context, String name) {
        log.info("Greeting user", SafeArg.of("name", name));
        return "Hello, " + name;
    }

    static Integer calculate(Context context, CalculateInput input) {
        log.debug("Starting calculation",
                  SafeArg.of("operation", input.operation()),
                  SafeArg.of("x", input.x()),
                  SafeArg.of("y", input.y()));

        try {
            int result = performCalculation(input);
            log.info("Calculation successful", SafeArg.of("result", result));
            return result;
        } catch (Exception e) {
            log.error("Calculation failed", e);
            throw e;
        }
    }
}

Learn more about debugging and viewing logs.

Important configuration

If you are using an old version of the Java SDK with DeployedAppRuntime instead of ComputeModule as the main class, navigate to the Configure tab and ensure the Include runtime option is turned OFF. This is required for Java compute modules with DeployedAppRuntime to function correctly.

GitHub repository

The Java SDK is open source and available on GitHub:


中文翻译

Java SDK

Java SDK(Java 软件开发工具包)用于计算模块,使您能够构建与 Foundry 集成的已部署函数。该 SDK 提供了用于函数注册的构建器模式、身份验证辅助工具、结构化日志记录以及与 Foundry 资源交互的实用程序。

Java SDK 从 com.palantir.computemodules 包中提供以下关键类:

类/包 用途
ComputeModule 用于创建和启动模块的构建器模式
functions.Context 传递给每个函数的上下文对象(元数据、凭据)
auth.PipelinesAuth 为 Pipeline 模式检索管道令牌
auth.RefreshingOauthToken 用于应用程序权限的自动刷新 OAuth 令牌包装器

定义函数

ComputeModule 构建器

ComputeModule 构建器是创建和注册函数的主要方式:

import com.palantir.computemodules.ComputeModule;
import com.palantir.computemodules.functions.Context;

public class App {
    public static void main(String[] args) {
        ComputeModule.builder()
                .add(App::hello, String.class, String.class, "hello")
                .add(App::goodbye, Payload.class, Integer.class, "goodbye")
                .build()
                .start();
    }

    record Payload(String name) {}

    static String hello(Context context, String name) {
        return "Hello, " + name;
    }

    static Integer goodbye(Context context, Payload payload) {
        return payload.name.length();
    }
}

.add() 方法的参数:

  1. 函数引用(App::hello): 要调用的函数的引用
  2. 输入类型(String.class): 与第二个参数类型匹配
  3. 输出类型(String.class): 与返回类型匹配
  4. 端点名称("hello"): 用于调用函数的公开名称

:::callout{theme="warning"} 重要提示: 每个函数必须将 Context 作为第一个参数,将您的负载类型作为第二个参数。 :::

定义输入/输出类型

Java 记录(推荐):

记录提供了一种定义不可变数据类型的简洁方式:

public record Car(String brand, int doors) {}

public record CalculateInput(double x, double y, String operation) {}

public record CalculateOutput(double result, String operation) {}

带有 @JsonProperty 注解的类:

对于更复杂的场景,请使用带有 Jackson 注解的类:

import com.fasterxml.jackson.annotation.JsonProperty;

public static class Car {
    @JsonProperty("brand")
    private String brand;

    @JsonProperty("doors")
    private int doors;

    Car() {} // Jackson 反序列化所需

    public String brand() { return brand; }
    public int doors() { return doors; }
}

了解更多关于类型系统和模式推断的信息。

身份验证

Pipeline 模式令牌

对于 Pipeline 模式,检索 build2 令牌:

import com.palantir.computemodules.auth.PipelinesAuth;

String token = PipelinesAuth.retrievePipelineToken();

应用程序权限(3PA)

使用 RefreshingOauthToken 通过自动刷新令牌访问 Foundry 资源:

import com.palantir.computemodules.auth.RefreshingOauthToken;

String HOSTNAME = "myenrollment.palantirfoundry.com";

RefreshingOauthToken refreshingToken = new RefreshingOauthToken(
    HOSTNAME,
    List.of("api:datasets-read", "api:datasets-write")
);

// 令牌在过期前自动刷新
String token = refreshingToken.getToken();

RefreshingOauthToken 包装器会自动处理令牌刷新,确保您的令牌在长时间运行的操作中保持有效。

了解更多关于身份验证模式的信息。

使用 Foundry 资源

使用 Ontology SDK(OSDK)

Java SDK 与 Ontology SDK 集成,用于处理 Ontology 对象。首先,在开发者控制台中为 Java 生成 OSDK,然后:

import com.palantir.computemodules.client.config.EnvVars;
import com.palantir.foundry.your_osdk_package.FoundryClient;
import com.palantir.foundry.your_osdk_package.objects.Employee;
import com.palantir.osdk.api.Auth;
import com.palantir.osdk.api.auth.ConfidentialClientAuth;
import com.palantir.osdk.internal.api.FoundryConnectionConfig;
import java.util.List;

static String returnObject() {
    Auth auth = ConfidentialClientAuth.builder()
            .clientId(EnvVars.Reserved.CLIENT_ID.get())
            .clientSecret(EnvVars.Reserved.CLIENT_SECRET.get())
            .build();

    FoundryClient client = FoundryClient.builder()
            .auth(auth)
            .connectionConfig(FoundryConnectionConfig.builder()
                    .foundryUri("https://" + System.getenv("FOUNDRY_URL"))
                    .build())
            .build();

    List<Employee> objects = client.ontology().objects().Employee().fetchStream().toList();
    return objects.get(0).toString();
}

:::callout{theme="neutral"} 当使用应用程序权限时,CLIENT_IDCLIENT_SECRET 环境变量会自动设置。您可以使用 EnvVars.Reserved.CLIENT_ID.get()EnvVars.Reserved.CLIENT_SECRET.get() 访问它们,或者直接使用 System.getenv()。 :::

了解更多关于 OSDK 集成的信息。

日志记录

当调用 start() 时,SDK 会自动配置日志记录。它使用 SLS(service.1)JSON 布局输出到 STDOUT,并自动在每个日志行中包含 session_idjob_idpid

使用 SafeLogger(推荐)

使用 SafeLogger 进行结构化、安全的日志记录:

import com.palantir.logsafe.SafeArg;
import com.palantir.logsafe.logger.SafeLogger;
import com.palantir.logsafe.logger.SafeLoggerFactory;

public class App {
    private static final SafeLogger log = SafeLoggerFactory.get(App.class);

    static String hello(Context context, String name) {
        log.info("Greeting user", SafeArg.of("name", name));
        return "Hello, " + name;
    }

    static Integer calculate(Context context, CalculateInput input) {
        log.debug("Starting calculation",
                  SafeArg.of("operation", input.operation()),
                  SafeArg.of("x", input.x()),
                  SafeArg.of("y", input.y()));

        try {
            int result = performCalculation(input);
            log.info("Calculation successful", SafeArg.of("result", result));
            return result;
        } catch (Exception e) {
            log.error("Calculation failed", e);
            throw e;
        }
    }
}

了解更多关于调试和查看日志的信息。

重要配置

如果您使用的是旧版 Java SDK,且主类为 DeployedAppRuntime 而非 ComputeModule,请导航到 Configure 选项卡,确保 Include runtime 选项处于 关闭 状态。这对于使用 DeployedAppRuntime 的 Java 计算模块正常运行是必需的。

GitHub 仓库

Java SDK 是开源的,可在 GitHub 上获取: