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 install
and 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=TRACE
and 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?