As we all know, SonarQube is a great tool that helps us increase quality of our codebase. However, it does apply mainly to general Java issues. As we know, we can hurt ourselves much more doing AEM. Adobe Experience Manager is a comprehensive content management platform solution for building websites, mobile apps and forms. This tool is intended to find common bugs and bad smells specific for AEM development. Documentation of each rule is available from SonarQube interface after plugin installation.
Each release has its own prerequisites section, for more information please check releases page.
Go to your SonarQube instance administration console and open Update Center. Find AEM Rules for SonarQube plugin and click install!
- Download
aemrules-x.y.jar
or build AEM Rules for SonarQube plugin. - Paste it into
sonarqube/extensions/plugins
directory. - Restart SonarQube.
- Go to rules section and activate AEM rules in your profile.
Use of the plugin does not differ much from regular SonarQube analysis. However, as rules are often tied to a certain AEM version and its components (Felix, Sling), we've introduced the aemVersion
analysis property.
Each rule defines supported AEM version or version range. Most of the rules are universal. By providing the AEM version parameter, you can instruct the Sonar Runner to only use only a subset of rules applicable to a particular AEM version. When the parameter is not provided then a default AEM version is used (currently 6.4)
When running analysis, pass sonarRunner.aemVersion
property with your AEM version. The format is as follows:
sonarRunner.aemVersion=<MAJOR_VERSION>.<MINOR_VERSION>
Runing with Maven
mvn sonar:sonar -DsonarRunner.aemVersion=6.4
Runing with Gradle (See Gradle AEM Plugin)
gradlew sonarQube -DsonarRunner.aemVersion=6.4
Below you will find descriptions of all rules available in AEM Rules for SonarQube plugin.
-
AEM-1 Use predefined constant in annotation instead of hardcoded value.
- Use constants available in AEM instead of repeating inline literals.
-
AEM-2 Use predefined constant instead of hardcoded value.
- Use constants available in AEM instead of repeating inline literals.
-
AEM-8 Prefer cleaner
@SlingServlet
annotation.- Prefer cleaner
@SlingServlet
annotation over@Properties
approach. Do not mix up both approaches.
- Prefer cleaner
-
AEM-14 Using http literal hardcoded makes it difficult to switch to https later on.
- We should not use http as a literal in our projects because if we want to switch to https, our code will be not ready.
-
AEM-15 Usage of
synchronized
keyword should be avoided if possible.- Usage of
synchronized
keyword should be avoided if possible. Check if usingsynchronized
can be replaced with more sophisticated solution.
- Usage of
-
AEM-17 No mutator methods invoked on
ModifiableValueMap
ModifiableValueMap
should be replaced byValueMap
if no mutator methods are invoked.
-
AEM-19 Implicit search strategy used in Sling Query
SearchStrategy
can have negative performance impact if mismatched. Therefore developer should always make informed decision and define strategy explicitly.
-
AEM-3 Non-thread safe object used as a field of Servlet / Filter etc.
- It is not safe to keep session based object as a field in
Servlet
orFilter
. Rule checks for the occurrence of any instance or static fields of following types:org.apache.sling.api.resource.ResourceResolver
javax.jcr.Session
com.day.cq.wcm.api.PageManager
com.day.cq.wcm.api.components.ComponentManager
com.day.cq.wcm.api.designer.Designer
com.day.cq.dam.api.AssetManager
com.day.cq.tagging.TagManager
com.day.cq.security.UserManager
org.apache.jackrabbit.api.security.user.Authorizable
org.apache.jackrabbit.api.security.user.User
org.apache.jackrabbit.api.security.user.UserManager
- It is not safe to keep session based object as a field in
-
AEM-6 ResourceResolver should be closed in finally block.
- According to its Javadoc, Resource Resolver has a life cycle which begins with the creation of the Resource Resolver using any of the factory methods and ends with calling the
close
method. It is very important to call theclose
method once the resource resolver is not used any more to ensure any system resources are properly clean up.
- According to its Javadoc, Resource Resolver has a life cycle which begins with the creation of the Resource Resolver using any of the factory methods and ends with calling the
-
AEM-7 Session should be logged out in finally block.
- Manually created
javax.jcr.Session
should be logged out after it is no longer needed. Thelogout
method releases all resources associated withSession
.
- Manually created
-
AEM-11 Do not use deprecated administrative access methods
- Administrative access to the resource tree and JCR Repository by means of usage of
ResourceResolverFactory.getAdministrativeResourceResolver
andSlingRepository.loginAdministrative
has been deprecated. UseResourceResolverFactory.getServiceResourceResolver
orSlingRepository.loginService
respectively.
- Administrative access to the resource tree and JCR Repository by means of usage of
Slice related
-
AEM-4 Injector should be closed in finally block or created as a resource within try block.
- Injectors (
com.cognifide.slice.api.injector.InjectorWithContext
) are created in the context of either request or resource resolver. To restore its initial state after using injector, it should be closed in finally block or created as a resource within try block.
- Injectors (
-
AEM-5 Injector can be closed using try-with-resources Java 7 feature.
- Take advantage of Java 7 try-with-resources feature to close
com.cognifide.slice.api.injector.InjectorWithContext
.
- Take advantage of Java 7 try-with-resources feature to close
-
AEM-9 Objects annotated by
@SliceResource
should not use (except: constructor,com.cognifide.slice.api.model.InitializableModel.afterCreated()
) and return any session based object.- Objects annotated by
@SliceResource
should not use any session based objects, except places like constructor and overriddencom.cognifide.slice.api.model.InitializableModel.afterCreated()
method.
- Objects annotated by
-
AEM-10 Use
ModelProvider#getListFromResources
instead of iteration- Slice provides method for creating list of models from specified resources given as an
Iterator
. Instead of iterating over resources yourself, useModelProvider#getListFromResources
method.
- Slice provides method for creating list of models from specified resources given as an
-
AEM-12 Fields annotated by
@JcrProperty
shouldn't be accessed from constructor.- Fields that are annotated with
@JcrProperty
should not be accessed from within constructor.
- Fields that are annotated with
Sling Models related
- AEM-16 Optional is defined as
DefaultInjectionStrategy
- Usage of
@Optional
annotation is redundant, whendefaultInjectionStrategy
isOPTIONAL
.
- Usage of
Release notes for each version can be found in releases section.
Copyright 2015-2016 Cognifide Ltd.
Licensed under the Apache License, Version 2.0
Technical support can be made available if needed. Please contact us for more details.
We can:
- prioritize your feature request,
- tailor the product to your needs,
- provide a training for your engineers,
- support your development teams.