quarkusio/quarkus · error · RuntimeException

Unable to determine groupId and artifactId of the jar that c

Error message

Unable to determine groupId and artifactId of the jar that contains ${clazz.getName()}

What it means

The catch-all failure of ArtifactInfoUtil.groupIdAndArtifactId: an IOException or URISyntaxException occurred while opening the class's jar/filesystem or reading its metadata. The RuntimeException wraps the original cause ('...caused by...') and reports the class whose jar coordinates could not be determined.

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/util/ArtifactInfoUtil.java:118

                if (isTargetClasses(location)) {
                    Path mavenArchiver = location.getParent().resolve("maven-archiver");
                    if (mavenArchiver.toFile().canRead()) {
                        Entry<String, String> ret = groupIdAndArtifactId(mavenArchiver);
                        if (ret == null) {
                            throw new RuntimeException(
                                    "Unable to determine groupId and artifactId of the extension that contains "
                                            + clazz.getName()
                                            + " because the directory doesn't contain the necessary metadata");
                        }
                        return ret;
                    }
                }
                return new AbstractMap.SimpleEntry<>("unspecified", "unspecified");
            } else {
                return new AbstractMap.SimpleEntry<>("unspecified", "unspecified");
            }
        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException("Unable to determine groupId and artifactId of the jar that contains " + clazz.getName(),
                    e);
        }
    }

    /**
     * Checks if the given path represents a Maven target/classes directory.
     * This works for any module type (deployment, runtime, spi, etc.).
     */
    static boolean isTargetClasses(Path location) {
        if (location == null || location.getFileName() == null) {
            return false;
        }
        if (!location.getFileName().toString().equals("classes")) {
            return false;
        }
        Path target = location.getParent();
        return !(target == null || target.getFileName() == null || !target.getFileName().toString().equals("target"));
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Check the cause chain (getCause) to see whether it is IOException or URISyntaxException and fix the underlying file/URI problem
  2. Ensure the class passed belongs to a plain jar file or file: directory, not a jrt:/ or nested-jar location
  3. Verify the jar is readable and not corrupt (jar tf <file>)
  4. Catch the RuntimeException and fall back to 'unspecified' coordinates when the info is optional

Example fix

// before
var ga = ArtifactInfoUtil.groupIdAndArtifactId(String.class); // jrt:/ location -> fails
// after
if (String.class.getProtectionDomain().getCodeSource() == null || !isPlainJar(String.class)) {
    var ga = new AbstractMap.SimpleEntry<>("unspecified", "unspecified");
} else {
    var ga = ArtifactInfoUtil.groupIdAndArtifactId(String.class);
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean resolvableCodeSource(Class<?> clazz) throws URISyntaxException {
    var cs = clazz.getProtectionDomain().getCodeSource();
    if (cs == null || cs.getLocation() == null) return false;
    var uri = cs.getLocation().toURI();
    return uri.getScheme().equals("file") || uri.getScheme().equals("jar");
}

Try / catch

try {
    var ga = ArtifactInfoUtil.groupIdAndArtifactId(clazz);
} catch (RuntimeException e) {
    // e.getCause() is IOException | URISyntaxException
    log.warnf(e.getCause(), "I/O failure resolving coordinates for %s", clazz.getName());
}

Prevention

When it happens

Trigger: The code location URI is malformed (URISyntaxException) or reading the jar filesystem fails (IOException): corrupt jar, jar deleted/moved between resolution and read, permission denied, unsupported URI scheme (e.g. jrt:/ or nested Spring Boot jar URLs).

Common situations: Running on JRE class library classes (jrt:/ URLs in Java 9+); nested-jar classloading schemes; race conditions where the jar is replaced during a hot redeploy; read-protected files or NFS-mounted repositories.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/0ed0c1a9ff5cf73b. Report an issue: GitHub.