karatelabs/karate · error · RuntimeException

Failed to create resource from classpath

Error message

Failed to create resource from classpath: {path}

What it means

When a classpath resource is found but lives inside a JAR and the JAR file-system provider is unavailable (e.g. jpackage/JavaFX runtimes), Resource.path() falls back to streaming the resource's content into a MemoryResource. If even that streaming read fails (url.openStream() or decode error), it wraps the failure in this RuntimeException; the same message also wraps any other failure while converting the classpath URL to a PathResource.

Solutions

  1. Inspect the wrapped cause (ex) to see why the jar stream failed
  2. Rebuild/redeploy the jar if it is corrupt; verify with jar tf
  3. Avoid packaging restrictions: run with the resources exploded on the filesystem instead of inside a jar when using jpackage
  4. Add the JDK zip file-system provider if missing (ensure a full JDK/JRE, not a stripped runtime image)

Example fix

// before (resource inside jar, stripped runtime without zipfs)
Resource r = Resource.path("classpath:config.json");
// after: ship config outside the jar and load via file path
Resource r = Resource.path("file:" + System.getProperty("app.home") + "/config.json");
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: prefer loading external config files directly when running packaged
Path external = Paths.get(System.getProperty("app.home"), "config.json");
Resource r = Files.exists(external)
    ? Resource.path("file:" + external)
    : Resource.path("classpath:config.json");

Try / catch

try {
    Resource r = Resource.path("classpath:config.json");
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Failed to create resource from classpath:")) {
        logger.error("classpath fallback failed, cause: {}", e.getCause());
    }
}

Prevention

When it happens

Trigger: Classpath resource inside a JAR where urlToPath conversion fails AND the fallback openStream() also throws (corrupt jar, sealed/locked jar file, security policy blocking stream open); or an unexpected exception during the URL-to-Path conversion itself.

Common situations: Running a packaged app (jpackage) where the zipfs provider is missing; jar corrupted during deployment; resource stream blocked by a restrictive SecurityManager or module-access policy; reading from a jar being concurrently rewritten.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/9fda79b221fc4ed7. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/common/Resource.java:586

            }
            if (url == null) {
                url = ClassLoader.getSystemResource(relativePath);
            }
            if (url == null) {
                throw new ResourceNotFoundException(path);
            }
            // Convert URL to Path for classpath resources
            try {
                Path resourcePath = urlToPath(url, null);
                return new PathResource(resourcePath, FileUtils.WORKING_DIR.toPath(), true);
            } catch (java.nio.file.ProviderNotFoundException e) {
                // JAR file system provider not available (common in jpackage/JavaFX apps)
                // Fall back to streaming the resource content (root defaults to SYSTEM_TEMP)
                try (java.io.InputStream is = url.openStream()) {
                    String content = FileUtils.toString(is);
                    return new MemoryResource(content);
                } catch (Exception ex) {
                    throw new RuntimeException("Failed to create resource from classpath: " + path, ex);
                }
            } catch (Exception e) {
                throw new RuntimeException("Failed to create resource from classpath: " + path, e);
            }
        } else if (path.startsWith(FILE_COLON)) {
            // Handle file: prefix by stripping it and creating PathResource
            String filePath = normalizePath(removePrefix(path));
            return new PathResource(Path.of(filePath));
        } else {
            return new PathResource(Path.of(normalizePath(path)));
        }
    }

    /**
     * Scans classpath directories for resources with the given extension.
     * Handles both file system classpath entries and JARs.
     *
     * @param classpathDir the classpath directory (without "classpath:" prefix)

View on GitHub (pinned to a22eb90246)