{"record":{"id":"c7fe47ea301e2fd8","repo":"eclipse-vertx/vert.x","slug":"nesting-more-than-two-levels-is-not-supported","errorCode":null,"errorMessage":"Nesting more than two levels is not supported","messagePattern":"Nesting more than two levels is not supported","errorType":"exception","errorClass":"VertxException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/file/impl/FileResolverImpl.java","lineNumber":364,"sourceCode":"                @Override\n                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\n                  Path relative = path.relativize(file);\n                  cache.cacheFile(relative.toString(), file.toFile(), false);\n                  return FileVisitResult.CONTINUE;\n                }\n              });\n            } else {\n              // jar:file:/path/to/nesting.jar!/path/to/nested.jar\n              try (ZipFile zip = new ZipFile(root)) {\n                extractFilesFromJarFile(zip, fileName);\n              }\n            }\n          } else {\n            throw new VertxException(\"Unexpected nested url : \" + nestedURL);\n          }\n          break;\n        default:\n          throw new VertxException(\"Nesting more than two levels is not supported\");\n      }\n    } catch (IOException e) {\n      throw new VertxException(FileSystemImpl.getFileAccessErrorMessage(\"unpack\", url.toString()), e);\n    }\n    return cache.getFile(fileName);\n  }\n\n  /**\n   * Extract a subset of the entries to the cache.\n   */\n  private void extractFilesFromJarFile(ZipFile zip, String entryFilter) throws IOException {\n    Enumeration<? extends ZipEntry> entries = zip.entries();\n    while (entries.hasMoreElements()) {\n      ZipEntry entry = entries.nextElement();\n      String name = entry.getName();\n      int len = name.length();\n      if (len == 0) {\n        return;","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/file/impl/FileResolverImpl.java#L346-L382","documentation":"FileResolverImpl.unpackFromJarURL throws this VertxException when it encounters a jar-within-jar (or deeper) URL scheme while extracting a resource from an embedded jar. Vert.x's file resolver only understands at most two levels of nesting (e.g. an entry inside a jar), and any deeper 'jar:file:...!/...!/...' URL falls into the default switch branch. It is an internal invariant check protecting the unpacking algorithm, not a user-recoverable condition.","triggerScenarios":"Calling vertx.fileSystem().propsAsync/copy etc. (or deploying verticles) where a resource on the classpath resolves to a URL with more than two '!' nesting levels, typically 'jar:jar:file:...!/inner.jar!/resource' produced by fat jars nested inside fat jars or Spring Boot nested-jar layout used without its own classloader.","commonSituations":"Spring Boot executable jars (Boot's nested jar: URLs) run through plain Vert.x classloading; shading an uber-jar that itself gets repackaged; running from a jar extracted into another jar by a build plugin; container images that bundle the app jar inside a second jar.","solutions":["Run the application as a single-level fat jar (use the standard vertx-maven-plugin / gradle shadowJar packaging) so resources sit directly in the top jar.","If using Spring Boot nested jars, launch via Spring Boot's launcher/classloader rather than Vert.x's FileResolver, or extract the jar before running (java -Dvertx.disableFileCPResolving=true after unpacking).","Set vertx.disableFileCPResolving=true and copy the resource out yourself with java.util.zip APIs that support arbitrary nesting.","Restructure the artifact so the resource is a direct classpath entry (move it out of the nested jar)."],"exampleFix":"// before: resources inside a Spring Boot nested jar read via vertx.fileSystem().readFile(\"config.json\")\n// after: launch with Boot loader or extract first\njava -jar app.jar  // Boot LaunchedURLClassLoader handles nesting\n// or in Docker:\nRUN java -Djarmode=tools -jar app.jar extract --destination /app\nENTRYPOINT [\"java\", \"-jar\", \"/app/app.jar\"]","handlingStrategy":"validation","validationCode":"URL url = cl.getResource(name);\nint depth = 0;\nfor (int i = 0; i < url.toString().length() - 1; i++)\n  if (url.toString().charAt(i) == '!' && url.toString().charAt(i + 1) == '/') depth++;\nif (depth > 1) throw new IllegalStateException(\n    \"Resource nested more than two levels deep: \" + url +\n    \" — flatten the jar layout or disable FileCP resolving\");","typeGuard":"static boolean isOverlyNestedJarUrl(URL url) {\n  String s = url.toString();\n  return s.startsWith(\"jar:\") && s.split(\"!\").length > 2;\n}","tryCatchPattern":"try {\n  vertx.fileSystem().readFileBlocking(resource);\n} catch (VertxException e) {\n  if (e.getMessage().contains(\"Nesting more than two levels\")) {\n    // fall back to ClassLoader stream read\n  } else throw e;\n}","preventionTips":["Package a single-level fat jar with vertx-maven-plugin or Gradle shadowJar","Do not run Spring Boot nested-jar layouts under plain Vert.x classloading","Avoid repackaging/shading an already-assembled fat jar","Read nested resources via ClassLoader streams instead of file-system APIs"],"tags":["file-system","jar-nesting","classpath","fat-jar"],"backgroundTag":"unsupported-operation","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}