microsoft/aspire · error · DistributedApplicationException
Java application ' ' has no in ' ' or in the build root…
Error message
Java application '{resource.Name}' has no {wrapperName} in '{resource.WorkingDirectory}' or in the build root above it. Aspire runs Java applications through the project's own wrapper so that every build uses the tool version the repository pins. Generate one with {GenerateWrapperCommand(tool)}, or point at an existing wrapper with WithWrapperPath. What it means
Aspire runs Java applications through the project's own wrapper so every build uses the tool version the repository pins. When neither the resource's working directory nor the build root above it contains the default wrapper (mvnw/mvnw.cmd or gradlew/gradlew.bat), and no WithWrapperPath was given, ValidateWrapperExists throws with instructions to generate a wrapper or point at an existing one.
Solutions
- Generate the wrapper in the project: 'mvn wrapper:wrapper' for Maven or 'gradle wrapper' for Gradle, and commit it
- Point at an existing wrapper elsewhere with WithWrapperPath("path/to/wrapper")
- Move/copy the wrapper into the resource's working directory or the build root above it
Example fix
// before
// project has no mvnw; AppHost: builder.AddJavaApp("app", dir).WithMavenGoal("spring-boot:run")
// after: run 'mvn wrapper:wrapper' in the project, then
builder.AddJavaApp("app", dir).WithMavenGoal("spring-boot:run"); // mvnw now found Defensive patterns
Strategy: validation
Validate before calling
var wrapperName = OperatingSystem.IsWindows() ? "mvnw.cmd" : "mvnw"; // or gradlew(.bat)
if (!File.Exists(Path.Combine(workingDirectory, wrapperName)) && !File.Exists(Path.Combine(buildRoot, wrapperName)))
{
// run 'mvn wrapper:wrapper' or 'gradle wrapper' before starting the AppHost
} Type guard
bool HasWrapper(string dir, string name) => File.Exists(Path.Combine(dir, name));
Try / catch
try { ConfigureJavaApp(); }
catch (DistributedApplicationException ex) when (ex.Message.Contains("has no mvnw") || ex.Message.Contains("has no gradlew"))
{
// generate the wrapper or point at one via WithWrapperPath
} Prevention
- Commit mvnw/gradlew (and .cmd variants) to every Java project
- On Windows ensure gradlew.bat/mvnw.cmd exist, not just the shell scripts
- Run 'gradle wrapper' or 'mvn wrapper:wrapper' when creating new Java projects used by Aspire
When it happens
Trigger: AddJavaApp with a build-tool launch (WithMavenGoal/WithGradleTask or WithMavenBuild/WithGradleBuild) where the project directory lacks the wrapper script; the wrapper exists only in the developer's global installation, not the repo.
Common situations: Cloning a repo without wrapper files (gitignored or never committed); on Windows expecting 'gradlew' instead of 'gradlew.bat'; project layout where the wrapper lives in a parent directory outside the searched build root.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Java application ' ' has no wrapper at ' '. That path came…
- The Java AppHost project in
- Directory ' ' contains both Maven and Gradle build files…
- Java application ' ' cannot be published because its has no…
- Java application ' ' cannot be published because the…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/4f2b317dc3f44d97.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Java/JavaHostingExtensions.cs:1545
{
var wrapperPath = JavaBuildToolResolver.ResolveWrapperPath(resource, tool, OperatingSystem.IsWindows());
if (File.Exists(wrapperPath))
{
return;
}
if (resource.HasAnnotationOfType<WrapperAnnotation>())
{
throw new DistributedApplicationException(
$"Java application '{resource.Name}' has no wrapper at '{wrapperPath}'. That path came " +
$"from {nameof(WithWrapperPath)} and is resolved relative to the application's working " +
$"directory '{resource.WorkingDirectory}'.");
}
var wrapperName = JavaBuildToolResolver.GetDefaultWrapperName(tool, OperatingSystem.IsWindows());
throw new DistributedApplicationException(
$"Java application '{resource.Name}' has no {wrapperName} in '{resource.WorkingDirectory}' " +
$"or in the build root above it. Aspire runs Java applications through the project's own " +
$"wrapper so that every build uses the tool version the repository pins. Generate one with " +
$"{GenerateWrapperCommand(tool)}, or point at an existing wrapper with {nameof(WithWrapperPath)}.");
}
/// <summary>
/// Arranges for the resource's wrapper to be validated once its configuration is final.
/// </summary>
private static IResourceBuilder<T> WithDeferredWrapperValidation<T>(
this IResourceBuilder<T> builder,
JavaBuildTool tool) where T : JavaAppResource
{
// WithMavenGoal and WithMavenBuild both want this, and either may be called more than once, so
// the subscription is registered at most once per tool.
if (builder.Resource.Annotations.OfType<JavaWrapperValidationAnnotation>().Any(a => a.Tool == tool))
{
return builder;View on GitHub (pinned to 25830f84bd)