{"record":{"id":"7af9df225df4d608","repo":"eclipse-vertx/vert.x","slug":"packagefolderurl-is-not-a-jar-file","errorCode":null,"errorMessage":"${packageFolderURL} is not a JAR file","messagePattern":"(.+?) is not a JAR file","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/impl/verticle/PackageHelper.java","lineNumber":88,"sourceCode":"  private static List<JavaFileObject> browseJar(URL packageFolderURL) {\n    List<JavaFileObject> result = new ArrayList<>();\n    try {\n      String jarUri = packageFolderURL.toExternalForm().split(\"!\")[0];\n      JarURLConnection jarConn = (JarURLConnection) packageFolderURL.openConnection();\n      String rootEntryName = jarConn.getEntryName();\n      int rootEnd = rootEntryName.length() + 1;\n\n      Enumeration<JarEntry> entryEnum = jarConn.getJarFile().entries();\n      while (entryEnum.hasMoreElements()) {\n        JarEntry jarEntry = entryEnum.nextElement();\n        String name = jarEntry.getName();\n        if (name.startsWith(rootEntryName) && name.indexOf('/', rootEnd) == -1 && name.endsWith(CLASS_FILE)) {\n          String binaryName = name.replaceAll(\"/\", \".\").replaceAll(CLASS_FILE + \"$\", \"\");\n          result.add(new CustomJavaFileObject(URI.create(jarUri + \"!/\" + name), JavaFileObject.Kind.CLASS, binaryName));\n        }\n      }\n    } catch (Exception e) {\n      throw new RuntimeException(packageFolderURL + \" is not a JAR file\", e);\n    }\n    return result;\n  }\n}\n","sourceCodeStart":70,"sourceCodeEnd":93,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/impl/verticle/PackageHelper.java#L70-L93","documentation":"PackageHelper.browseJar scans a URL expected to point to a JAR archive to enumerate compiled verticle classes. When the URL cannot be opened as a JAR (the underlying JarInputStream/entries access fails), it wraps the failure in this RuntimeException identifying the offending URL.","triggerScenarios":"Calling verticle resolution with a package folder URL that points to a plain directory, corrupt JAR, or non-archive resource during classpath scanning for verticles in a package.","commonSituations":"Classpath misconfiguration where a JAR was replaced by an exploded directory or truncated download; passing a directory URL to a helper that assumes a jar: URI.","solutions":["Verify the URL/classpath entry actually points to a valid, non-corrupt JAR (test with `jar tf file.jar`)","Check the cause exception chained in the RuntimeException for the real I/O failure","If classes are in an exploded directory, ensure the resolution path used is the directory variant, not the JAR variant"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"try (JarFile jf = new JarFile(new File(url.toURI()))) { /* valid jar */ } catch (Exception e) { /* not a jar */ }","typeGuard":null,"tryCatchPattern":"try {\n  vertx.deployVerticle(packageName);\n} catch (RuntimeException e) {\n  if (e.getCause() != null) { log.warn(\"Classpath scan failed\", e.getCause()); }\n  // fall back to explicit verticle class names\n}","preventionTips":["Verify JAR integrity after build/publish (jar tf)","Don't mix exploded-dir and jar: URLs for the same package","Keep classpath entries in sync between build tool and runtime"],"tags":["classpath","jar","verticle-resolution"],"backgroundTag":"file-read-failed","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}