Skip to content

Java hosting integration enhancements & Gradle support#1129

Open
marshalhayes wants to merge 15 commits intoCommunityToolkit:mainfrom
marshalhayes:gradle
Open

Java hosting integration enhancements & Gradle support#1129
marshalhayes wants to merge 15 commits intoCommunityToolkit:mainfrom
marshalhayes:gradle

Conversation

@marshalhayes
Copy link
Contributor

@marshalhayes marshalhayes commented Feb 14, 2026

Closes #1128

This PR updates the Java hosting integration, replacing options-based configuration with composable, fluent builder methods that align with current Aspire patterns.

What's New

Gradle support

  • WithGradleTask() runs Gradle tasks (e.g., bootRun) on Java app resources, automatically resolving the correct platform-specific wrapper (gradlew / gradlew.bat).
  • WithGradleBuild() adds a pre-build lifecycle hook using the Gradle wrapper, modeled as a dependent GradleBuildResource that runs before the app starts.

Composable builder methods

  • WithMavenGoal() — configures Maven to run a goal (e.g., spring-boot:run) instead of executing a JAR directly.
  • WithOtelAgent() — attaches the OpenTelemetry Java agent via -javaagent JVM arg.
  • WithJvmArgs() — adds arbitrary JVM arguments (e.g., -Xmx512m).

Simplified entry points

  • AddJavaApp(name, workingDirectory) — creates an executable Java resource (optionally with a JAR path).
  • AddJavaContainerApp(name, image) — creates a container-based Java resource.

What's Changed

  • AddSpringApp() replaced in favor of AddJavaApp() / AddJavaContainerApp()
  • Options classes deprecatedJavaAppContainerResourceOptions and JavaAppExecutableResourceOptions are marked [Obsolete]; the legacy overloads that accept them still work but delegate to the new API internally.
  • JavaAppExecutableResource now implements IResourceWithWaitSupport and defaults its command to java, with arguments constructed dynamically via CommandLineArgsCallbackAnnotation.
  • JavaAppContainerResource now uses ContainerMountAnnotation for the OTel agent instead of an environment variable pointing to a directory.
  • Maven build refactored — WithMavenBuild() now creates a dependent MavenBuildResource (lifecycle hook) instead of a dashboard rebuild command.
  • Tests rewritten to cover the new API surface including Gradle tasks, Maven goals, OTel agent configuration, JVM args, and mutual-exclusion guards (e.g., WithMavenGoal throws if a JAR path is already set).

PR Checklist

  • Created a feature/dev branch in your fork (vs. submitting directly from a commit on main)
  • Based off latest main branch of toolkit
  • PR doesn't include merge commits (always rebase on top of our main, if needed)
  • New integration
    • Docs are written
    • Added description of major feature to project description for NuGet package (4000 total character limit, so don't push entire description over that)
  • Tests for the changes have been added (for bug fixes / features) (if applicable)
  • Contains NO breaking changes
  • Every new API (including internal ones) has full XML docs
  • Code follows all style conventions

Other information

@marshalhayes marshalhayes changed the title Add Gradle support Java hosting integration enhancements & Gradle support Feb 17, 2026
@marshalhayes marshalhayes marked this pull request as ready for review February 24, 2026 05:43
Copilot AI review requested due to automatic review settings February 24, 2026 05:43
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 modernizes the Java hosting integration by replacing options-based configuration with composable, fluent builder methods and adds Gradle support alongside the existing Maven support. The changes align with current Aspire patterns while maintaining backward compatibility through obsolete methods.

Changes:

  • Introduces Gradle support with WithGradleBuild() and WithGradleTask() methods that mirror Maven's functionality
  • Refactors API from options-based to fluent builder pattern with methods like WithMavenGoal(), WithGradleTask(), WithJvmArgs(), and WithOtelAgent()
  • Adds new resource types (MavenBuildResource, GradleBuildResource, JavaBuildToolAnnotation) to support build tool integration
  • Deprecates AddSpringApp() in favor of AddJavaApp() and AddJavaContainerApp(), and marks options classes as obsolete

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
ExecutableResourceCreationTests.cs Updates tests to use new API, adds comprehensive tests for Maven/Gradle build and goal/task execution
ContainerResourceCreationTests.cs Adds test for new AddJavaContainerApp API, wraps deprecated tests in pragma warnings
README.md Complete rewrite with examples for Maven, Gradle, JAR execution, and JVM configuration
JavaAppHostingExtension.Executable.cs Major refactor introducing new fluent API methods, BeforeStartEvent handling for build tool command switching
JavaAppHostingExtension.Container.cs Adds AddJavaContainerApp method with cleaner API, deprecates old methods
JavaAppExecutableResource.cs Adds new constructor and JarPath property to support flexible execution modes
MavenBuildResource.cs New resource representing Maven build steps
GradleBuildResource.cs New resource representing Gradle build steps
JavaBuildToolAnnotation.cs Internal annotation for tracking build tool configuration
MavenOptions.cs Marked as obsolete
JavaAppExecutableResourceOptions.cs Marked as obsolete
JavaAppContainerResourceOptions.cs Marked as obsolete
Program.cs (example) Updated to demonstrate new API patterns

@marshalhayes marshalhayes force-pushed the gradle branch 2 times, most recently from 6699705 to 220fd04 Compare February 24, 2026 06:24
marshalhayes and others added 8 commits February 24, 2026 00:27
- Make jarPath a required parameter in AddJavaApp
- Remove jarPath from WithMavenBuild/WithGradleBuild
- Simplify wrapper path resolution using ??= pattern
- Inline ResolveWrapperCommand into callers
- Restructure README to align with other integrations
- Fix stale Obsolete messages to match current signatures

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rload

- Add AddJavaApp(name, workingDirectory) overload without jarPath
- Add WithJarPath() fluent method for explicit JAR path configuration
- Add WithMavenGoal() and WithGradleTask() to run apps via build tools
- Add JavaBuildToolAnnotation for build tool integration
- Refactor existing AddJavaApp to delegate to new overload
- Simplify Dockerfile generation for publish scenarios
- Update README with new API patterns and examples
- Update example app to use new API
- Add new tests for the expanded API surface

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove PublishAsJavaDockerfile and JavaBuildAnnotation, which were new
functionality not present in the existing integration. Auto-Dockerfile
generation can be revisited as a separate feature.

Fix deprecated AddSpringApp (container) obsolete message to point to
AddJavaContainerApp instead of the also-deprecated AddJavaApp.

Restore endpoint assertions in container resource tests.

Update README publishing section to reflect manual PublishAsDockerFile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove stray double quote characters after </param> tags and
remove unnecessary blank lines in Container and Executable extensions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Follow C# naming conventions for constants by renaming
JAVA_TOOL_OPTIONS to JavaToolOptions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
marshalhayes and others added 5 commits February 24, 2026 20:46
…ng with WithCommand

MavenBuildResource and GradleBuildResource now accept the resolved wrapper
script path in their constructors, eliminating the need to pass a placeholder
("mvnw"/"gradlew") and immediately override it with .WithCommand().

This aligns with the Aspire convention where ExecutableResource receives the
actual command at construction time (e.g. PythonAppResource, NodeAppResource).

Addresses PR review comments r2844673239 and r2844673316.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AddJavaContainerApp and the new AddJavaApp called WithOtelAgent()
with no agentPath, which just delegates to WithOtlpExporter() anyway.
Call WithOtlpExporter() directly to avoid implying an OTel agent is
configured. Users who need the agent can chain WithOtelAgent(path).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Maven-specific default was misleading for Gradle users and unused
by the WithMavenGoal/WithGradleTask code path.

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>
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

Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.

Comment on lines +24 to +26
public static IResourceBuilder<JavaAppExecutableResource> AddJavaApp(this IDistributedApplicationBuilder builder, [ResourceName] string name, string workingDirectory,
string jarPath, string[]? args = null)
{
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

This PR introduces new/changed public APIs (e.g., new AddJavaApp overloads and the Gradle/Maven fluent methods), but the generated API baseline file (src/CommunityToolkit.Aspire.Hosting.Java/api/CommunityToolkit.Aspire.Hosting.Java.cs) still appears to reflect the pre-change surface area. If CI/packaging expects these api/*.cs files to be kept in sync (as other integrations do), please regenerate/update the Java one for this PR.

Copilot uses AI. Check for mistakes.
- WithJvmArgs: remove params, require explicit string[] args with null
  check and empty-array early return
- Fix XML docs: remove incorrect 'If null, falls back to current process
  directory' claim from workingDirectory params (non-nullable)
- Obsolete WithMavenBuild(MavenOptions): pass Command as wrapperScript
  to preserve existing callers' custom wrapper commands

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Member

@aaronpowell aaronpowell left a comment

Choose a reason for hiding this comment

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

Looking like a really solid overhaul of the Java integration - nice work!

I see we have some build failures, that's likely next to tackle before merging is to be tackled.

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.

Add support for Gradle

3 participants