pkl-executor: Migrate nullness to jSpecify (#1527)

Annotating SPI classes is binary compatible (forward and backward).
This commit is contained in:
odenix
2026-04-16 23:02:40 +01:00
committed by GitHub
parent 03a641354e
commit 8103b7759f
12 changed files with 143 additions and 102 deletions
+24 -3
View File
@@ -2,10 +2,28 @@
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.github.ben-manes.caffeine:caffeine:2.9.3=swiftExportClasspathResolvable
com.github.ben-manes.caffeine:caffeine:3.0.5=annotationProcessor,testAnnotationProcessor
com.github.kevinstern:software-and-algorithms:1.0=annotationProcessor,testAnnotationProcessor
com.google.auto.service:auto-service-annotations:1.0.1=annotationProcessor,testAnnotationProcessor
com.google.auto.value:auto-value-annotations:1.9=annotationProcessor,testAnnotationProcessor
com.google.auto:auto-common:1.2.2=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_annotation:2.48.0=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_annotations:2.28.0=swiftExportClasspathResolvable
io.github.java-diff-utils:java-diff-utils:4.12=kotlinInternalAbiValidation
com.google.errorprone:error_prone_annotations:2.48.0=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_check_api:2.48.0=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_core:2.48.0=annotationProcessor,testAnnotationProcessor
com.google.googlejavaformat:google-java-format:1.34.1=annotationProcessor,testAnnotationProcessor
com.google.guava:failureaccess:1.0.3=annotationProcessor,testAnnotationProcessor
com.google.guava:guava:33.5.0-jre=annotationProcessor,testAnnotationProcessor
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,testAnnotationProcessor
com.google.j2objc:j2objc-annotations:3.1=annotationProcessor,testAnnotationProcessor
com.google.protobuf:protobuf-java:4.33.2=annotationProcessor,testAnnotationProcessor
com.uber.nullaway:nullaway:0.13.1=annotationProcessor,testAnnotationProcessor
io.github.eisop:dataflow-errorprone:3.41.0-eisop1=annotationProcessor,testAnnotationProcessor
io.github.java-diff-utils:java-diff-utils:4.12=annotationProcessor,kotlinInternalAbiValidation,testAnnotationProcessor
io.opentelemetry:opentelemetry-api:1.41.0=swiftExportClasspathResolvable
io.opentelemetry:opentelemetry-context:1.41.0=swiftExportClasspathResolvable
javax.inject:javax.inject:1=annotationProcessor,testAnnotationProcessor
net.bytebuddy:byte-buddy:1.18.3=testCompileClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
org.assertj:assertj-core:3.27.7=testCompileClasspath,testRuntimeClasspath
@@ -14,6 +32,8 @@ org.bouncycastle:bcpkix-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcprov-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcutil-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.checkerframework:checker-qual:3.43.0=swiftExportClasspathResolvable
org.checkerframework:checker-qual:3.53.0=annotationProcessor,testAnnotationProcessor
org.checkerframework:dataflow-nullaway:3.53.0=annotationProcessor,testAnnotationProcessor
org.graalvm.polyglot:polyglot:25.0.1=testRuntimeClasspath
org.graalvm.sdk:collections:25.0.1=testRuntimeClasspath
org.graalvm.sdk:graal-sdk:25.0.1=testRuntimeClasspath
@@ -53,7 +73,7 @@ org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=swiftExportClasspathResolv
org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=swiftExportClasspathResolvable
org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath
org.jspecify:jspecify:1.0.0=testCompileClasspath,testRuntimeClasspath
org.jspecify:jspecify:1.0.0=annotationProcessor,compileClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:6.0.3=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:6.0.3=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:6.0.3=testCompileClasspath,testRuntimeClasspath
@@ -64,8 +84,9 @@ org.junit:junit-bom:6.0.3=testCompileClasspath,testRuntimeClasspath
org.msgpack:msgpack-core:0.9.11=testRuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath
org.organicdesign:Paguro:3.10.3=testRuntimeClasspath
org.pcollections:pcollections:4.0.1=annotationProcessor,testAnnotationProcessor
org.pkl-lang:pkl-config-java-all:0.25.0=pklHistoricalDistributions
org.slf4j:slf4j-api:2.0.17=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.slf4j:slf4j-simple:2.0.17=testCompileClasspath,testRuntimeClasspath
org.snakeyaml:snakeyaml-engine:2.10=testRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,pklDistributionCurrent,signatures,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
empty=apiDependenciesMetadata,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,pklDistributionCurrent,signatures,sourcesJar,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
+2 -1
View File
@@ -20,6 +20,7 @@ plugins {
id("pklAllProjects")
id("pklJavaLibrary")
id("pklPublishLibrary")
id("pklJSpecify")
}
val pklDistributionCurrent: Configuration by configurations.creating
@@ -31,7 +32,7 @@ val pklHistoricalDistributions: Configuration by configurations.creating
// (Pkl distributions used by EmbeddedExecutor are isolated via class loaders.)
dependencies {
pklDistributionCurrent(project(":pkl-config-java", "fatJar"))
@Suppress("UnstableApiUsage") pklHistoricalDistributions(libs.pklConfigJavaAll025)
pklHistoricalDistributions(libs.pklConfigJavaAll025)
implementation(libs.slf4jApi)
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import java.nio.file.Path;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.jspecify.annotations.Nullable;
import org.pkl.executor.spi.v1.ExecutorSpi;
import org.pkl.executor.spi.v1.ExecutorSpiException;
import org.slf4j.Logger;
@@ -60,8 +61,7 @@ final class EmbeddedExecutor implements Executor {
Version requestedVersion = null;
PklDistribution distribution = null;
String output = null;
RuntimeException exception = null;
String output;
try {
if (!Files.isRegularFile(modulePath)) {
@@ -76,29 +76,33 @@ final class EmbeddedExecutor implements Executor {
// (but not any modules imported by it) and only requires parsing (but not evaluating) the
// module.
requestedVersion = detectRequestedPklVersion(modulePath, options);
//noinspection resource
distribution = findCompatibleDistribution(modulePath, requestedVersion, options);
output = distribution.evaluatePath(modulePath, options);
} catch (RuntimeException e) {
exception = e;
// Could log exception, but this would violate "don't log and throw",
// and Pkl stack trace might contain semi-sensitive information.
logFinished(modulePath, false, requestedVersion, distribution, startTime, System.nanoTime());
throw e;
}
var endTime = System.nanoTime();
logFinished(modulePath, true, requestedVersion, distribution, startTime, System.nanoTime());
return output;
}
// Could log exception, but this would violate "don't log and throw",
// and Pkl stack trace might contain semi-sensitive information.
private static void logFinished(
Path modulePath,
boolean success,
@Nullable Version requestedVersion,
@Nullable PklDistribution distribution,
long startTime,
long endTime) {
logger.info(
"Finished evaluating Pkl module. modulePath={} outcome={} requestedVersion={} selectedVersion={} elapsedMillis={}",
modulePath,
exception == null ? "success" : "failure",
success,
requestedVersion == null ? "n/a" : requestedVersion.toString(),
distribution == null ? "n/a" : distribution.getVersion().toString(),
(endTime - startTime) / 1_000_000);
if (exception != null) throw exception;
assert output != null;
return output;
}
private Version detectRequestedPklVersion(Path modulePath, ExecutorOptions options) {
@@ -126,7 +130,7 @@ final class EmbeddedExecutor implements Executor {
toDisplayPath(modulePath, options), availableVersions));
}
/* @Nullable */ static Version extractMinPklVersion(String sourceText) {
static @Nullable Version extractMinPklVersion(String sourceText) {
var matcher = MODULE_INFO_PATTERN.matcher(sourceText);
return matcher.find() ? Version.parse(matcher.group(1)) : null;
}
@@ -177,7 +181,7 @@ final class EmbeddedExecutor implements Executor {
private static final class PklDistribution implements AutoCloseable {
final URLClassLoader pklDistributionClassLoader;
final /* @Nullable */ ExecutorSpi executorSpi;
final ExecutorSpi executorSpi;
final Version version;
/**
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,24 +16,26 @@
package org.pkl.executor;
import java.util.Objects;
import org.jspecify.annotations.Nullable;
/**
* Indicates an {@link Executor} error. {@link #getMessage()} returns a user-facing error message.
*/
public final class ExecutorException extends RuntimeException {
private final String pklVersion;
private final @Nullable String pklVersion;
public ExecutorException(String message) {
super(message);
pklVersion = null;
}
public ExecutorException(String message, Throwable cause) {
public ExecutorException(@Nullable String message, @Nullable Throwable cause) {
super(message, cause);
pklVersion = null;
}
public ExecutorException(String message, Throwable cause, String version) {
public ExecutorException(
@Nullable String message, @Nullable Throwable cause, @Nullable String version) {
super(message, cause);
pklVersion = Objects.requireNonNull(version);
}
@@ -43,12 +45,12 @@ public final class ExecutorException extends RuntimeException {
*
* <p>Returns {@code null} if this exception does not originate from an underlying Pkl evaluator.
*/
public String getPklVersion() {
public @Nullable String getPklVersion() {
return pklVersion;
}
@Override
public String getMessage() {
public @Nullable String getMessage() {
var message = super.getMessage();
if (pklVersion == null) {
return message;
@@ -1,5 +1,5 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.jspecify.annotations.Nullable;
import org.pkl.executor.spi.v1.ExecutorSpiOptions;
import org.pkl.executor.spi.v1.ExecutorSpiOptions2;
import org.pkl.executor.spi.v1.ExecutorSpiOptions3;
@@ -41,15 +42,15 @@ public final class ExecutorOptions {
private final List<Path> modulePath;
private final /* @Nullable */ Path rootDir;
private final @Nullable Path rootDir;
private final /* @Nullable */ Duration timeout;
private final @Nullable Duration timeout;
private final /* @Nullable */ String outputFormat;
private final @Nullable String outputFormat;
private final /* @Nullable */ Path moduleCacheDir;
private final @Nullable Path moduleCacheDir;
private final /* @Nullable */ Path projectDir;
private final @Nullable Path projectDir;
private final List<Path> certificateFiles;
@@ -81,11 +82,11 @@ public final class ExecutorOptions {
private Map<String, String> environmentVariables = Map.of();
private Map<String, String> externalProperties = Map.of();
private List<Path> modulePath = List.of();
private /* @Nullable */ Path rootDir;
private /* @Nullable */ Duration timeout;
private /* @Nullable */ String outputFormat;
private /* @Nullable */ Path moduleCacheDir;
private /* @Nullable */ Path projectDir;
private @Nullable Path rootDir;
private @Nullable Duration timeout;
private @Nullable String outputFormat;
private @Nullable Path moduleCacheDir;
private @Nullable Path projectDir;
private List<Path> certificateFiles = List.of();
private List<byte[]> certificateBytes = List.of();
private Map<URI, URI> httpRewrites = Map.of();
@@ -270,11 +271,11 @@ public final class ExecutorOptions {
Map<String, String> environmentVariables,
Map<String, String> externalProperties,
List<Path> modulePath,
/* @Nullable */ Path rootDir,
/* @Nullable */ Duration timeout,
/* @Nullable */ String outputFormat,
/* @Nullable */ Path moduleCacheDir,
/* @Nullable */ Path projectDir) {
@Nullable Path rootDir,
@Nullable Duration timeout,
@Nullable String outputFormat,
@Nullable Path moduleCacheDir,
@Nullable Path projectDir) {
this(
allowedModules,
@@ -300,11 +301,11 @@ public final class ExecutorOptions {
Map<String, String> environmentVariables,
Map<String, String> externalProperties,
List<Path> modulePath,
/* @Nullable */ Path rootDir,
/* @Nullable */ Duration timeout,
/* @Nullable */ String outputFormat,
/* @Nullable */ Path moduleCacheDir,
/* @Nullable */ Path projectDir,
@Nullable Path rootDir,
@Nullable Duration timeout,
@Nullable String outputFormat,
@Nullable Path moduleCacheDir,
@Nullable Path projectDir,
List<Path> certificateFiles,
List<byte[]> certificateBytes,
Map<URI, URI> httpRewrites,
@@ -354,17 +355,17 @@ public final class ExecutorOptions {
}
/** API equivalent of the {@code --root-dir} CLI option. */
public /* @Nullable */ Path getRootDir() {
public @Nullable Path getRootDir() {
return rootDir;
}
/** API equivalent of the {@code --timeout} CLI option. */
public Duration getTimeout() {
public @Nullable Duration getTimeout() {
return timeout;
}
/** API equivalent of the {@code --format} CLI option. */
public /* @Nullable */ String getOutputFormat() {
public @Nullable String getOutputFormat() {
return outputFormat;
}
@@ -372,7 +373,7 @@ public final class ExecutorOptions {
* API equivalent of the {@code --cache-dir} CLI option. {@code null} is equivalent to {@code
* --no-cache}.
*/
public /* @Nullable */ Path getModuleCacheDir() {
public @Nullable Path getModuleCacheDir() {
return moduleCacheDir;
}
@@ -382,7 +383,7 @@ public final class ExecutorOptions {
* <p>Unlike the CLI, this option only sets project dependencies. It does not set evaluator
* settings.
*/
public /* @Nullable */ Path getProjectDir() {
public @Nullable Path getProjectDir() {
return projectDir;
}
@@ -407,11 +408,10 @@ public final class ExecutorOptions {
}
@Override
public boolean equals(/* @Nullable */ Object obj) {
public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (obj.getClass() != ExecutorOptions.class) return false;
if (!(obj instanceof ExecutorOptions other)) return false;
var other = (ExecutorOptions) obj;
return allowedModules.equals(other.allowedModules)
&& allowedResources.equals(other.allowedResources)
&& environmentVariables.equals(other.environmentVariables)
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package org.pkl.executor;
import java.util.*;
import java.util.regex.Pattern;
import org.jspecify.annotations.Nullable;
/**
* A <a href="https://semver.org/spec/v2.0.0.html">semantic version</a>.
@@ -54,19 +55,15 @@ final class Version implements Comparable<Version> {
private final int major;
private final int minor;
private final int patch;
private final /*@Nullable*/ String preRelease;
private final /*@Nullable*/ String build;
private final @Nullable String preRelease;
private final @Nullable String build;
// always access through getter
private volatile Identifier[] __preReleaseIdentifiers;
private volatile Identifier @Nullable [] __preReleaseIdentifiers;
/** Constructs a semantic version. */
public Version(
int major,
int minor,
int patch,
/*@Nullable*/ String preRelease,
/*@Nullable*/ String build) {
int major, int minor, int patch, @Nullable String preRelease, @Nullable String build) {
this.major = major;
this.minor = minor;
this.patch = patch;
@@ -99,7 +96,7 @@ final class Version implements Comparable<Version> {
* <p>Returns {@code null} if the given string could not be parsed as a semantic version number or
* is too large to fit into a {@link Version}.
*/
public static /*@Nullable*/ Version parseOrNull(String version) {
public static @Nullable Version parseOrNull(String version) {
var matcher = VERSION.matcher(version);
if (!matcher.matches()) return null;
@@ -151,22 +148,22 @@ final class Version implements Comparable<Version> {
}
/** Returns the pre-release version (if any). */
public /*@Nullable*/ String getPreRelease() {
public @Nullable String getPreRelease() {
return preRelease;
}
/** Returns a copy of this version with the given pre-release version. */
public Version withPreRelease(/*@Nullable*/ String preRelease) {
public Version withPreRelease(@Nullable String preRelease) {
return new Version(major, minor, patch, preRelease, build);
}
/** Returns the build metadata (if any). */
public /*@Nullable*/ String getBuild() {
public @Nullable String getBuild() {
return build;
}
/** Returns a copy of this version with the given build metadata. */
public Version withBuild(/*@Nullable*/ String build) {
public Version withBuild(@Nullable String build) {
return new Version(major, minor, patch, preRelease, build);
}
@@ -196,7 +193,7 @@ final class Version implements Comparable<Version> {
/** Tells if this version is equal to {@code obj} according to semantic versioning rules. */
@Override
public boolean equals(/* @Nullable */ Object obj) {
public boolean equals(@Nullable Object obj) {
if (this == obj) return true;
if (!(obj instanceof Version other)) return false;
return major == other.major
@@ -222,8 +219,9 @@ final class Version implements Comparable<Version> {
}
private Identifier[] getPreReleaseIdentifiers() {
if (__preReleaseIdentifiers == null) {
__preReleaseIdentifiers =
var result = __preReleaseIdentifiers;
if (result == null) {
result =
preRelease == null
? new Identifier[0]
: Arrays.stream(preRelease.split("\\."))
@@ -233,11 +231,12 @@ final class Version implements Comparable<Version> {
? new Identifier(Long.parseLong(str), null)
: new Identifier(-1, str))
.toArray(Identifier[]::new);
__preReleaseIdentifiers = result;
}
return __preReleaseIdentifiers;
return result;
}
private record Identifier(long numericId, /*@Nullable*/ String alphanumericId)
private record Identifier(long numericId, @Nullable String alphanumericId)
implements Comparable<Identifier> {
@Override
@@ -0,0 +1,4 @@
@NullMarked
package org.pkl.executor;
import org.jspecify.annotations.NullMarked;
@@ -9,4 +9,7 @@
* <li>X MUST only use classes from its own package and Java platform packages.
* </ol>
*/
@NullMarked
package org.pkl.executor.spi;
import org.jspecify.annotations.NullMarked;
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import org.jspecify.annotations.Nullable;
public class ExecutorSpiOptions {
private final List<String> allowedModules;
@@ -31,13 +32,13 @@ public class ExecutorSpiOptions {
private final List<Path> modulePath;
private final Path rootDir;
private final @Nullable Path rootDir;
private final Duration timeout;
private final @Nullable Duration timeout;
private final String outputFormat;
private final Path moduleCacheDir;
private final Path projectDir;
private final @Nullable String outputFormat;
private final @Nullable Path moduleCacheDir;
private final @Nullable Path projectDir;
public ExecutorSpiOptions(
List<String> allowedModules,
@@ -45,11 +46,11 @@ public class ExecutorSpiOptions {
Map<String, String> environmentVariables,
Map<String, String> externalProperties,
List<Path> modulePath,
/* @Nullable */ Path rootDir,
/* @Nullable */ Duration timeout,
/* @Nullable */ String outputFormat,
/* @Nullable */ Path moduleCacheDir,
/* @Nullable */ Path projectDir) {
@Nullable Path rootDir,
@Nullable Duration timeout,
@Nullable String outputFormat,
@Nullable Path moduleCacheDir,
@Nullable Path projectDir) {
this.allowedModules = allowedModules;
this.allowedResources = allowedResources;
@@ -83,23 +84,23 @@ public class ExecutorSpiOptions {
return modulePath;
}
public /* @Nullable */ Path getRootDir() {
public @Nullable Path getRootDir() {
return rootDir;
}
public /* @Nullable */ Duration getTimeout() {
public @Nullable Duration getTimeout() {
return timeout;
}
public /* @Nullable */ String getOutputFormat() {
public @Nullable String getOutputFormat() {
return outputFormat;
}
public /* @Nullable */ Path getModuleCacheDir() {
public @Nullable Path getModuleCacheDir() {
return moduleCacheDir;
}
public Path getProjectDir() {
public @Nullable Path getProjectDir() {
return projectDir;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import org.jspecify.annotations.Nullable;
public class ExecutorSpiOptions2 extends ExecutorSpiOptions {
private final List<Path> certificateFiles;
@@ -33,11 +34,11 @@ public class ExecutorSpiOptions2 extends ExecutorSpiOptions {
Map<String, String> environmentVariables,
Map<String, String> externalProperties,
List<Path> modulePath,
Path rootDir,
Duration timeout,
String outputFormat,
Path moduleCacheDir,
Path projectDir,
@Nullable Path rootDir,
@Nullable Duration timeout,
@Nullable String outputFormat,
@Nullable Path moduleCacheDir,
@Nullable Path projectDir,
List<Path> certificateFiles,
List<byte[]> certificateBytes,
int testPort) {
@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import org.jspecify.annotations.Nullable;
public class ExecutorSpiOptions3 extends ExecutorSpiOptions2 {
@@ -31,11 +32,11 @@ public class ExecutorSpiOptions3 extends ExecutorSpiOptions2 {
Map<String, String> environmentVariables,
Map<String, String> externalProperties,
List<Path> modulePath,
Path rootDir,
Duration timeout,
String outputFormat,
Path moduleCacheDir,
Path projectDir,
@Nullable Path rootDir,
@Nullable Duration timeout,
@Nullable String outputFormat,
@Nullable Path moduleCacheDir,
@Nullable Path projectDir,
List<Path> certificateFiles,
List<byte[]> certificateBytes,
int testPort,
@@ -0,0 +1,4 @@
@NullMarked
package org.pkl.executor.spi.v1;
import org.jspecify.annotations.NullMarked;