microsoft/aspire · error · DistributedApplicationException
Java application ' ' cannot be published because there is…
Error message
Java application '{resource.Name}' cannot be published because there is no {defaultWrapperName} in '{appDirectory}'. Aspire builds the image with the project's own wrapper so the container uses the tool version the repository pins. Generate one with {JavaHostingExtensions.GenerateWrapperCommand(tool)}, or point at an existing wrapper with WithWrapperPath. What it means
When no wrapper was explicitly configured, Aspire expects the project's own default wrapper (mvnw or gradlew, non-Windows name) inside the build context directory and throws if it is absent. Aspire deliberately builds the image with the repository-pinned wrapper so the container uses the same tool version the repo pins. The error tells you how to generate the wrapper or override with an existing one.
Solutions
- Run the tool's wrapper generation command (JavaHostingExtensions.GenerateWrapperCommand(tool), e.g. 'mvn wrapper:wrapper' or 'gradle wrapper') in the app directory and commit the result.
- Call WithWrapperPath to point at an existing wrapper inside the app directory.
- Copy an existing mvnw/gradlew (plus .mvn/ or gradle/wrapper supporting files) into the app directory.
Example fix
// before
builder.AddJavaApp("api", "src/Api"); // no mvnw in src/Api
// after
// cd src/Api && mvn wrapper:wrapper
builder.AddJavaApp("api", "src/Api"); // mvnw now present Defensive patterns
Strategy: validation
Validate before calling
var dir = "src/Api";
if (!File.Exists(Path.Combine(dir, "mvnw")) && !File.Exists(Path.Combine(dir, "gradlew")))
Console.WriteLine("Generate a wrapper: mvn wrapper:wrapper or gradle wrapper"); Try / catch
try { /* publish */ }
catch (DistributedApplicationException ex) when (ex.Message.Contains("there is no"))
{ /* run mvn wrapper:wrapper / gradle wrapper, then republish */ } Prevention
- Run 'mvn wrapper:wrapper' or 'gradle wrapper' when creating a new project
- Do not gitignore mvnw/gradlew or their support directories
- Adopt the wrapper as the standard build entry point for the repo
When it happens
Trigger: Publishing an AddJavaApp resource without WithWrapperPath where the app directory contains pom.xml/build.gradle but no mvnw/gradlew script (and its sibling files).
Common situations: Fresh Maven/Gradle projects created without 'mvn wrapper:wrapper' or 'gradle wrapper'; wrapper files stripped by .gitignore; template-generated projects that only commit build files; CI checkouts that exclude wrapper jars/scripts.
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 ' ' cannot be published because its has no…
- Java application ' ' cannot be published because its…
- Java application ' ' cannot be published because the…
- ArgumentOutOfRangeException: Specified argument was out of…
- Java application ' ' cannot be published because its…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/3a82a5baf9bf2bff.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Java/JavaDockerfileGenerator.cs:1062
{
throw new DistributedApplicationException(
$"Java application '{resource.Name}' cannot be published because its wrapper " +
$"'{resolvedWrapperPath}' is outside the build context '{appDirectory}'. " +
"Move the wrapper into the application directory, or set the build context to a " +
"directory that contains both.");
}
if (!File.Exists(resolvedWrapperPath))
{
if (isConfigured)
{
throw new DistributedApplicationException(
$"Java application '{resource.Name}' cannot be published because the wrapper " +
$"configured with WithWrapperPath was not found at '{resolvedWrapperPath}'.");
}
var defaultWrapperName = JavaBuildToolResolver.GetDefaultWrapperName(tool, isWindows: false);
throw new DistributedApplicationException(
$"Java application '{resource.Name}' cannot be published because there is no " +
$"{defaultWrapperName} in '{appDirectory}'. Aspire builds the image with the project's " +
$"own wrapper so the container uses the tool version the repository pins. Generate one " +
$"with {JavaHostingExtensions.GenerateWrapperCommand(tool)}, or point at an existing " +
"wrapper with WithWrapperPath.");
}
// The build stage is Linux, so a Windows batch wrapper cannot run there even though it is
// the right choice on the developer's machine. Maven and Gradle ship the POSIX script
// alongside the batch one under the same base name, so prefer that sibling and only fail
// when it is genuinely absent.
// https://maven.apache.org/wrapper/ and https://docs.gradle.org/current/userguide/gradle_wrapper.html
if (Path.GetExtension(relative) is ".cmd" or ".bat")
{
var posixSibling = relative[..^Path.GetExtension(relative).Length];
if (!File.Exists(Path.Combine(appDirectory, posixSibling.Replace('/', Path.DirectorySeparatorChar))))
{View on GitHub (pinned to 25830f84bd)