microsoft/aspire · error · InvalidOperationException

cannot be used when a JAR path has been specified. Use…

Error message

{methodName} cannot be used when a JAR path has been specified. Use either the AddJavaApp overload that takes a jarPath, or {methodName}, not both.

What it means

Aspire's Java hosting support allows launching a Java application either from a prebuilt JAR (AddJavaApp with jarPath) or through a build tool like Maven/Gradle. These two launch modes are mutually exclusive because the build tool decides what to run, so any -jar argument would be silently ignored. The library throws this InvalidOperationException when WithBuildToolLaunch is called on a resource that already has a JavaJarPathAnnotation.

Solutions

  1. Remove the jarPath argument from the AddJavaApp call and use the overload without jarPath
  2. Remove the WithMavenGoal/WithGradleTask call if you intend to run the prebuilt JAR
  3. Choose one launch mode: JAR path or build tool, never both

Example fix

// before
var java = builder.AddJavaApp("app", workingDirectory: "..").WithJarPath("app.jar").WithMavenGoal("spring-boot:run");
// after
var java = builder.AddJavaApp("app", workingDirectory: "..").WithMavenGoal("spring-boot:run");
Defensive patterns

Strategy: validation

Validate before calling

if (resource.HasAnnotationOfType<JavaJarPathAnnotation>())
{
    throw new InvalidOperationException("Do not call WithMavenGoal/WithGradleTask on a JAR-based Java app resource.");
}

Type guard

var isJarBased = builder.Resource.HasAnnotationOfType<JavaJarPathAnnotation>();

Try / catch

try { java.WithMavenGoal("spring-boot:run"); }
catch (InvalidOperationException ex) when (ex.Message.Contains("JAR path has been specified"))
{
    // pick one launch mode: drop the jarPath or drop the build-tool launch
}

Prevention

When it happens

Trigger: Calling WithMavenGoal or WithGradleTask (which route through WithBuildToolLaunch) on a resource created via the AddJavaApp overload that takes a jarPath.

Common situations: Switching a resource from a prebuilt-JAR setup to a build-tool run by adding a Maven/Gradle launch call without removing the jarPath overload; copy-pasting resource configuration between projects that use different launch styles.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/6f10cd51ecbfc05c. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Java/JavaHostingExtensions.cs:693

        ArgumentException.ThrowIfNullOrWhiteSpace(task);
        ArgumentNullException.ThrowIfNull(args);

        return builder.WithBuildToolLaunch(JavaBuildTool.Gradle, task, args, nameof(WithGradleTask));
    }

    private static IResourceBuilder<T> WithBuildToolLaunch<T>(
        this IResourceBuilder<T> builder,
        JavaBuildTool tool,
        string goalOrTask,
        string[] args,
        string methodName) where T : JavaAppResource
    {
        // A prebuilt JAR and a build-tool launch are mutually exclusive: the build tool decides what to
        // run, so -jar would be ignored. CommunityToolkit rejects both combinations; this port only
        // rejected the Gradle half, letting a Maven+JAR application silently drop its JAR.
        if (builder.Resource.HasAnnotationOfType<JavaJarPathAnnotation>())
        {
            throw new InvalidOperationException(
                $"{methodName} cannot be used when a JAR path has been specified. Use either the " +
                $"{nameof(AddJavaApp)} overload that takes a jarPath, or {methodName}, not both.");
        }

        if (builder.Resource.TryGetLastAnnotation<JavaBuildToolAnnotation>(out var existing) && existing.Tool != tool)
        {
            throw new InvalidOperationException(
                $"{methodName} cannot be used when the application is already configured to launch with " +
                $"{existing.Tool}. A Java application is launched by a single build tool.");
        }

        if (builder.Resource.TryGetLastAnnotation<JavaBuildStepAnnotation>(out var buildStep) && buildStep.Tool != tool)
        {
            throw new InvalidOperationException(
                $"{methodName} cannot be used when the application is already configured to build with " +
                $"{buildStep.Tool}. A Java application is built and launched by a single build tool.");
        }

View on GitHub (pinned to 25830f84bd)