SonarSource/sonarqube · critical
Cannot detect path of main jar file
Error message
Cannot detect path of main jar file
What it means
AppSettingsLoaderImpl.detectHomeDir locates the SonarQube installation by resolving the code source of the org.sonar.application.App class and walking up two directory levels to find the home directory. If the class cannot be loaded or its location is not a valid URI, an IllegalStateException 'Cannot detect path of main jar file' is thrown during loader construction.
Solutions
- Start SonarQube with the official scripts (bin/run.sh / StartSonar.bat) so the application jar is on the classpath as distributed
- Verify sonar-application.jar exists in the lib directory and is not corrupted (reinstall/extract the distribution again)
- Avoid custom classloaders or shading that renames/moves org.sonar.application.App
- Move the installation to a plain path without unusual characters if URISyntaxException is the cause
Example fix
// before (custom launcher) java -cp my-custom-boot.jar org.sonar.server.Server // App class absent // after cd sonarqube-<version>/bin/linux-x86-64 && ./sonar.sh start
Defensive patterns
Strategy: try-catch
Validate before calling
try {
Class.forName("org.sonar.application.App");
} catch (ClassNotFoundException e) {
throw new IllegalStateException("sonar-application jar missing from classpath");
} Try / catch
try {
settingsLoader = new AppSettingsLoaderImpl(...);
} catch (IllegalStateException e) {
if (e.getMessage().equals("Cannot detect path of main jar file")) {
log.error("Launch SonarQube with the official start scripts; check sonar-application.jar in lib/", e.getCause());
}
throw e;
} Prevention
- Always start via the distributed bin scripts, not custom classloaders
- Verify sonar-application.jar exists in the lib directory after upgrades
- Re-extract the distribution if jars are missing or corrupted
- Install SonarQube at a plain filesystem path without exotic characters
When it happens
Trigger: Constructing AppSettingsLoaderImpl when org.sonar.application.App is missing from the classpath (ClassNotFoundException) or its code source location cannot be converted to a URI (URISyntaxException, e.g. paths with illegal characters or running from an unpacked/exotic classloader setup).
Common situations: Running the server with a repackaged or trimmed jar, launching via custom classloaders/frameworks instead of the official start scripts, jar paths with special characters (spaces are usually fine but URL-encoded quirks can break toURI), or partially extracted distributions.
Related errors
- a JVM option can't be empty and must start with '-'. The…
- a JVM option can't overwrite mandatory JVM options. The…
- a JVM option can't overwrite mandatory JVM options.
- A rule with the key ' ' already exists
- Already started
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/dae3784083628cb6.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-main/src/main/java/org/sonar/application/config/AppSettingsLoaderImpl.java:145
// supports decryption of values, so it must be used when values
// are accessed
return new Props(p);
}
private static void loadPropertiesFromEnvironment(System2 system, Properties properties, Set<String> overridableSettings) {
overridableSettings.forEach(key -> {
String environmentVarName = fromJavaPropertyToEnvVariable(key);
Optional<String> envVarValue = ofNullable(system.envVariable(environmentVarName));
envVarValue.ifPresent(value -> properties.put(key, value));
});
}
private static File detectHomeDir() {
try {
File appJar = new File(Class.forName("org.sonar.application.App").getProtectionDomain().getCodeSource().getLocation().toURI());
return appJar.getParentFile().getParentFile();
} catch (URISyntaxException | ClassNotFoundException e) {
throw new IllegalStateException("Cannot detect path of main jar file", e);
}
}
private static void warnOnNonSystemProperties(Properties fileProperties) {
Set<String> systemKeys = stream(ProcessProperties.Property.values())
.map(ProcessProperties.Property::getKey)
.collect(Collectors.toSet());
systemKeys.addAll(ADDITIONAL_SYSTEM_KEYS);
fileProperties.stringPropertyNames().stream()
.filter(key -> !systemKeys.contains(key))
.filter(key -> !key.startsWith("sonar.log.level."))
.filter(key -> MULTI_SERVER_LDAP_SETTINGS.stream().noneMatch(pattern -> key.matches(pattern.replace(".", "\\.").replace("*", "[^.]+"))))
.sorted()
.forEach(key -> LOG.warn(
"Property '{}' is not a recognized system property. It cannot be managed from the UI or API when set here, and it may have no effect. Please check the documentation.",
key));
}View on GitHub (pinned to 184c821202)