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
- Build the jar with Maven so META-INF/maven/<groupId>/<artifactId>/pom.properties is included, or configure the shade plugin to keep it
- Return 'unspecified' handling upstream if the caller only needs best-effort coordinates — wrap in try-catch
- Pass a class from a proper Maven-built extension artifact instead of a shaded jar
- 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
- Avoid shipping shaded/uber jars for artifacts whose coordinates Quarkus must resolve
- Keep META-INF/maven/** in shade/relocation plugin filters
- Build library jars with Maven or explicitly add pom.properties
- Prefer passing classes from Quarkus extension artifacts
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
- Unable to determine groupId and artifactId of the extension
- Unable to determine groupId and artifactId of the jar that c
- Failed to resolve version range for ${artifact}
- Unable to parse pom file: ${pom}
- The specified %s identifier (%s) contains invalid characters
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2fb0be62b225fdcf.
Report an issue: GitHub.