Angshuman
Angshuman

Reputation: 21

Sonar-qube 4.5.1 custom rules plugin is not working

I have created a custom rule plugin using custom rule code snippet. Now I have added another rule which will show error when a anonymous class has more than 30 lines. I have build the custom rule plugin jar using mvn package command and put in in sonar server extension/plugin and restarted the server. my corresponding rule can be viewed from sonar server but rule cannot analyze the the code though there is a class with anonymous class with loc >30 lines. my custom rule is given below.

@Rule(
  key = AnonymousClassesTooBigCheck.KEY,
    name = "Avoid  too big classes",
    description = "avoid too bid classes",
  tags = {"brain-overload"},
  priority = Priority.MAJOR)
@BelongsToProfile(title = "Sonar way", priority = Priority.MAJOR)
public class AnonymousClassesTooBigCheck extends BaseTreeVisitor implements JavaFileScanner {
public static final String KEY = "AD0001";
  private static final RuleKey RULE_KEY = RuleKey.of(MyJavaRulesDefinition.REPOSITORY_KEY, KEY);
  private static final int DEFAULT_MAX = 30;

  @RuleProperty(defaultValue = "" + DEFAULT_MAX)
  public int max = DEFAULT_MAX;

  private JavaFileScannerContext context;
  /**
   * Flag to skip check for class bodies of EnumConstants.
   */
  private boolean isEnumConstantBody;

  @Override
  public void scanFile(JavaFileScannerContext context) {
    this.context = context;
    isEnumConstantBody = false;
    scan(context.getTree());
  }

  @Override
  public void visitNewClass(NewClassTree tree) {
    if (tree.classBody() != null && !isEnumConstantBody) {
      int lines = getNumberOfLines(tree.classBody());
      if (lines > max) {
        context.addIssue(tree, RULE_KEY, "Reduce this anonymous class number of lines from " + lines + " to at most " + max + ", or make it a named class.");
      }
    }
    isEnumConstantBody = false;
    super.visitNewClass(tree);
  }

  @Override
  public void visitEnumConstant(EnumConstantTree tree) {
    isEnumConstantBody = true;
    super.visitEnumConstant(tree);
  }

  @Override
  public void visitLambdaExpression(LambdaExpressionTree lambdaExpressionTree) {
    int lines = getNumberOfLines(((JavaTree) lambdaExpressionTree.body()).getAstNode());
    if (lines > max) {
      context.addIssue(lambdaExpressionTree, RULE_KEY, "Reduce this lambda expression number of lines from " + lines + " to at most " + max + ".");
    }
    super.visitLambdaExpression(lambdaExpressionTree);
  }

  private int getNumberOfLines(ClassTree classTree) {
    int startLine = ((InternalSyntaxToken) classTree.openBraceToken()).getLine();
    int endline = ((InternalSyntaxToken) classTree.closeBraceToken()).getLine();
    return endline - startLine + 1;
  }

  private int getNumberOfLines(AstNode node) {
    return node.getLastToken().getLine() - node.getTokenLine() + 1;
  }

}

Now do I need to do any thing more to get the rule hit?

One more thing after putting the plugin jar in plugin folder if i run the analyzer using mvn sonar:sonar a error occures

Embedded error: org/sonar/java/model/InternalSyntaxToken
org.sonar.java.model.InternalSyntaxToken
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.lifecycle.LifecycleExecutionException: Can not execute Sonar
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:719)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:284)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
        at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
        at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
        at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
        at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.MojoExecutionException: Can not execute Sonar
        at org.codehaus.mojo.sonar.Bootstraper.executeMojo(Bootstraper.java:103)
        at org.codehaus.mojo.sonar.Bootstraper.start(Bootstraper.java:79)
        at org.codehaus.mojo.sonar.SonarMojo.execute(SonarMojo.java:88)
        at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
        ... 17 more
Caused by: org.apache.maven.plugin.MojoExecutionException: org/sonar/java/model/InternalSyntaxToken
        at org.sonar.maven.ExceptionHandling.handle(ExceptionHandling.java:37)
        at org.sonar.maven.SonarMojo.execute(SonarMojo.java:175)
        at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
        at org.codehaus.mojo.sonar.Bootstraper.executeMojo(Bootstraper.java:98)
        ... 21 more
Caused by: java.lang.NoClassDefFoundError: org/sonar/java/model/InternalSyntaxToken
        at org.sonar.samples.java.AnonymousClassesTooBigCheck.getNumberOfLines(AnonymousClassesTooBigCheck.java:78)
        at org.sonar.samples.java.AnonymousClassesTooBigCheck.visitNewClass(AnonymousClassesTooBigCheck.java:53)
        at org.sonar.java.model.expression.NewClassTreeImpl.accept(NewClassTreeImpl.java:126)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitVariable(BaseTreeVisitor.java:291)
        at org.sonar.java.model.declaration.VariableTreeImpl.accept(VariableTreeImpl.java:180)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:36)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitClass(BaseTreeVisitor.java:69)
        at org.sonar.java.model.declaration.ClassTreeImpl.accept(ClassTreeImpl.java:201)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:36)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitClass(BaseTreeVisitor.java:69)
        at org.sonar.java.model.declaration.ClassTreeImpl.accept(ClassTreeImpl.java:201)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:36)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitCompilationUnit(BaseTreeVisitor.java:55)
        at org.sonar.java.model.JavaTree$CompilationUnitTreeImpl.accept(JavaTree.java:202)
        at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
        at org.sonar.samples.java.AnonymousClassesTooBigCheck.scanFile(AnonymousClassesTooBigCheck.java:47)
        at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:123)
        at com.sonar.sslr.impl.ast.AstWalker.walkAndVisit(AstWalker.java:67)
        at org.sonar.java.ast.AstScanner.simpleScan(AstScanner.java:107)
        at org.sonar.java.ast.AstScanner.scan(AstScanner.java:75)
        at org.sonar.java.JavaSquid.scanSources(JavaSquid.java:122)
        at org.sonar.java.JavaSquid.scan(JavaSquid.java:115)
        at org.sonar.plugins.java.JavaSquidSensor.analyse(JavaSquidSensor.java:91)
        at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:79)
        at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:70)
        at org.sonar.batch.phases.PhaseExecutor.execute(PhaseExecutor.java:119)
        at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:194)
        at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
        at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
        at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:233)
        at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:228)
        at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:221)
        at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
        at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
        at org.sonar.batch.scan.ScanTask.scan(ScanTask.java:64)
        at org.sonar.batch.scan.ScanTask.execute(ScanTask.java:51)
        at org.sonar.batch.bootstrap.TaskContainer.doAfterStart(TaskContainer.java:125)
        at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
        at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
        at org.sonar.batch.bootstrap.BootstrapContainer.executeTask(BootstrapContainer.java:173)
        at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:95)
        at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
        at org.sonar.runner.batch.IsolatedLauncher.execute(IsolatedLauncher.java:48)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.sonar.runner.impl.BatchLauncher$1.delegateExecution(BatchLauncher.java:87)
        at org.sonar.runner.impl.BatchLauncher$1.run(BatchLauncher.java:75)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.sonar.runner.impl.BatchLauncher.doExecute(BatchLauncher.java:69)
        at org.sonar.runner.impl.BatchLauncher.execute(BatchLauncher.java:50)
        at org.sonar.runner.api.EmbeddedRunner.doExecute(EmbeddedRunner.java:102)
        at org.sonar.runner.api.Runner.execute(Runner.java:100)
        at org.sonar.maven.SonarMojo.execute(SonarMojo.java:173)
        ... 23 more
Caused by: java.lang.ClassNotFoundException: org.sonar.java.model.InternalSyntaxToken
        at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:259)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:235)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:227)
        ... 82 more

Upvotes: 2

Views: 688

Answers (1)

benzonico
benzonico

Reputation: 10833

The reason you encounter this error is that the code of the AnonymousClassesTooBigCheck is using internal APIs, here InternalSyntaxToken is not supposed to be used directly and thus fails at runtime (you might notice that none of the example in the custom rule code snippet is using this class).

Upvotes: 0

Related Questions