Custom plugin dependency injection issue


(Alex) #1

Hello,

I’m writing a plugin for a new language (let’s call it Base Plugin). I have the basics rules for this language, wrote the grammar and manage to use it to analyse files with Sonarqube server.
Now I would like to create a new plugin (let’s call it Extending Plugin) that adds some rules using extensions. However the injected objects are always null.

Am I missing something ?

Context:
Sonarqube 7.3.0.15553
Running debug using mvnDebug (Scanner side)
sonar-plugin-api 7.3

What I did:

  1. In the base plugin I defined class:
// Imports to make sure I'm using the good packages
import org.sonar.api.batch.ScannerSide;
import org.sonarsource.api.sonarlint.SonarLintSide;

@SonarLintSide
@ScannerSide
// @ExtensionPoint annotation is not required, right ?
public interface MyExtensionPoint {

	void call(String str);
}
  1. Then in the extending plugin I did:
@SonarLintSide
@ScannerSide
public class MyExtensionPointImpl implements MyExtensionPoint {

	@Override
	public void call(final String str) {
		System.err.println(str);
	}
}
  1. And registered the extension in the extending plugin declaration:
public class ExtendingPluginPlugin implements Plugin{

	@Override
	public void define(final Context context) {
		context.addExtension(MyExtensionPointImpl.class);
		// ... registering other extensions that are working well
	}
}
  1. Now in the base plugin, trying to inject a MyExtensionPoint in the Sensor always get null:
public class BaseSquidSensor implements Sensor {
	// Constructor with less arguments...

	public BaseSquidSensor (final CheckFactory checkFactory,
						  final Configuration settings,
						  @Nullable MyExtensionPoint[] myExtensionPoints){
		// Injected myExtensionPoints is always null...
	}

	//....
}

Thank you


(Pierre-Yves Nicolas) #2

Hi,

I’m not sure, but you should check the basePlugin property when configuring sonar-packaging-maven-plugin. See the doc to build a plugin.


(Alex) #3

Good guess, I will have to test. I can no longer access the code right now :slight_smile:

My question is why the example (https://github.com/SonarSource/sonar-custom-plugin-example/blob/master/pom.xml) doesn’t use it. It shows how to extend Java rule, but doesn’t use this tag… I’m confused


(Julien Henry) #4

Hi,

basePlugin will make your two plugins share the same classloader. This is not always good. Another option is to put your interface MyExtensionPoint in the package org.sonar.plugins.<plugin key>.api. By convention all classes in this package are visible to all other plugins.

The example you linked is not a custom Java rule plugin. You are confusing with: https://github.com/SonarSource/sonar-custom-rules-examples/tree/master/java-custom-rules

But as I said using basePlugin is only needed when the extension point is not in the API. In fact I will check but to me no custom rule plugin should use basePlugin.


(Alex) #5

Thanks Julien for the info.
I will try to change the package instead of using basePlugin.
You’re correct about the examples. I think I mixed the links :slight_smile:


(Alex) #6

Switching to package as mentionned by @Julien_HENRY did the trick.


(Alex) #7

I am now getting an
java.lang.ArrayStoreException: org.sonar.plugins.mysql.api.grammar.SqlGrammar
when running the scanner. This indicates that wrong type argument is provided, but it works in unit test. So my only guess is a runtime class resolution issue.

The target line is simply (invoked in the Extending plugin):

subscribeTo(SqlGrammar.FILE_INPUT);

with signature

public void subscribeTo(final AstNodeType... astNodeTypes) {

SqlGrammar is obviously a GrammarRuleKey which extends AstNodeType, so I’m not sure why it throws an exception. SqlGrammar is defined in the base plugin.
The Extending plugin has a provided Maven dependency to the Base plugin, so I assume that Sonarqube provides the good Jar…

Any idea ?


(Julien Henry) #8

Inspect the content of your extending plugin JAR, and be sure the extended plugin is not packaged. If you are using the Maven scope “provided” it should not be the case.

Is AstNodeType also in the org.sonar.plugins.mysql.api package?


(Alex) #9

Base plugin JAR is not within the extended plugin.
AstNodeType is part of org.sonarsource.sslr:sslr-core in com.sonar.sslr.api package. It is included in my extending plugin with compile scope. This might be the issue.
I’m not sure I can switch it to provided. Will Sonarqube provide it ?


(Julien Henry) #10

SonarQube won’t provide it. If this library should be part of your plugin API. You can use the Maven shade plugin to relocate classes in the right package.