Watch Aspire live streamsDocsTry Aspire
Watch Aspire live streamsDocsTry

JavaHostingExtensions Methods

ClassMethods15 members
Provides extension methods for adding Java applications to an Hosting.IDistributedApplicationBuilder.
AddJavaApp(IDistributedApplicationBuilder, string, string)Section titled AddJavaApp(IDistributedApplicationBuilder, string, string)extensionIResourceBuilder<JavaAppResource>
Adds a Java application to the application model, launched with java.
public static class JavaHostingExtensions
{
public static IResourceBuilder<JavaAppResource> AddJavaApp(
this IDistributedApplicationBuilder builder,
string name,
string appDirectory)
{
// ...
}
}
builderIDistributedApplicationBuilderThe Hosting.IDistributedApplicationBuilder to add the resource to.
namestringThe name of the resource.
appDirectorystringThe application directory. Relative paths are resolved against the AppHost directory.
IResourceBuilder<JavaAppResource>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
ArgumentExceptionname or appDirectory is null, empty, or whitespace.
InvalidOperationExceptionNo launch mode was configured. Raised when the resource starts, not when this is called.
Combine with JavaHostingExtensions.WithMavenGoal or JavaHostingExtensions.WithGradleTask to run the application through a build tool, or use the overload that accepts a jarPath to run a prebuilt JAR with java -jar. Exactly one of those three launch modes must be configured.

Run a Spring Boot application through the Maven wrapper:

var builder = DistributedApplication.CreateBuilder(args);
builder.AddJavaApp("catalog", "../catalog")
.WithMavenGoal("spring-boot:run")
.WithHttpEndpoint(env: "SERVER_PORT")
.WithHttpHealthCheck("/actuator/health");
builder.Build().Run();
AddJavaApp(IDistributedApplicationBuilder, string, string, string, string[])Section titled AddJavaApp(IDistributedApplicationBuilder, string, string, string, string[])extensionIResourceBuilder<JavaAppResource>
Adds a Java application that runs a prebuilt JAR with java -jar.
public static class JavaHostingExtensions
{
public static IResourceBuilder<JavaAppResource> AddJavaApp(
this IDistributedApplicationBuilder builder,
string name,
string appDirectory,
string jarPath,
params string[] args)
{
// ...
}
}
builderIDistributedApplicationBuilderThe Hosting.IDistributedApplicationBuilder to add the resource to.
namestringThe name of the resource.
appDirectorystringThe application directory. Relative paths are resolved against the AppHost directory.
jarPathstringThe path to the JAR file to execute. Relative paths are resolved against appDirectory.
argsstring[]Arguments passed to the Java application after the JAR path.
IResourceBuilder<JavaAppResource>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder or args is null.
ArgumentExceptionname, appDirectory, or jarPath is null, empty, or whitespace.

Build the JAR with Maven, then run it:

builder.AddJavaApp("worker", "../worker", "target/worker.jar")
.WithMavenBuild();
AddJavaContainer(IDistributedApplicationBuilder, string, string, string?)Section titled AddJavaContainer(IDistributedApplicationBuilder, string, string, string?)extensionIResourceBuilder<JavaContainerResource>
Adds a Java application that runs from an existing container image.
public static class JavaHostingExtensions
{
public static IResourceBuilder<JavaContainerResource> AddJavaContainer(
this IDistributedApplicationBuilder builder,
string name,
string image,
string? tag = null)
{
// ...
}
}
builderIDistributedApplicationBuilderThe Hosting.IDistributedApplicationBuilder to add the resource to.
namestringThe name of the resource.
imagestringThe container image that runs the application, for example mycompany/catalog.
tagstring?optionalThe image tag. Defaults to the image's latest tag.
IResourceBuilder<JavaContainerResource>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
ArgumentExceptionname or image is null, empty, or whitespace.
Use this when the image is built elsewhere — by a separate CI pipeline, or by a team that ships the application as a container. Aspire runs the image as-is and never rebuilds it, so the JAR, the JDK, and any OpenTelemetry agent all come from the image. Use JavaHostingExtensions.AddJavaApp instead when Aspire should build and run the application from source.

No endpoint is declared, because the port the image listens on is a property of the image. Add one with WithHttpEndpoint(targetPort: 8080), using whichever port the application binds — 8080 for a default Spring Boot or Quarkus image.

Run a published Spring Boot image and give it a database:

var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddPostgres("pg").AddDatabase("catalogdb");
builder.AddJavaContainer("catalog", "mycompany/catalog", "1.4.0")
.WithHttpEndpoint(targetPort: 8080)
.WithReference(db)
.WithJvmArgs("-Xmx512m");
builder.Build().Run();
AddQuarkusApp(IDistributedApplicationBuilder, string, string)Section titled AddQuarkusApp(IDistributedApplicationBuilder, string, string)extensionIResourceBuilder<JavaAppResource>
Adds a Quarkus application to the application model, built and launched with its own Maven or Gradle wrapper.
public static class JavaHostingExtensions
{
public static IResourceBuilder<JavaAppResource> AddQuarkusApp(
this IDistributedApplicationBuilder builder,
string name,
string appDirectory)
{
// ...
}
}
builderIDistributedApplicationBuilderThe Hosting.IDistributedApplicationBuilder to add the resource to.
namestringThe name of the resource.
appDirectorystringThe application directory, containing pom.xml, build.gradle, build.gradle.kts, settings.gradle, or settings.gradle.kts. Relative paths are resolved against the AppHost directory.
IResourceBuilder<JavaAppResource>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
ArgumentExceptionname or appDirectory is null, empty, or whitespace.
InvalidOperationExceptionThe directory contains neither a Maven nor a Gradle build file, or contains both.
The build tool is detected when the resource starts, the application runs in Quarkus dev mode ( quarkus:dev or quarkusDev) so live coding works, and an HTTP endpoint is declared through QUARKUS_HTTP_PORT, the environment variable Quarkus reads for its listening port. Everything else behaves like JavaHostingExtensions.AddJavaApp. The dev-mode goal compiles the application itself, so Aspire does not add a separate build resource before it. There are two exceptions. JavaHostingExtensions.WithOtelAgent with a build-produced agent cannot be loaded until a build has written it, and a debug session launches the packaged fast JAR rather than the dev-mode wrapper, which no build has written on a clean checkout.

Quarkus Dev Services are left enabled but do not activate for anything Aspire supplies: Dev Services only start a container when the corresponding configuration is missing, and a WithReference to a database or broker provides it. That means Aspire's resources are used rather than a second set started underneath.

QUARKUS_PROFILE is set to dev in run mode. Dev mode already selects that profile; setting it explicitly means a debugger, which launches the packaged application rather than the dev-mode wrapper, resolves the same %dev. configuration the application would see when run normally.

In run mode the application is bound to all interfaces. Quarkus enables Host header validation whenever it binds a localhost name, and that filter rejects the hostname Aspire publishes, which makes the endpoint link in the dashboard return 400. Published output is left alone, where the application already binds all interfaces.

No health check is added. /q/health only exists when the application depends on quarkus-smallrye-health, and adding it unconditionally would leave applications without that extension permanently unhealthy and silently stall every WaitFor on them. Add WithHttpHealthCheck("/q/health") when the extension is present.

A Quarkus service backed by a database Aspire provides:

var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddPostgres("pg").AddDatabase("inventorydb");
builder.AddQuarkusApp("inventory", "../inventory")
.WithReference(db)
.WaitFor(db);
builder.Build().Run();
AddSpringBootApp(IDistributedApplicationBuilder, string, string)Section titled AddSpringBootApp(IDistributedApplicationBuilder, string, string)extensionIResourceBuilder<JavaAppResource>
Adds a Spring Boot application to the application model, built and launched with its own Maven or Gradle wrapper.
public static class JavaHostingExtensions
{
public static IResourceBuilder<JavaAppResource> AddSpringBootApp(
this IDistributedApplicationBuilder builder,
string name,
string appDirectory)
{
// ...
}
}
builderIDistributedApplicationBuilderThe Hosting.IDistributedApplicationBuilder to add the resource to.
namestringThe name of the resource.
appDirectorystringThe application directory, containing pom.xml, build.gradle, build.gradle.kts, settings.gradle, or settings.gradle.kts. Relative paths are resolved against the AppHost directory.
IResourceBuilder<JavaAppResource>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
ArgumentExceptionname or appDirectory is null, empty, or whitespace.
InvalidOperationExceptionThe directory contains neither a Maven nor a Gradle build file, or contains both.
This is JavaHostingExtensions.AddJavaApp with the common Spring Boot configuration already applied: the build tool is detected when the resource starts, the application is launched through that tool's Spring Boot plugin ( spring-boot:run or bootRun), and an HTTP endpoint is declared through SERVER_PORT, which is the environment variable Spring Boot reads for its listening port. Everything else is the same, so any With… method that works on JavaHostingExtensions.AddJavaApp works here too.

The launch goal compiles the application itself, so Aspire does not add a separate build resource before it. Publishing still packages the application with tests skipped ( -DskipTests for Maven, -x test for Gradle). Call JavaHostingExtensions.WithMavenBuild or JavaHostingExtensions.WithGradleBuild afterwards to customize those package arguments. The one thing that does add a build resource is JavaHostingExtensions.WithOtelAgent with a build-produced agent, which cannot be loaded until a build has written it.

No health check is added. /actuator/health only exists when the application depends on spring-boot-starter-actuator, and adding it unconditionally would leave applications without that dependency permanently unhealthy and silently stall every WaitFor on them. Add WithHttpHealthCheck("/actuator/health") when the actuator is present.

Two Spring Boot services and a database:

var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddPostgres("pg").AddDatabase("catalogdb");
var catalog = builder.AddSpringBootApp("catalog", "../catalog")
.WithReference(db);
builder.AddSpringBootApp("orders", "../orders")
.WithReference(catalog)
.WaitFor(catalog);
builder.Build().Run();
WithGradleBuild(IResourceBuilder<T>, string[])Section titled WithGradleBuild(IResourceBuilder<T>, string[])extensionIResourceBuilder<T>
Runs a Gradle build before the Java application starts.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithGradleBuild<T>(
this IResourceBuilder<T> builder,
params string[] args)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder for the Java application.
argsstring[]Arguments passed to the Gradle wrapper. Defaults to clean build.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder or args is null.
InvalidOperationExceptionThe application is already configured to build with Maven.
When the application launches with JavaHostingExtensions.WithGradleTask, that task performs the local compilation, so these arguments normally configure publishing without adding a second run-mode build. Otherwise, the build step is a child resource that the application waits for. No child is created when publishing because the generated container image performs the build.

This runs a build before the application starts. To launch the application through Gradle, use JavaHostingExtensions.WithGradleTask instead.

WithGradleTask(IResourceBuilder<T>, string, string[])Section titled WithGradleTask(IResourceBuilder<T>, string, string[])extensionIResourceBuilder<T>
Launches the Java application through a Gradle task instead of java, for example bootRun.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithGradleTask<T>(
this IResourceBuilder<T> builder,
string task,
params string[] args)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder for the Java application.
taskstringThe Gradle task to execute.
argsstring[]Additional arguments passed to the Gradle wrapper after the task.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder or args is null.
ArgumentExceptiontask is null, empty, or whitespace.
InvalidOperationExceptionThe application is already configured to run a prebuilt JAR or a Maven goal.
The wrapper defaults to gradlew ( gradlew.bat on Windows) in the resource's working directory and can be overridden with JavaHostingExtensions.WithWrapperPath.
WithJarArtifact(IResourceBuilder<T>, string)Section titled WithJarArtifact(IResourceBuilder<T>, string)extensionIResourceBuilder<T>
Selects the JAR the generated container image runs, for projects whose build produces more than one.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithJarArtifact<T>(
this IResourceBuilder<T> builder,
string jarPath)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder for the Java application.
jarPathstringThe path to the JAR produced by the build, relative to the application directory, for example target/app.jar.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
ArgumentExceptionjarPath is null, empty, or whitespace.
Only affects publishing, and only when the application is built in the image. Without it the container build selects the single JAR that is not a -plain, -sources, or -javadoc artifact, and fails the build if that is ambiguous.

This takes precedence over the JAR named by the jarPath overload of JavaHostingExtensions.AddJavaApp, so a resource can run one JAR locally and publish another. It has no effect on an application published from a prebuilt JAR, because nothing is built in the image for it to select from.

WithJvmArgs(IResourceBuilder<T>, string[])Section titled WithJvmArgs(IResourceBuilder<T>, string[])extensionIResourceBuilder<T>
Adds arguments to the Java Virtual Machine that runs the application.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithJvmArgs<T>(
this IResourceBuilder<T> builder,
params string[] args)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder.
argsstring[]The JVM arguments, for example -Xmx512m.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder or args is null.
Arguments are passed through the JAVA_TOOL_OPTIONS environment variable, which the JVM reads however it was started — java -jar, a Maven goal, a Gradle task, or a container image's own entrypoint, including the JVM those build tools fork. Values containing spaces are quoted, because the JVM splits this variable on whitespace.

This is also how a container image that already carries the OpenTelemetry Java agent turns it on, since JavaHostingExtensions.WithOtelAgent copies an agent from the build context and so applies only to applications Aspire itself launches or builds: WithJvmArgs("-javaagent:/app/opentelemetry-javaagent.jar").

WithMainClass(IResourceBuilder<T>, string)Section titled WithMainClass(IResourceBuilder<T>, string)extensionIResourceBuilder<T>
Sets the main class an IDE launches when running or debugging this application. Has no effect on how Aspire starts the process, which is decided by the JAR path, Maven goal, or Gradle task.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithMainClass<T>(
this IResourceBuilder<T> builder,
string mainClass)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder for the Java application.
mainClassstringThe fully qualified name of the class declaring main, for example com.example.Application.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
ArgumentExceptionmainClass is null, empty, or whitespace.
Only affects IDE execution. When omitted, the IDE resolves the main class from the project's build files; set it explicitly when a project declares more than one class with a main method.
WithMavenBuild(IResourceBuilder<T>, string[])Section titled WithMavenBuild(IResourceBuilder<T>, string[])extensionIResourceBuilder<T>
Runs a Maven build before the Java application starts.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithMavenBuild<T>(
this IResourceBuilder<T> builder,
params string[] args)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder for the Java application.
argsstring[]Arguments passed to the Maven wrapper. Defaults to clean package.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder or args is null.
InvalidOperationExceptionThe application is already configured to build with Gradle.
When the application launches with JavaHostingExtensions.WithMavenGoal, that goal performs the local compilation, so these arguments normally configure publishing without adding a second run-mode build. Otherwise, the build step is a child resource that the application waits for. No child is created when publishing because the generated container image performs the build.

This runs a build before the application starts. To launch the application through Maven, use JavaHostingExtensions.WithMavenGoal instead.

WithMavenGoal(IResourceBuilder<T>, string, string[])Section titled WithMavenGoal(IResourceBuilder<T>, string, string[])extensionIResourceBuilder<T>
Launches the Java application through a Maven goal instead of java, for example spring-boot:run.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithMavenGoal<T>(
this IResourceBuilder<T> builder,
string goal,
params string[] args)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder for the Java application.
goalstringThe Maven goal to execute.
argsstring[]Additional arguments passed to the Maven wrapper after the goal.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder or args is null.
ArgumentExceptiongoal is null, empty, or whitespace.
InvalidOperationExceptionThe application is already configured to run a prebuilt JAR or a Gradle task.
The wrapper defaults to mvnw ( mvnw.cmd on Windows) in the resource's working directory and can be overridden with JavaHostingExtensions.WithWrapperPath.
WithOtelAgent(IResourceBuilder<T>)Section titled WithOtelAgent(IResourceBuilder<T>)extensionIResourceBuilder<T>
Runs the application with the OpenTelemetry Java agent from the location the build tool writes it to.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithOtelAgent<T>(
this IResourceBuilder<T> builder)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
InvalidOperationExceptionThe resource has no Maven or Gradle build configured, so the agent location cannot be inferred. Raised when the application model is built, not when this is called.
The agent is expected at target/agent/opentelemetry-javaagent.jar for Maven and build/agent/opentelemetry-javaagent.jar for Gradle — the conventional output directory of each tool with an agent subdirectory. The build has to put it there; nothing is downloaded. With Maven, copy it with maven-dependency-plugin 's copy goal bound to process-resources; with Gradle, declare the agent in its own configuration and add a Copy task that compileJava depends on.

May be called before or after the build tool is configured: which directory the agent is read from is decided when the application model is built, so the result does not depend on the order of builder calls.

Because the build writes the agent, Aspire runs that build as its own resource in run mode and holds the application until it finishes — including for Spring Boot and Quarkus, whose launch goals would otherwise be the only build. This is required rather than an optimization: JAVA_TOOL_OPTIONS is read by every JVM started beneath the resource, and the first of those is the wrapper's own, so an agent the build has not written yet kills that JVM during VM initialization with "Error opening zip file or JAR manifest missing" before the launch goal runs.

Use JavaHostingExtensions.WithOtelAgent when the agent lives anywhere else, including when it is committed to the repository or supplied by the container base image.

WithOtelAgent(IResourceBuilder<T>, string)Section titled WithOtelAgent(IResourceBuilder<T>, string)extensionIResourceBuilder<T>
Runs the application with the OpenTelemetry Java agent so it exports traces, metrics, and logs to Aspire.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithOtelAgent<T>(
this IResourceBuilder<T> builder,
string agentPath)
{
// ...
}
}
builderIResourceBuilder<T>The resource builder.
agentPathstringThe path to the opentelemetry-javaagent.jar file.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
ArgumentExceptionagentPath is null, empty, or whitespace.
The agent is not downloaded. Obtain it as a build dependency, or from https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases, and point this at the resulting file. The OTLP exporter is configured by AddJavaApp regardless of whether an agent is used, so call this only when you want the agent's automatic instrumentation.

A relative agentPath is resolved against the application directory and made absolute when running locally. This is required, not cosmetic: JAVA_TOOL_OPTIONS is inherited by every JVM started beneath the resource, and build tools start JVMs whose working directory is not the application directory. The Gradle daemon, for example, starts from its own distribution directory, so a relative -javaagent: path fails to resolve and the daemon dies during VM initialization with "Error opening zip file or JAR manifest missing".

A relative path names a file the build produces, so Aspire runs that build as its own resource in run mode and holds the application until it finishes. An absolute path names a file that exists independently of the build, so no build resource is added.

In publish mode a relative path is rewritten to the location the generated Dockerfile copies the agent to, because the path has to be interpreted inside the container rather than on the build machine. An absolute path is emitted unchanged, since it cannot have come from the build context and must be supplied by the base image or a mount.

WithWrapperPath(IResourceBuilder<T>, string)Section titled WithWrapperPath(IResourceBuilder<T>, string)extensionIResourceBuilder<T>
Overrides the build tool wrapper script path, for repositories whose wrapper is not in the default location or does not use the default name.
public static class JavaHostingExtensions
{
public static IResourceBuilder<T> WithWrapperPath<T>(
this IResourceBuilder<T> builder,
string wrapperPath)
{
// ...
}
}
builderIResourceBuilder<T>The ApplicationModel.IResourceBuilder`1 to configure.
wrapperPathstringThe path to the wrapper script, absolute or relative to the resource's working directory.
IResourceBuilder<T>A reference to the ApplicationModel.IResourceBuilder`1.
ArgumentNullExceptionbuilder is null.
ArgumentExceptionwrapperPath is null, empty, or whitespace.
May be called before or after the build tool is configured. A later call re-points anything that already resolved the default wrapper, so the result does not depend on the order of builder calls.