{"record":{"id":"30f6f5ba50777290","repo":"testcontainers/testcontainers-java","slug":"failed-to-process-jar-file-when-extracting-classpath","errorCode":null,"errorMessage":"Failed to process JAR file when extracting classpath resource: <hostPath>","messagePattern":"Failed to process JAR file when extracting classpath resource: <hostPath>","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/testcontainers/utility/MountableFile.java","lineNumber":257,"sourceCode":"        String internalPath = hostPath.replaceAll(\"[^!]*!/\", \"\");\n\n        try (JarFile jarFile = new JarFile(urldecodedJarPath)) {\n            Enumeration<JarEntry> entries = jarFile.entries();\n\n            while (entries.hasMoreElements()) {\n                JarEntry entry = entries.nextElement();\n                final String name = entry.getName();\n                if (name.startsWith(internalPath)) {\n                    log.debug(\n                        \"Copying classpath resource(s) from {} to {} to permit Docker to bind\",\n                        hostPath,\n                        tmpLocation\n                    );\n                    copyFromJarToLocation(jarFile, entry, internalPath, tmpLocation);\n                }\n            }\n        } catch (IOException e) {\n            throw new IllegalStateException(\n                \"Failed to process JAR file when extracting classpath resource: \" + hostPath,\n                e\n            );\n        }\n\n        // Mark temporary files/dirs for deletion at JVM shutdown\n        deleteOnExit(tmpLocation.toPath());\n\n        try {\n            return tmpLocation.getCanonicalPath();\n        } catch (IOException e) {\n            throw new IllegalStateException(e);\n        }\n    }\n\n    private File createTempDirectory() {\n        try {\n            if (SystemUtils.IS_OS_MAC) {","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/core/src/main/java/org/testcontainers/utility/MountableFile.java#L239-L275","documentation":"MountableFile wraps classpath resources so they can be mounted into containers. When it must extract a resource that lives inside a JAR (e.g. from a fat jar) to a temp location, any IOException while reading the JAR or copying the entry is wrapped in this IllegalStateException. It means Testcontainers could not materialize the classpath resource on the host filesystem, not that the resource itself is necessarily missing (missing resources fail earlier with IllegalArgumentException).","triggerScenarios":"Calling MountableFile.forClasspathResource(...) (directly or via withClasspathResourceMapping / copyFileToContainer) where the resource is inside a JAR, and copyFromJarToLocation throws IOException: corrupt/unreadable JAR, entry is a directory with IO problems, disk full, or temp dir not writable.","commonSituations":"Running tests from a Spring Boot fat jar or shaded jar where resources are nested jars; read-only or full temp directories; JAR corrupted by partial builds; running under a security manager or restricted filesystem that blocks reading the jar.","solutions":["Rebuild the artifact/JAR (mvn clean package or gradle clean build) to rule out a corrupt jar","Ensure the temp directory (java.io.tmpdir) exists, is writable, and has free space","Verify the resource exists on the classpath; if it is a directory of files in the jar, confirm the path points to an entry the code can copy","As a workaround, copy the resource out of the jar yourself and mount it with MountableFile.forHostFile(...)"],"exampleFix":"// before\nMountableFile.forClasspathResource(\"config/app.conf\"); // fails when inside nested/fat jar\n// after\nFile extracted = extractViaClassloader(\"config/app.conf\"); // write to your own temp file\nMountableFile.forHostFile(extracted);","handlingStrategy":"validation","validationCode":"String path = \"config/app.conf\";\nif (MountableFile.class.getClassLoader().getResource(path) == null)\n    throw new IllegalStateException(\"Classpath resource missing: \" + path);\n// also verify tmpdir is writable:\nFile tmp = new File(System.getProperty(\"java.io.tmpdir\"));\nif (!tmp.canWrite()) throw new IllegalStateException(\"Temp dir not writable: \" + tmp);","typeGuard":"boolean isExtractable(String path) {\n    URL u = Thread.currentThread().getContextClassLoader().getResource(path);\n    return u != null && List.of(\"jar\", \"file\").contains(u.getProtocol());\n}","tryCatchPattern":"try {\n    MountableFile.forClasspathResource(path);\n} catch (IllegalStateException e) {\n    // fallback: extract manually via classloader and mount a host file\n}","preventionTips":["Prefer running tests from exploded classes directories rather than fat/nested jars","Check java.io.tmpdir is writable and has disk space in CI","Rebuild artifacts cleanly before test runs to avoid corrupt jars"],"tags":["classpath","jar-extraction","docker-mount","io"],"backgroundTag":"file-read-failed","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}