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()} because the jar doesn't contain the necessary metadata

What it means

ArtifactInfoUtil.groupIdAndArtifactId resolves the Maven groupId:artifactId of the artifact containing a given class. When the class lives inside a .jar that has no POM metadata (maven/pom.properties or similar) embedded, this RuntimeException is thrown. Quarkus needs these coordinates mainly for Dev UI / console info about extensions.

Source

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

                            Path jarParentDir = p.getParent(); // .../module/target (if JAR is in target dir)
                            if (classesTargetDir != null && classesTargetDir.equals(jarParentDir)) {
                                String artifactId = i.getArtifactId();
                                if (artifactId.endsWith(DEPLOYMENT)) {
                                    artifactId = artifactId.substring(0, artifactId.length() - DEPLOYMENT.length());
                                }
                                return new AbstractMap.SimpleEntry<>(i.getGroupId(), artifactId);
                            }
                        }
                    }
                }
            }

            if (codeLocation.toString().endsWith(".jar")) {
                // Search inside the jar for pom properties, needed for workspace artifacts
                try (FileSystem fs = ZipUtils.newFileSystem(Paths.get(codeLocation.toURI()))) {
                    Entry<String, String> ret = groupIdAndArtifactId(fs);
                    if (ret == null) {
                        throw new RuntimeException("Unable to determine groupId and artifactId of the jar that contains "
                                + clazz.getName() + " because the jar doesn't contain the necessary metadata");
                    }
                    return ret;
                }
            } else if ("file".equals(codeLocation.getProtocol())) {
                // E.g. /quarkus/extensions/arc/deployment/target/classes/io/quarkus/arc/deployment/devconsole
                // This can happen if you run an example app in dev mode
                // and this app is part of a multi-module project which also declares the extension
                // Just try to locate the pom.properties file in the target/maven-archiver directory
                // Note that this hack will not work if addMavenDescriptor=false or if the pomPropertiesFile is overridden
                Path location = Paths.get(codeLocation.toURI());
                while (!isTargetClasses(location) && location.getParent() != null) {
                    location = location.getParent();
                }
                if (isTargetClasses(location)) {
                    Path mavenArchiver = location.getParent().resolve("maven-archiver");
                    if (mavenArchiver.toFile().canRead()) {
                        Entry<String, String> ret = groupIdAndArtifactId(mavenArchiver);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Build the jar with Maven so META-INF/maven/<groupId>/<artifactId>/pom.properties is included, or configure the shade plugin to keep it
  2. Return 'unspecified' handling upstream if the caller only needs best-effort coordinates — wrap in try-catch
  3. Pass a class from a proper Maven-built extension artifact instead of a shaded jar
  4. If it is your own artifact, verify the jar contents (unzip -l | grep pom.properties)

Example fix

// before
Entry<String,String> ga = ArtifactInfoUtil.groupIdAndArtifactId(ShadedLib.class); // throws
// after
Entry<String,String> ga;
try {
    ga = ArtifactInfoUtil.groupIdAndArtifactId(ShadedLib.class);
} catch (RuntimeException e) {
    ga = new AbstractMap.SimpleEntry<>("unspecified", "unspecified");
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean jarHasMavenMetadata(Class<?> clazz) throws Exception {
    var loc = clazz.getProtectionDomain().getCodeSource().getLocation();
    if (loc == null || !loc.toString().endsWith(".jar")) return false;
    try (var fs = java.nio.file.FileSystems.newFileSystem(java.nio.file.Paths.get(loc.toURI()), (ClassLoader) null);
         var walk = java.nio.file.Files.walk(fs.getPath("META-INF/maven"))) {
        return walk.filter(p -> p.getFileName().toString().equals("pom.properties")).findFirst().isPresent();
    } catch (Exception e) { return false; }
}

Try / catch

try {
    var ga = ArtifactInfoUtil.groupIdAndArtifactId(clazz);
    use(ga.getKey(), ga.getValue());
} catch (RuntimeException e) {
    log.warnf(e, "No Maven metadata for jar of %s; using unspecified", clazz.getName());
    use("unspecified", "unspecified");
}

Prevention

When it happens

Trigger: Calling ArtifactInfoUtil.groupIdAndArtifactId(Class) (or a variant) with a class whose code location is a jar lacking META-INF/maven/**/pom.properties — e.g. shaded/uber jars, jars built without Maven, or relocated dependency jars.

Common situations: Shaded dependencies (fat jars) where pom.properties was stripped; jars built by Gradle/sbt without Maven metadata; application classes packaged by a custom build; third-party jars repackaged by shadow plugin.

Related errors


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