Skip to content

JNI: support Foundation values in protocol callbacks - #5

Merged
teamhimeh merged 1 commit into
qoncept-forkfrom
codex/fix-jni-foundation-callbacks
Oct 23, 2026
Merged

teamhimeh merged 1 commit into
qoncept-forkfrom
codex/fix-jni-foundation-callbacks

Conversation

@teamhimeh

Copy link
Copy Markdown
Collaborator

Problem

JNI protocol callbacks reject Foundation value types even though the Java-facing method signatures already support them. As a result, a Swift protocol accepting or returning Data, Date, URL, or UUID cannot be implemented as an ordinary Java callback.

For example:

import Foundation

public protocol IdentityCallback {
  func transform(_ value: UUID) -> UUID
}

public func apply(_ callback: some IdentityCallback, _ value: UUID) -> UUID {
  callback.transform(value)
}

With this change, Java can implement that protocol using the existing java.util.UUID representation:

IdentityCallback callback = value ->
    java.util.UUID.fromString("87654321-4321-8765-cba9-876543210fed");
java.util.UUID result = MySwiftLibrary.apply(callback, input);

The generated callback bridge converts the Swift argument into a Java UUID and converts the Java result back into Swift. Data, Date, and URL callbacks instead use their existing generated wrapper classes and native value storage.

Changes

  • Allow Data, Date, and URL in callback parameters and results using the existing wrapper conversions.
  • Convert UUID through java.util.UUID.fromString and toString, consistently with the existing JNI-facing UUID API. UUIDs must not be treated as opaque Swift pointer wrappers.
  • Add the java.util.UUID projection and dependency mapping to runtime support so wrap-java can generate callback methods with UUID signatures.
  • Cover both Foundation and FoundationEssentials, plus Optional Data and Date, in generator regressions.
  • Add Java runtime tests for all four value types, a Java callback returning a different UUID, and present/empty Optional values. Document the supported representations and current limits.

Scope

This change enables Foundation values within the types already handled by JNI method extraction. Arrays of Foundation values and Optional URL/UUID parameters need separate extraction support and are outside this PR.

Validation

  • Confirmed the scalar callback generator regressions fail before the fix.
  • swift test --disable-experimental-prebuilts --disable-sandbox: passed.
  • ./gradlew :Samples:SwiftJavaExtractJNISampleApp:test --no-daemon: passed (278 Java tests, no failures or skips), including the five new runtime tests.
  • swift-format lint --strict on changed Swift files and git diff --check: passed.

Tested with Apple Swift 6.4 and JetBrains Runtime 25.0.2 on macOS.

Bridge Data, Date, and URL with their generated wrappers and convert UUID
through java.util.UUID. Register the UUID projection with runtime support
so wrap-java preserves callback methods containing Java UUID signatures.

Add regressions for Foundation and FoundationEssentials, Java callback
round trips, and present or empty Optional Data and Date values.
@teamhimeh
teamhimeh merged commit 3edec05 into qoncept-fork Oct 23, 2026
33 of 42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant