alibaba/spring-ai-alibaba · error · RuntimeException

Failed to copy JAR file:

Error message

Failed to copy JAR file: 

What it means

During copyResourceJarToWorkDir, each discovered .jar path in the resources lib directory is copied into the target working directory with REPLACE_EXISTING. An IOException while copying any single JAR is wrapped in this RuntimeException carrying the JAR path.

Source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/utils/FileUtils.java:97

				throw new RuntimeException("Could not find lib directory in resources");
			}

			// Create target directory if it doesn't exist
			Path targetDir = Path.of(workDir);
			if (!Files.exists(targetDir)) {
				Files.createDirectories(targetDir);
			}

			// Get all JAR files from lib directory
			Path libPath = Path.of(libUrl.toURI());
			try (var stream = Files.walk(libPath)) {
				stream.filter(path -> path.toString().endsWith(".jar")).forEach(jarPath -> {
					try {
						Path targetPath = targetDir.resolve(jarPath.getFileName());
						Files.copy(jarPath, targetPath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
					}
					catch (IOException e) {
						throw new RuntimeException("Failed to copy JAR file: " + jarPath, e);
					}
				});
			}
		}
		catch (Exception e) {
			throw new RuntimeException("Failed to copy JAR files to working directory", e);
		}
	}

	/**
	 * Deletes all JAR files from the specified working directory.
	 * @param workDir The working directory from which the JAR files will be deleted.
	 */
	public static void deleteResourceJarFromWorkDir(String workDir) {
		try {
			Path workDirPath = Path.of(workDir);
			if (Files.exists(workDirPath)) {
				try (var stream = Files.walk(workDirPath)) {

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Read e.getCause() (IOException) and check the target workDir is writable and has free space.
  2. Ensure the work directory exists and the process user has write permission (chmod / run with proper user).
  3. Copy JARs once at startup and reuse, avoiding repeated replace races with concurrent workers.
  4. For Spring Boot fat jars, copy the resource stream via Files.copy(InputStream, target) instead of Path-to-Path if the source lives inside a nested jar.

Example fix

// before
Files.copy(jarPath, targetPath, REPLACE_EXISTING); // IOException if target dir read-only
// after
Files.createDirectories(targetDir);
if (!Files.isWritable(targetDir)) {
    throw new IOException("Work dir not writable: " + targetDir);
}
try (InputStream in = jarUrl.openStream()) {
    Files.copy(in, targetPath, REPLACE_EXISTING);
}
Defensive patterns

Strategy: try-catch

Validate before calling

Files.createDirectories(Path.of(workDir));
if (!Files.isWritable(Path.of(workDir))) {
    throw new IllegalStateException("workDir is not writable: " + workDir);
}

Try / catch

try {
    FileUtils.copyResourceJarToWorkDir(workDir);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Failed to copy JAR file:")) {
        logger.error("Per-jar copy failed: {} cause: {}", e.getMessage(), e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: Files.copy fails for a specific jarPath: target directory not writable, disk full, source JAR unreadable (permissions), or the source is a nested-jar URL whose FileSystem was closed mid-walk.

Common situations: Read-only work directory (container filesystem restrictions), insufficient disk space, Spring Boot nested jar resource streams closed before copy, or concurrent processes competing for the same target file.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/887c12a38137a994. Report an issue: GitHub.