SonarSource/sonarqube · critical · IllegalStateException

The plugin [ ] does not support Java

Error message

The plugin [%s] does not support Java %s

What it means

PluginClassLoader instantiates each plugin's main class; if the JVM raises UnsupportedClassVersionError (plugin compiled for a newer Java than the runtime), it is translated to an IllegalStateException stating the plugin does not support the current Java version.

Solutions

  1. Upgrade the JVM running SonarQube to the version the plugin requires
  2. Downgrade the plugin to a build compatible with the current Java version
  3. Rebuild the plugin targeting the appropriate --release byte-code level
Defensive patterns

Strategy: try-catch

Validate before calling

int runtimeMajor = Integer.parseInt(System.getProperty("java.class.version").split("\\.")[0]) - 44;
// compare against the plugin's required major version from its manifest before loading

Try / catch

try {
  return loader.load(pluginDef);
} catch (IllegalStateException e) {
  LOG.error("Plugin incompatible with current Java version", e);
  throw e;
}

Prevention

When it happens

Trigger: Loading a plugin whose main class was compiled with a class-file major version higher than the running JVM's JAVA_VERSION.

Common situations: Running SonarQube on an older JDK than plugins require (e.g. Java 8 runtime with Java 11-built plugins); plugins built without targeting older bytecode.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/d464ee4b0da3e33a. Report an issue: GitHub.

Appendix: source

Thrown at sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoader.java:137

   *
   * @return the instances grouped by plugin key
   * @throws IllegalStateException if at least one plugin can't be correctly loaded
   */
  private static Map<String, Plugin> instantiatePluginClasses(Map<PluginClassLoaderDef, ClassLoader> classloaders) {
    // instantiate plugins
    Map<String, Plugin> instancesByPluginKey = new HashMap<>();
    for (Map.Entry<PluginClassLoaderDef, ClassLoader> entry : classloaders.entrySet()) {
      PluginClassLoaderDef def = entry.getKey();
      ClassLoader classLoader = entry.getValue();

      // the same classloader can be used by multiple plugins
      for (Map.Entry<String, String> mainClassEntry : def.getMainClassesByPluginKey().entrySet()) {
        String pluginKey = mainClassEntry.getKey();
        String mainClass = mainClassEntry.getValue();
        try {
          instancesByPluginKey.put(pluginKey, (Plugin) classLoader.loadClass(mainClass).getDeclaredConstructor().newInstance());
        } catch (UnsupportedClassVersionError e) {
          throw new IllegalStateException(String.format("The plugin [%s] does not support Java %s", pluginKey, SystemUtils.JAVA_VERSION), e);
        } catch (Throwable e) {
          throw new IllegalStateException(String.format("Fail to instantiate class [%s] of plugin [%s]", mainClass, pluginKey), e);
        }
      }
    }
    return instancesByPluginKey;
  }

  public void unload(Collection<Plugin> plugins) {
    for (Plugin plugin : plugins) {
      ClassLoader classLoader = plugin.getClass().getClassLoader();
      if (classLoader instanceof Closeable closeable && classLoader != classloaderFactory.baseClassLoader()) {
        try {
          closeable.close();
        } catch (Exception e) {
          LoggerFactory.getLogger(getClass()).error("Fail to close classloader " + classLoader.toString(), e);
        }
      }

View on GitHub (pinned to 184c821202)