Simple custom rule not working

Hi, I wrote a relatively simple custom rule that just won’t work on my project, the tests work as expected, however when the rule is activated, it throws an internal error:

java.lang.NoClassDefFoundError: org/sonar/java/cfg/CFG
at org.sonar.samples.java.checks.EntityDtoReturnCheck.visitNode(EntityDtoReturnCheck.java:28)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.lambda$visit$6(VisitorsBridge.java:306)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.lambda$forEach$9(VisitorsBridge.java:321)
at org.sonar.java.model.VisitorsBridge.runScanner(VisitorsBridge.java:185)
at org.sonar.java.model.VisitorsBridge.access$100(VisitorsBridge.java:64)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.forEach(VisitorsBridge.java:321)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:308)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:292)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:312)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:292)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:312)
at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.run(VisitorsBridge.java:283)
at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:167)
at org.sonar.java.ast.JavaAstScanner.simpleScan(JavaAstScanner.java:98)
at org.sonar.java.ast.JavaAstScanner.scan(JavaAstScanner.java:64)
at org.sonar.java.JavaSquid.scanSources(JavaSquid.java:114)
at org.sonar.java.JavaSquid.scan(JavaSquid.java:107)
at org.sonar.plugins.java.JavaSquidSensor.execute(JavaSquidSensor.java:103)
at org.sonarsource.sonarlint.core.analyzer.sensor.SensorsExecutor.executeSensor(SensorsExecutor.java:80)
at org.sonarsource.sonarlint.core.analyzer.sensor.SensorsExecutor.execute(SensorsExecutor.java:71)
at org.sonarsource.sonarlint.core.container.analysis.AnalysisContainer.doAfterStart(AnalysisContainer.java:133)
at org.sonarsource.sonarlint.core.container.ComponentContainer.startComponents(ComponentContainer.java:126)
at org.sonarsource.sonarlint.core.container.ComponentContainer.execute(ComponentContainer.java:111)
at org.sonarsource.sonarlint.core.container.storage.StorageAnalyzer.analyze(StorageAnalyzer.java:77)
at org.sonarsource.sonarlint.core.container.storage.StorageContainerHandler.analyze(StorageContainerHandler.java:80)
at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.lambda$analyze$0(ConnectedSonarLintEngineImpl.java:159)
at org.sonarsource.sonarlint.core.AbstractSonarLintEngine.withModule(AbstractSonarLintEngine.java:87)
at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.lambda$analyze$1(ConnectedSonarLintEngineImpl.java:157)
at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.withReadLock(ConnectedSonarLintEngineImpl.java:371)
at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.withReadLock(ConnectedSonarLintEngineImpl.java:361)
at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.analyze(ConnectedSonarLintEngineImpl.java:155)
at org.sonarlint.eclipse.core.internal.engine.connected.ConnectedEngineFacade.lambda$15(ConnectedEngineFacade.java:392)
at org.sonarlint.eclipse.core.internal.engine.connected.ConnectedEngineFacade.withEngine(ConnectedEngineFacade.java:185)
at org.sonarlint.eclipse.core.internal.engine.connected.ConnectedEngineFacade.runAnalysis(ConnectedEngineFacade.java:391)
at org.sonarlint.eclipse.core.internal.jobs.AnalyzeConnectedProjectJob.runAnalysis(AnalyzeConnectedProjectJob.java:70)
at org.sonarlint.eclipse.core.internal.jobs.AnalyzeConnectedProjectJob.runAnalysis(AnalyzeConnectedProjectJob.java:1)
at org.sonarlint.eclipse.core.internal.jobs.AbstractAnalyzeProjectJob.run(AbstractAnalyzeProjectJob.java:400)
at org.sonarlint.eclipse.core.internal.jobs.AbstractAnalyzeProjectJob.runAnalysisAndUpdateMarkers(AbstractAnalyzeProjectJob.java:208)
at org.sonarlint.eclipse.core.internal.jobs.AbstractAnalyzeProjectJob.doRun(AbstractAnalyzeProjectJob.java:162)
at org.sonarlint.eclipse.core.internal.jobs.AbstractSonarProjectJob.run(AbstractSonarProjectJob.java:45)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: java.lang.ClassNotFoundException: org.sonar.java.cfg.CFG
at org.sonar.classloader.ParentFirstStrategy.loadClass(ParentFirstStrategy.java:39)
at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:87)
at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:76)
… 41 more

Here is the rule code:

@Rule(key = "EntityDtoReturn")
public class EntityDtoReturnCheck extends IssuableSubscriptionVisitor {

	@Override
	public List<Kind> nodesToVisit() {
		return Arrays.asList(Kind.METHOD);
	}

	@Override
	public void visitNode(Tree tree) {
		MethodTree method = (MethodTree) tree;

		if (method.block() != null) {
			CFG cfg = (CFG) method.cfg();

			for (Block block : cfg.blocks()) {
				Tree terminator = block.terminator();

				if (terminator != null && terminator.is(Kind.RETURN_STATEMENT)) {

					String returnValueClass = ((ReturnStatementTree) terminator).expression().symbolType().name();
					String returnTypeClass = method.symbol().returnType().type().name();

					if (returnTypeClass.equals(returnValueClass + "DTO")) {
						reportIssue(terminator, "Don't do that.");
					}
				}
			}
		}
	}
}

Any help is appreciated.

Hi.

Unfortunately you’re using a class that’s not available for custom rules (org.sonar.java.cfg.CFG).

This is mentioned in the documentation:

What you can use, and what you can’t

When writing custom Java rules, you can only use classes from package org.sonar.plugins.java.api .

I don’t have any experience developing custom rules for Java, so I can’t suggest any alternative solution for you.

Edit: actually, I don’t understand why are you casting method.cfg() to CFG. It returns a ControlFlowGraph instance and ControlFlowGraph has the same methods you’re using.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.