Skip to content

Add Java polyglot AppHost parity#15470

Open
sebastienros wants to merge 10 commits intomainfrom
sebros/java-empty-apphost-template
Open

Add Java polyglot AppHost parity#15470
sebastienros wants to merge 10 commits intomainfrom
sebros/java-empty-apphost-template

Conversation

@sebastienros
Copy link
Contributor

@sebastienros sebastienros commented Mar 21, 2026

Description

This PR brings Java polyglot AppHost support much closer to the existing TypeScript experience.

Summary:

  • adds Java validation apphosts across playground/polyglot/Java/** to mirror the TypeScript playground coverage
  • improves generated Java SDK ergonomics for unions, callbacks, optional/nullability handling, and direct resource overloads
  • adds a runnable playground/JavaAppHost sample
  • adds Java CI validation in tests.yml and the polyglot validation Docker/scripts, including a dedicated Java playground validation script
  • replaces the previous Java Express/React CLI template with Empty (Java AppHost) behind the experimental Java feature flag
  • adds scoped .gitignore entries for Java playground build outputs

Motivation/context:

  • Java polyglot support was lagging behind TypeScript in generated surface area, playground coverage, CLI scaffolding, and CI validation.
  • This change closes those gaps so Java can serve as a practical experimental AppHost language with much better compile-time validation.

Limitation:
If we want to generate compact source files (https://openjdk.org/jeps/512) like file-based apps in C# we need to explore the currently unique .java sdk file into split classes which would generate a lot of fils in the .modules folder. That wouldn't change the size of the git repo (objects would be reused) but can feel very overwhelming. Like node_modules feel. Current generated code is also compatbile with jdk 17 while jep512 requires jdk 25.

To enable the java support, type aspire config set -g features.experimentalPolyglot:java true

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 21, 2026 04:28
@github-actions
Copy link
Contributor

github-actions bot commented Mar 21, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 15470

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 15470"

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands Java polyglot AppHost support to better match the TypeScript experience by adding Java validation AppHosts across the polyglot playground, introducing a runnable Java sample, and wiring Java validation into CI/Docker workflows.

Changes:

  • Added multiple Java playground validation AppHosts (configs + AppHost.java + generated .modules) mirroring TypeScript coverage
  • Added a runnable playground/JavaAppHost sample (Java AppHost + Node/React frontend)
  • Added Java CI/unit-test job and Docker/scripts for Java playground validation

Reviewed changes

Copilot reviewed 86 out of 374 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
playground/polyglot/Java/Aspire.Hosting.Azure.PostgreSQL/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for Java validation AppHost SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.OperationalInsights/ValidationAppHost/aspire.config.json Adds Java AppHost config enabling experimental Java polyglot and package restore.
playground/polyglot/Java/Aspire.Hosting.Azure.OperationalInsights/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising OperationalInsights API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.OperationalInsights/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.OperationalInsights/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.Kusto/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for Kusto package.
playground/polyglot/Java/Aspire.Hosting.Azure.Kusto/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising Kusto API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.Kusto/ValidationAppHost/.modules/Transport.java Adds generated Java JSON-RPC transport for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.Kusto/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.Kusto/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.KeyVault/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for KeyVault package.
playground/polyglot/Java/Aspire.Hosting.Azure.KeyVault/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising KeyVault API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.KeyVault/ValidationAppHost/.modules/Transport.java Adds generated Java JSON-RPC transport for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.KeyVault/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.KeyVault/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.Functions/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for Functions (+ Storage dependency).
playground/polyglot/Java/Aspire.Hosting.Azure.Functions/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising Functions API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.Functions/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.Functions/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.EventHubs/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for EventHubs package.
playground/polyglot/Java/Aspire.Hosting.Azure.EventHubs/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising EventHubs API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.EventHubs/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.EventHubs/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.CosmosDB/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for CosmosDB (+ KeyVault dependency).
playground/polyglot/Java/Aspire.Hosting.Azure.CosmosDB/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising CosmosDB API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.CosmosDB/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.CosmosDB/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.ContainerRegistry/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for ContainerRegistry (+ AppContainers dependency).
playground/polyglot/Java/Aspire.Hosting.Azure.ContainerRegistry/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising ContainerRegistry API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.ContainerRegistry/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.ContainerRegistry/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.CognitiveServices/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for CognitiveServices package.
playground/polyglot/Java/Aspire.Hosting.Azure.CognitiveServices/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising CognitiveServices/OpenAI API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.CognitiveServices/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.CognitiveServices/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.ApplicationInsights/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for ApplicationInsights (+ OperationalInsights dependency).
playground/polyglot/Java/Aspire.Hosting.Azure.ApplicationInsights/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising ApplicationInsights API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.ApplicationInsights/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.ApplicationInsights/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.AppService/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for AppService package.
playground/polyglot/Java/Aspire.Hosting.Azure.AppService/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising AppService API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.AppService/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.AppService/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.AppContainers/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for AppContainers (+ OperationalInsights dependency).
playground/polyglot/Java/Aspire.Hosting.Azure.AppContainers/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising AppContainers API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.AppContainers/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.AppContainers/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/polyglot/Java/Aspire.Hosting.Azure.AppConfiguration/ValidationAppHost/aspire.config.json Adds Java validation AppHost config for AppConfiguration package.
playground/polyglot/Java/Aspire.Hosting.Azure.AppConfiguration/ValidationAppHost/AppHost.java Adds Java validation AppHost exercising AppConfiguration API surface.
playground/polyglot/Java/Aspire.Hosting.Azure.AppConfiguration/ValidationAppHost/.modules/Base.java Adds generated Java base/runtime helpers for SDK.
playground/polyglot/Java/Aspire.Hosting.Azure.AppConfiguration/ValidationAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
playground/JavaAppHost/frontend/vite.config.ts Adds Vite config including API proxy for frontend dev server.
playground/JavaAppHost/frontend/tsconfig.node.json Adds TS config for Vite/node tooling.
playground/JavaAppHost/frontend/tsconfig.json Adds TS project references setup.
playground/JavaAppHost/frontend/tsconfig.app.json Adds TS config for React app compilation.
playground/JavaAppHost/frontend/src/main.tsx Adds React entrypoint.
playground/JavaAppHost/frontend/src/index.css Adds base/reset styles and reduced-motion handling.
playground/JavaAppHost/frontend/src/App.tsx Adds sample UI fetching weather forecast via API proxy.
playground/JavaAppHost/frontend/package.json Adds frontend dependencies/scripts and Node engine constraints.
playground/JavaAppHost/frontend/index.html Adds Vite HTML entry.
playground/JavaAppHost/frontend/eslint.config.js Adds ESLint config for TS/React hooks and refresh.
playground/JavaAppHost/frontend/.dockerignore Adds Docker ignore for Node build artifacts.
playground/JavaAppHost/aspire.config.json Adds Java AppHost config for the runnable JavaAppHost sample.
playground/JavaAppHost/api/tsconfig.json Adds TS config for the API service build output.
playground/JavaAppHost/api/src/instrumentation.ts Adds OpenTelemetry NodeSDK initialization for Aspire dashboard.
playground/JavaAppHost/api/src/index.ts Adds Express API service serving forecast and optional static bundle.
playground/JavaAppHost/api/package.json Adds API dependencies including express and OpenTelemetry exporters/SDK.
playground/JavaAppHost/AppHost.java Adds runnable Java AppHost wiring Node API + Vite frontend and publish bundling.
playground/JavaAppHost/.modules/Transport.java Adds generated Java JSON-RPC transport for the JavaAppHost sample.
playground/JavaAppHost/.modules/Base.java Adds generated Java base/runtime helpers for the JavaAppHost sample.
playground/JavaAppHost/.modules/.codegen-hash Adds codegen hash for generated SDK output.
.github/workflows/tests.yml Adds Java SDK unit test job and integrates it into overall results gating.
.github/workflows/polyglot-validation/test-java.sh Updates Java polyglot validation script to create/restore/run a minimal Redis-backed Java AppHost.
.github/workflows/polyglot-validation/test-java-playground.sh Adds script to restore + javac compile all Java validation AppHosts in the playground.
.github/workflows/polyglot-validation/Dockerfile.java Updates Docker image and runs both Java validation scripts in container.
Files not reviewed (1)
  • playground/JavaAppHost/frontend/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)

playground/JavaAppHost/.modules/Transport.java:1

  • The RandomAccessFile used for the Windows named pipe is a local variable that is never stored/closed. If it becomes GC-eligible, the underlying handle can be closed unexpectedly (via finalization/cleaner), breaking the transport. Store the RandomAccessFile as an instance field to keep it alive for the duration of the connection and close it when disconnecting/shutting down (or avoid RandomAccessFile entirely by opening streams directly against the pipe path if supported).

sebastienros and others added 9 commits March 20, 2026 21:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor

🎬 CLI E2E Test Recordings — 54 recordings uploaded (commit 62ae748)

View recordings
Test Recording
AddPackageInteractiveWhileAppHostRunningDetached ▶️ View Recording
AddPackageWhileAppHostRunningDetached ▶️ View Recording
AgentCommands_AllHelpOutputs_AreCorrect ▶️ View Recording
AgentInitCommand_DefaultSelection_InstallsSkillOnly ▶️ View Recording
AgentInitCommand_MigratesDeprecatedConfig ▶️ View Recording
AspireAddPackageVersionToDirectoryPackagesProps ▶️ View Recording
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps ▶️ View Recording
Banner_DisplayedOnFirstRun ▶️ View Recording
Banner_DisplayedWithExplicitFlag ▶️ View Recording
CertificatesClean_RemovesCertificates ▶️ View Recording
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate ▶️ View Recording
CertificatesTrust_WithUntrustedCert_TrustsCertificate ▶️ View Recording
ConfigSetGet_CreatesNestedJsonFormat ▶️ View Recording
CreateAndDeployToDockerCompose ▶️ View Recording
CreateAndDeployToDockerComposeInteractive ▶️ View Recording
CreateAndPublishToKubernetes ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunEmptyAppHostProject ▶️ View Recording
CreateAndRunJavaEmptyAppHostProject ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateAndRunTypeScriptEmptyAppHostProject ▶️ View Recording
CreateAndRunTypeScriptStarterProject ▶️ View Recording
CreateJavaAppHostWithViteApp ▶️ View Recording
CreateStartAndStopAspireProject ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DescribeCommandResolvesReplicaNames ▶️ View Recording
DescribeCommandShowsRunningResources ▶️ View Recording
DetachFormatJsonProducesValidJson ▶️ View Recording
DoctorCommand_DetectsDeprecatedAgentConfig ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
GlobalMigration_HandlesCommentsAndTrailingCommas ▶️ View Recording
GlobalMigration_HandlesMalformedLegacyJson ▶️ View Recording
GlobalMigration_PreservesAllValueTypes ▶️ View Recording
GlobalMigration_SkipsWhenNewConfigExists ▶️ View Recording
GlobalSettings_MigratedFromLegacyFormat ▶️ View Recording
InvalidAppHostPathWithComments_IsHealedOnRun ▶️ View Recording
LogsCommandShowsResourceLogs ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording
PsFormatJsonOutputsOnlyJsonToStdout ▶️ View Recording
PublishWithDockerComposeServiceCallbackSucceeds ▶️ View Recording
RestoreGeneratesSdkFiles ▶️ View Recording
RunWithMissingAwaitShowsHelpfulError ▶️ View Recording
SecretCrudOnDotNetAppHost ▶️ View Recording
SecretCrudOnTypeScriptAppHost ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ▶️ View Recording
StopAllAppHostsFromUnrelatedDirectory ▶️ View Recording
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ▶️ View Recording
TypeScriptAppHostWithProjectReferenceIntegration ▶️ View Recording

📹 Recordings uploaded automatically from CI run #23385491108

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.

2 participants