What are you trying to accomplish?
I am trying to develop a plugin to my company, regarding some OpenAPI checks.
- Support a new language?
 Not actually, I want to parse possible OpenAPI files (json, xml, yaml) and check if they comply with our standarts.
- Extend an existing one? Which one?
 No, but any extension tips would definitely be useful!
What’s your specific coding challenge in developing your plugin?
I am using the recommended example plugin to develop a POC regarding OpenApi file security validation. However, I haven’t been able to initialize my language, even though the rules were developed and tested. This is the process that I followed:
- Create a language, let’s call it Temp and the necessary classes, I’ve copied FooLanguage’s flow (pic below - added in ExamplePlugin.java)
- Validate language’s recognition: To test out if the language shows up in SonarQube, I ran mvn clean installand saved the .jar file inplugins/extensions.
 However, when I run SonarQube, I get the following error:
2024.06.05 11:14:38 INFO  web[][o.s.s.q.b.BuiltInQProfileRepositoryImpl] Load quality profiles
2024.06.05 11:14:39 INFO  web[][o.s.s.q.b.BuiltInQProfileRepositoryImpl] Language Temp is not installed, related quality profiles are ignored
2024.06.05 11:14:39 WARN  web[][o.s.c.a.AnnotationConfigApplicationContext] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdk.internal.loader.ClassLoaders$AppClassLoader@659e0bfd-org.sonar.server.qualityprofile.builtin.BuiltInQProfileLoader': Initialization of bean failed; nested exception is java.lang.IllegalStateException: The following languages have no built-in quality profiles: temp
2024.06.05 11:14:39 ERROR web[][o.s.s.p.Platform] Background initialization failed. Stopping SonarQube
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdk.internal.loader.ClassLoaders$AppClassLoader@659e0bfd-org.sonar.server.qualityprofile.builtin.BuiltInQProfileLoader': Initialization of bean failed; nested exception is java.lang.IllegalStateException: The following languages have no built-in quality profiles: temp
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:628)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:920)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:187)
	at org.sonar.server.platform.platformlevel.PlatformLevel.start(PlatformLevel.java:80)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup.access$001(PlatformLevelStartup.java:55)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup$1.doPrivileged(PlatformLevelStartup.java:127)
	at org.sonar.server.user.DoPrivileged.execute(DoPrivileged.java:45)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup.start(PlatformLevelStartup.java:124)
	at org.sonar.server.platform.PlatformImpl.executeStartupTasks(PlatformImpl.java:183)
	at org.sonar.server.platform.PlatformImpl$AutoStarterRunnable.runIfNotAborted(PlatformImpl.java:344)
	at org.sonar.server.platform.PlatformImpl$1.doRun(PlatformImpl.java:107)
	at org.sonar.server.platform.PlatformImpl$AutoStarterRunnable.run(PlatformImpl.java:328)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalStateException: The following languages have no built-in quality profiles: temp
	at com.google.common.base.Preconditions.checkState(Preconditions.java:590)
	at org.sonar.server.qualityprofile.builtin.BuiltInQProfileRepositoryImpl.ensureAllLanguagesHaveAtLeastOneBuiltInQP(BuiltInQProfileRepositoryImpl.java:109)
	at org.sonar.server.qualityprofile.builtin.BuiltInQProfileRepositoryImpl.initialize(BuiltInQProfileRepositoryImpl.java:91)
	at org.sonar.server.qualityprofile.builtin.BuiltInQProfileLoader.start(BuiltInQProfileLoader.java:37)
	at org.sonar.core.platform.StartableBeanPostProcessor.postProcessBeforeInitialization(StartableBeanPostProcessor.java:33)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
	... 19 common frames omitted
2024.06.05 11:14:39 INFO  web[][o.s.p.ProcessEntryPoint] Hard stopping process
2024.06.05 11:14:39 INFO  web[][o.s.s.n.NotificationDaemon] Notification service stopped
2024.06.05 11:14:39 INFO  web[][c.z.h.HikariDataSource] HikariPool-1 - Shutdown initiated...
2024.06.05 11:14:39 INFO  web[][c.z.h.HikariDataSource] HikariPool-1 - Shutdown completed.
This is my TempQualityProfile, it is a copy from FooQualityProfile:
package org.sonarsource.plugins.example.languages;
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
import org.sonarsource.plugins.example.checks.OpenApiStringFieldsCheck;
import static org.sonarsource.plugins.example.settings.TempRuleDefinition.REPO_KEY;
/**
 * Default, BuiltIn Quality Profile for the projects having files of the language "Temp"
 */
public final class TempQualityProfile implements BuiltInQualityProfilesDefinition {
  @Override
  public void define(Context context) {
    NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile("Temp BV Way", TempLanguage.KEY);
    profile.setDefault(true);
    
    NewBuiltInActiveRule rule1 = profile.activateRule(REPO_KEY, OpenApiStringFieldsCheck.RULE_KEY);
    rule1.overrideSeverity("BLOCKER");
    profile.done();
  }
}
TempLanguage.java:
package org.sonarsource.plugins.example.languages;
import org.sonar.api.config.Configuration;
import org.sonar.api.resources.AbstractLanguage;
import org.sonarsource.plugins.example.settings.TempLanguageProperties;
/**
 * This class defines the Temp language.
 */
public final class TempLanguage extends AbstractLanguage {
  public static final String NAME = "Temp";
  public static final String KEY = "Temp";
  private final Configuration config;
  public TempLanguage(Configuration config) {
    super(KEY, NAME);
    this.setName(NAME);
    this.config = config;
  }
  @Override
  public String[] getFileSuffixes() {
    return config.getStringArray(TempLanguageProperties.FILE_SUFFIXES_KEY);
  }
}
Observations:
- I’ve also executed SonarQube with log.level=TRACEand the result was as inconclusive as this one had been.
- The lack of documentation / tutorials regarding custom plugin development has been a major issue in my task.
How does an almost similar code fails while the other don’t?

