You can discover and update the Java-specific properties in Administration > General Settings > Java.
.class files are required for java projects with more than one java file. If not provided properly, analysis will fail with the message:
If only some
.class files are missing, you'll see warnings like this:
If you are not using Maven or Gradle for analysis, you must manually provide bytecode to the analysis. You can also analyze test code, and for that you need to provide tests binaries and test libraries properties.
|Comma-separated paths to directories containing the compiled bytecode files corresponding to your source files.|
|Comma-separated paths to files with third-party libraries (JAR or Zip files) used by your project. Wildcards can be used: |
|Comma-separated paths to directories containing the compiled bytecode files corresponding to your test files|
|Comma-separated paths to files with third-party libraries (JAR or Zip files) used by your tests. (For example, this should include the junit jar). Wildcards can be used: |
Android users, Jack doesn't provide the required
In some situations, you might have to analyze a project built with a different version of Java than the one executing the analysis. The most common case is to run the analysis with Java 11, while the project itself uses Java 8 or before for its build. This case is normally automatically handled when using Maven or Gradle, as well as with any flavor of SonarLint.
If it is your case, and you are NOT using Maven or Gradle, you will need to set the property
sonar.java.jdkHome manually (see below). By doing this you'll specify which JDK classes the analyzer must refer to during the analysis. Not setting this property, while it would have been required, usually leads to inconsistent or even impossible-to-fix issues being reported, especially in relation with native JDK classes.
sonar.java.jdkHome, you need to provide the path to the JDK directory used by the project being analyzed, if different from the Java runtime executing the analysis. For example, for a Java 8 project, by setting it as follow:
The best way to deactivate an individual issue you don't intend to fix is to mark it "Won't Fix" or "False Positive" through the SonarQube UI.
If you need to deactivate a rule (or all rules) for an entire file, then issue exclusions are the way to go. But if you only want to deactivate a rule across a subset of a file - all the lines of a method or a class - you can use
@SuppressWarnings with rule keys:
Java analysis is able to react to the java version used for sources. This feature allows the deactivation of rules that target higher versions of Java than the one in use in the project so that false positives aren't generated from irrelevant rules.
The feature relies entirely on the
sonar.java.source property, which is automatically filled by most of the scanners used for analyses (Maven, Gradle). Java version-specific rules are not disabled when
sonar.java.source is not provided. Concretely, rules which are designed to target specific java versions (tagged "java7" or "java8") are activated by default in the Sonar Way Java profile. From a user perspective, the feature is fully automatic, but it means that you probably want your projects to be correctly configured.
When using SonarScanner to perform analyses of project, the property
sonar.java.source can to be set manually in
sonar-project.properties. Accepted formats are:
- "1.X" (for instance 1.6 for java 6, 1.7 for java 7, 1.8 for java 8, etc.)
- "X" (for instance 7 for java 7, 8 for java 8, etc. )
If the property is provided, the analysis will take the source version into account, and execute related rules accordingly. At run time, each of these rules will be executed – or not – depending of the Java version used by sources within the project. For instance, on a correctly configured project built with Java 6, rules targeting Java 7 and Java 8 will never raise issues, even though they are enabled in the associated rule profile.
In SonarQube Developer and Enterprise editions and on SonarCloud you can benefit from advanced security rules including XSS vulnerability detection. Java analysis supports analysis of Thymeleaf and JSP views when used with Java Servlets or Spring. To benefit from this analysis you need to make your views part of the project sources using
sonar.sources property. In practice this usually means adding the following in your Maven
or if you use Gradle
src/main/webapp is the directory which contains
.jsp or Thymeleaf's
- Test coverage and execution (JaCoCo, Surefire)
- Importing external issues (SpotBugs, FindBugs, FindSecBugs, PMD, Checkstyle)
- Adding coding rules
The tutorial Writing custom Java rules 101 will help to quickly start writing custom rules for Java.
- Switch representation change in the AST Previously, Switch Statements were represented thanks to a Switch Expression. It means that the child of the Switch Statement was a Switch Expression. This is no longer the case, a Switch statement is now a distinct node in the AST and does not contain a Switch Expression anymore. This may impact existing custom rules relying explicitly on Switch Expressions, via the kind SWITCH_EXPRESSION or the method visitSwitchExpression. More rarely, this could also impact rules relying on parents of Tree, as the overall shape of the AST may also change.
asSwitchExpression()method is deprecated for removal.
overriddenSymbol()method is deprecated for removal. It is replaced by method
overriddenSymbols()which returns all the overridden symbols in the type hierarchy instead of only the first one found.
- New interface
SwitchTreeSwitch Expression and Switch Statement share the same fields, it can sometimes make sense to manipulate a Switch as either one. Previously, it was possible to use the method asSwitchExpression() to do this. Since this method is deprecated, you can now use the new common interface
SwitchTree, containing all the elements shared between Switch Expressions and Statements.
- API is now enriched with
MethodMatchers. You can use it to identify a method with given a Type, Name and Parameters. We realized that MethodMatchers is a really convenient way of writing new rules, it will hopefully ease the addition of rules in custom plugins, without having to rewrite the logic. We are heavily using it in the different checks, plenty of examples can be found there.
- Two new methods have been added in the semantic API in order to access parametrized type in custom rules. The changes are available in
JavaCheckVerifier, used to test rules implementations and delivered with the
java-checks-testkitpackage, has been fully reworked in order to tackle inconcistencies. All the previously existing methods from it has been deprecated. In addition, a new method has been added, which allows access to a new rule testing interface. Starting from 6.3, when writting custom rules test, you should therefore rely only on
org.sonar.java.checks.verifier.JavaCheckVerifier.newVerifier(). Example of change:
ExpressionTreeinterface, from the AST API, is now enriched by two new methods
<T> Optional<T> asConstant(Class<T> type). These methods let you try to retrieve the equivalent constant value of an expression (from a variable, for instance). An example of usage would be:
- Deprecated method
org.sonar.plugins.java.api.JavaFileScannerContext.addIssue(File, JavaCheck, int, String)has been removed. Custom rules relying on it should report issues on a given
Treefrom now on.
- Deprecated method
org.sonar.plugins.java.api.JavaFileScannerContext.getFile()has been removed. Custom rules relying on it should rely on content of SQ's API
- Deprecated method
org.sonar.plugins.java.api.tree.TryStatementTree.resources()has been removed, in favor of
org.sonar.plugins.java.api.tree.TryStatementTree.resourceList(), as Java 9 allows other trees than
VariableTreeto be placed as resources in try-with-resources statements.
org.sonar.plugins.java.api.semantic.Symbol.owner()has been flagged with
@Nullableannotation, to explicitly document the fact that some symbols (package, unknown, recovered) might well return
- Semantic engine
- Return type of constructor is now
void typeinstead of
- A raw type is now explicitly different from an erasure type. It is recommended to systematically use type erasure for type comparison when dealing with generics.
- Return type of constructor is now
- According to Java Language Specification every array type implements the interface
isSubtypeOf("java.io.Serializable")on an array type now consistently returns
- Symbol corresponding to generic method invocations are now correctly parameterized.
- In some special cases (mostly missing bytecode dependencies, misconfigured projects), and due to ECJ recovery system, unknown/recovered types can now lead to unknown symbols, even on
VariableTree. To illustrate this, the following example now associate the method to an unknown symbol, while previous semantic engine from version 5.X series was creating a
Symbol.MethodSymbolwith an unknown return type.
- Thanks to improved semantic provided by ECJ engine, new semantic is now able to say that an unknown symbol is supposed to be type/variable/method (
isVariableSymbol(), ...). Old semantic was answering
falsefor all of them. Consequently, be sure to always use
isUnknown()to validate symbol resolution. Other
is...Symbol()methods are only designed to know how to cast the symbols (e.g from
org.sonar.plugins.java.api.JavaFileScannerContext: Drop deprecated method used to retrieve trees contributing to the complexity of a method from (deprecated since SonarJava 4.1).
org.sonar.plugins.java.api.JavaResourceLocator: The following method has been dropped (deprecated since SonarJava 4.1), without replacement.
org.sonar.plugins.surefire.api.SurefireUtils: Dropping deprecated field with old property (deprecated since SonarJava 4.11)
org.sonar.plugins.java.api.JavaFileScannerContext: Deprecate usage of File-based methods from API, which will be removed in future release. Starting from this version, methods relying on InputFile has to be preferred.
- Deprecate methods which are not relevant anymore in switch-related trees from API, following introduction of the new Java 12
org.sonar.plugins.java.api.JavaFileScannerContext: Following methods have been added in order to provide help reporting issues at project level, and access data through SonarQube's InputFile API, which won't be possible anymore through files:
- In order to cover the Java 12 new switch expression, introduce a new Tree in the SonarJava Syntax Tree API (Corresponding
SWITCH_EXPRESSION). New methods have also been added to fluently integrate the new switch expression into the SonarJava API.
- This change will impact mostly the custom rules relying on semantic API. The type returned by some symbols will change from raw type to parameterized type with identity substitution and this will change how subtyping will answer. It is possible to get the previous behavior back by using type erasure on the newly returned type. Note that not all returned types are impacted by this change. Example:
Check the issue tracker for this language.
© 2008-2023, SonarSource S.A, Switzerland. Except where otherwise noted, content in this space is licensed under a Creative Commons Attribution-NonCommercial 3.0 United States License. SONARQUBE is a trademark of SonarSource SA. All other trademarks and copyrights are the property of their respective owners.