Git Product home page Git Product logo

aem-rules-for-sonarqube's Introduction

Wunderman Thompson Technology logo

Builds Status Coverage Status Quality Gate

About AEM Rules for SonarQube

AEM Rules for SonarQube

Purpose

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.

Prerequisites

Each release has its own prerequisites section, for more information please check releases page.

Installation

Custom Dockerfile

Following Dockerfile uses official Sonarqube 7.9 image and download AEM Rules 1.0-RC2 to plugin directory.

FROM sonarqube:7.9-community AS aemrulesqube79
RUN curl -Lk -o $SONARQUBE_HOME/extensions/plugins/aemrules-1.0-RC2.jar https://github.com/wttech/AEM-Rules-for-SonarQube/releases/download/v1.0-RC2/aemrules-1.0-RC2.jar

Community image

This is already prepared solution thanks to @ahmed-musallam.

docker run --rm -p 9000:9000 ahmedmusallam/sonarqube-aem:latest

This solution is for those who would like to start testing theirs code within aem rules and sonarqube. It contains SonarQube v 7.7, aem rules v 0.11 and predefined quality gates. If you would like to participate in our Aem Rules development, please refer to wiki page to get into.

Update Center

Go to your SonarQube instance administration console and open Update Center. Find AEM Rules for SonarQube plugin and click install!

Manual

  1. Download aemrules-x.y.jar or build AEM Rules for SonarQube plugin.
  2. Paste it into sonarqube/extensions/plugins directory.
  3. Restart SonarQube.
  4. Go to rules section and activate AEM rules in your profile.

Usage

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)

Running analysis

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

Rule set

Below you will find descriptions of all rules available in AEM Rules for SonarQube plugin.

AEM Good practices

  • 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-5 getContentResource() is not null checked

    • Always null check the return value of getContentResource(). It is possible to get a null if a jcr:content node does not exist in the repository.
  • AEM-8 Prefer cleaner @SlingServlet annotation.

    • Prefer cleaner @SlingServlet annotation over @Properties approach. Do not mix up both approaches.
  • AEM-15 Usage of synchronized keyword should be avoided if possible.

    • Usage of synchronized keyword should be avoided if possible. Check if using synchronized can be replaced with more sophisticated solution.
  • AEM-17 No mutator methods invoked on ModifiableValueMap

    • ModifiableValueMap should be replaced by ValueMap 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.

HTL Good practices

  • HTL-1 Wrong placement of the HTL Attribute.

    • Always Place HTL Attributes After the Ones that are Part of the Markup.
  • HTL-2 HTL Templates should be placed in separate files.

    • HTL Templates should be placed in separate files. This helps to understand which code is meant to render a component and which code is re-used as a template.
  • HTL-3 Use Explicit Names in Loops

    • HTL provides implicit variables in data-sly-list and data-sly-repeat blocks. Try to avoid them and use explicit names clarifying the role of the objects instead.
  • HTL-4 Name and re-use Repeating Conditions

    • Consider caching data-sly-test conditions and reduce code duplication.
  • HTL-5 Usage of HTML comments should be avoided if possible

    • If you want to place comments regarding your code, make sure they don't display to the end users.
  • HTL-6 HTL automatically recognises the context for HTML output

    • HTL uses uri display context as default for src, poster, manifest, href, formaction, data, cite, action attributes
  • HTL-7 Style and script tags display context definition is mandatory

  • HTL-8 Event attribute attributes must have display context defined

  • HTL-9 Inline styles must have display context defined

  • HTL-10 Use sly tags over redundant markup.

    • HTL attributes should be wrapped in sly tags to avoid superfluous markup.
  • HTL-11 Use existing HTML elements instead of adding extra sly tags.

    • HTL attributes should be included in HTML markup without additional SLY tags.
  • HTL-12 Use the most restrictive HTL context possible.

    • For data attributes HTL applies HTML escaping.
  • HTL-13 Avoid using 'unsafe' display context.

    • 'unsafe' display context disables XSS protection completely.
  • HTL-14 HTL expressions in HTML comments should have defined context.

    • HTML comments automatically implies 'comment' markup context.
  • HTL-15 Use Camel Case in identifiers:

    • variable names
    • template names

Possible bugs

  • 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 or Filter. 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
  • 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 the close method once the resource resolver is not used any more to ensure any system resources are properly clean up.
  • 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. The logout method releases all resources associated with Session.
  • 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 and SlingRepository.loginAdministrative has been deprecated. Use ResourceResolverFactory.getServiceResourceResolver or SlingRepository.loginService respectively.

Sling Models related

  • AEM-16 Optional is defined as DefaultInjectionStrategy
    • Usage of @Optional annotation is redundant, when defaultInjectionStrategy is OPTIONAL.

Release notes

Release notes for each version can be found in releases section.

License

Copyright 2015-2016 Wunderman Thompson Technology

Licensed under the Apache License, Version 2.0

Commercial Support

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.

aem-rules-for-sonarqube's People

Contributors

chutch avatar dependabot[bot] avatar devzbysiu avatar fee-bee avatar joerghoh avatar jplucinski avatar justinedelson avatar leetcode-user avatar michaltobiasz avatar michalwronowski avatar piotr-wilczynski avatar raspy avatar rzepetto avatar tomasz-niedzwiedz-wttech avatar toniedzwiedz avatar twiernik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aem-rules-for-sonarqube's Issues

aemrules doesn't work with sonar 5.4

Hey there!
We tried using aemrules plugin (compiled from master branch) with Sonar 5.4 and java plugin 3.14 and Sonar failed on startup due to aemrules caused errors:

2016.06.02 09:58:06 ERROR web[o.a.c.c.C.[.[.[/]] Exception sending context initialized event to listener instance of class org.sonar.server.platform.PlatformServletContextListener             [40/242]
java.lang.NoClassDefFoundError: org/sonar/java/checks/SubscriptionBaseVisitor
        at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.7.0_75]
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800) ~[na:1.7.0_75]
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.7.0_75]
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) ~[na:1.7.0_75]
        at java.net.URLClassLoader.access$100(URLClassLoader.java:71) ~[na:1.7.0_75]
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361) ~[na:1.7.0_75]
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355) ~[na:1.7.0_75]
        at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_75]
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354) ~[na:1.7.0_75]
        at org.sonar.classloader.ClassRealm.loadClassFromSelf(ClassRealm.java:125) ~[sonar-classloader-1.0.jar:na]
        at org.sonar.classloader.ParentFirstStrategy.loadClass(ParentFirstStrategy.java:37) ~[sonar-classloader-1.0.jar:na]
        at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:87) ~[sonar-classloader-1.0.jar:na]
        at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:76) ~[sonar-classloader-1.0.jar:na]
        at com.cognifide.aemrules.extensions.CheckListRegistrar.<clinit>(CheckListRegistrar.java:29) ~[na:na]
        at com.cognifide.aemrules.extensions.AemRulesRulesDefinition.define(AemRulesRulesDefinition.java:12) ~[na:na]
        at org.sonar.server.rule.RuleDefinitionsLoader.load(RuleDefinitionsLoader.java:54) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.rule.RegisterRules.start(RegisterRules.java:100) ~[sonar-server-5.4.jar:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_75]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_75]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_75]
        at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_75]
        at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.invokeMethod(ReflectionLifecycleStrategy.java:110) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.start(ReflectionLifecycleStrategy.java:89) ~[picocontainer-2.15.jar:na]
        at org.sonar.core.platform.ComponentContainer$1.start(ComponentContainer.java:312) ~[sonar-core-5.4.jar:na]
        at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.start(AbstractInjectionFactory.java:84) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.AbstractBehavior.start(AbstractBehavior.java:169) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.Stored$RealComponentLifecycle.start(Stored.java:132) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.Stored.start(Stored.java:110) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.potentiallyStartAdapter(DefaultPicoContainer.java:1016) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.startAdapters(DefaultPicoContainer.java:1009) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.start(DefaultPicoContainer.java:767) ~[picocontainer-2.15.jar:na]
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:134) ~[sonar-core-5.4.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevel.start(PlatformLevel.java:84) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevelStartup.access$001(PlatformLevelStartup.java:44) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevelStartup$1.doPrivileged(PlatformLevelStartup.java:80) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.user.DoPrivileged.execute(DoPrivileged.java:44) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevelStartup.start(PlatformLevelStartup.java:76) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.platform.Platform.executeStartupTasks(Platform.java:197) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.platform.Platform.doStart(Platform.java:114) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.platform.Platform.doStart(Platform.java:99) ~[sonar-server-5.4.jar:na]
        at org.sonar.server.platform.PlatformServletContextListener.contextInitialized(PlatformServletContextListener.java:44) ~[sonar-server-5.4.jar:na]
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4812) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_75]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_75]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_75]
        at java.lang.Thread.run(Thread.java:745) [na:1.7.0_75]
Caused by: java.lang.ClassNotFoundException: org.sonar.java.checks.SubscriptionBaseVisitor
        at org.sonar.classloader.ParentFirstStrategy.loadClass(ParentFirstStrategy.java:39) ~[sonar-classloader-1.0.jar:na]
        at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:87) ~[sonar-classloader-1.0.jar:na]
        at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:76) ~[sonar-classloader-1.0.jar:na]
        ... 50 common frames omitted
2016.06.02 09:58:06 ERROR web[o.a.c.c.StandardContext] One or more listeners failed to start. Full details will be found in the appropriate container log file
2016.06.02 09:58:07 ERROR web[o.a.c.c.StandardContext] Context [] startup failed due to previous errors

AEM-9 produces false-positives

When a session based object is accessed or returned within a private method that is called in constructor or afterCreated method it is still reported as an issue.

Below is an example of valid code that is marked as non compliant. Issue is reported for getTags method.

@SliceResource
public class Model implements InitializableModel {

    @Inject
    @RequestedPage
    private Page page;

    private List<Tag> tags;

    @Override
    public void afterCreated() {
        this.tags = getTags(page.getContentResource());
    }

    private List<Tag> getTags(Resource contentResource) {
        TagManager manager = contentResource.getResourceResolver().adaptTo(TagManager.class);
        return Arrays.asList(manager.getTags(contentResource));
    }
}

Incompatible with new SonarJava 4.10 plugin

When I update the SonarJava plugin from 4.9 to 4.10 (released yesterday), the web server (SQ 6.3.0) fails to start up due to the following exception (using AEM Rules v0.8):

2017.05.31 10:29:45 ERROR web[][o.a.c.c.C.[.[.[/]] Exception sending context initialized event to listener instance of class org.sonar.server.platform.web.PlatformServletContextListener
java.lang.NoClassDefFoundError: com/google/common/base/Functions
	at com.cognifide.aemrules.extensions.RulesLoader.<clinit>(RulesLoader.java:49)
	at com.cognifide.aemrules.extensions.AemRulesRulesDefinition.define(AemRulesRulesDefinition.java:30)
	at org.sonar.server.rule.RuleDefinitionsLoader.load(RuleDefinitionsLoader.java:52)
	at org.sonar.server.rule.RegisterRules.start(RegisterRules.java:99)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.invokeMethod(ReflectionLifecycleStrategy.java:110)
	at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.start(ReflectionLifecycleStrategy.java:89)
	at org.sonar.core.platform.ComponentContainer$1.start(ComponentContainer.java:321)
	at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.start(AbstractInjectionFactory.java:84)
	at org.picocontainer.behaviors.AbstractBehavior.start(AbstractBehavior.java:169)
	at org.picocontainer.behaviors.Stored$RealComponentLifecycle.start(Stored.java:132)
	at org.picocontainer.behaviors.Stored.start(Stored.java:110)
	at org.picocontainer.DefaultPicoContainer.potentiallyStartAdapter(DefaultPicoContainer.java:1016)
	at org.picocontainer.DefaultPicoContainer.startAdapters(DefaultPicoContainer.java:1009)
	at org.picocontainer.DefaultPicoContainer.start(DefaultPicoContainer.java:767)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
	at org.sonar.server.platform.platformlevel.PlatformLevel.start(PlatformLevel.java:88)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup.access$001(PlatformLevelStartup.java:40)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup$1.doPrivileged(PlatformLevelStartup.java:70)
	at org.sonar.server.user.DoPrivileged.execute(DoPrivileged.java:45)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup.start(PlatformLevelStartup.java:67)
	at org.sonar.server.platform.Platform.executeStartupTasks(Platform.java:188)
	at org.sonar.server.platform.Platform.doStart(Platform.java:101)
	at org.sonar.server.platform.Platform.doStart(Platform.java:79)
	at org.sonar.server.platform.web.PlatformServletContextListener.contextInitialized(PlatformServletContextListener.java:45)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4727)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5189)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.google.common.base.Functions
	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)
	... 37 common frames omitted

Injector-based object is used outside the injector lifecycle

Consider following code.

ModelProvider modelProvider;
try (InjectorWithContext injector = InjectorUtil.getInjector(INJECTOR_NAME, request)) {
	modelProvider = injector.getInstance(ModelProvider.class);
	SomeSliceObject someSliceObject= injector.getInstance(SomeSliceObject.class);
}
someSliceObject.foo();

The reference for someSliceObject may fail depending on whether the injector has been closed already. The output is fairly indeterministic though.

Also, I believe a similar issue may appear out of Slice world for basically resource-based objects.

Support disabling rules via //NOSONAR

AEM rules should be possible to disable with the Java comment //NOSONAR (similar to what is possible with the Java Plugin). This currently does not work.

Warning about implicit JCR queries triggered by SlingQuery

We've had some performance trouble in our project caused by improper use of SlingQuery.

A lot of people tend not to think about the search strategy used under the hood and whether or not a JCR query (the default strategy) is good for the job they're using the SlingQuery for.

It would be nice to have a rule suggesting explicit selection of a searchStrategy, if only to improve the awareness of what's going on under the hood when one uses a SlingQuery.

Cycle causes stack overflow on rule AEM-9

Below scenario (Circular dependency) causes stack overflow on rule AEM-9

method1() {
    if(condition) {
        method2()
    }
}

method2() {
    if(differentConfition){
        method1()
    }
}

Please fix rule to don't visit method invocations which were visited in while visiting current method.

AEM Rules could not be activated

Hi,

Using the latest SonarQube 6.7 LTS release and installed V0.9 of rule plugin.

While going through the AEM Repo, on the rules, not getting rule "Activate" option.

Login used : admin

Java Plugin Version with SQ67: 4.15.xx

AEM Rules Activation.pdf

Regards
Milind

Use HTL comments

If you want to place comments regarding your code, make sure they don't display to end users.

<!--/* Good, this comment will not be rendered */-->
 
<!-- Potentially bad, plain HTML comments will be visible on the page -->

AEM-3 is too eager now

Since issue #45 , AEM-3 will complain about two interfaces that are documented to be available as OSGi services, and as such, must have a thread-safe implementation:

  • com.day.cq.search.QueryBuilder
  • com.day.cq.commons.Externalizer

They can be adapted from ResourceManager for convenience, but this doesn't imply that they aren't thread-safe or that they must be adapted from a ResourceManager instance. AEM-3 shouldn't complain about them; at most, they should be covered by a different rule that suggests adapting them from ResourceManager. (Although personally I can't see any reason why adapting them is better than having them referenced directly.)

Define formatter

  1. Prepare project formatter based on Google one with following changes
    • 160 characters for line break
    • 4 spaces for indentation
  2. Add formatter to the codebase (both for Eclipse & IntelliJ)
  3. Reformat all files

SlingModels defaultInjectionStrategy

If a majority of @injected fields/methods are optional, it is possible to change the default injection strategy by using adding defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL to the @model annotation.
If defaultInjectionStrategy is defined as optional, @optional annotation on injected fields (@Inject) is no longer needed.

Pass AEM version to execution

Some rules are only applicable for specific versions of AEM which translates to specific versions of Sling & OSGI.

Check whether it is possible to pass during execution a variable to conditionally turn on/off specific rules.

--aemVersion=6.4

Place Templates in Separate Files

HTL Templates should be placed in separate files. This helps understand which code is meant to render a componenta and which code is reused as a template. Additionally, component-specific code can be safely removed. It should be immediately obvious whether or not some code is re-used across the codebase.

<!--/* Bad - component code also defines a template, the template should be extracted to a separate file */-->
 
<template data-sly-template.image="${@ source, description}">
    <img src="${source}" alt="${description}" title="${description}"/>
</template>
 
<div class="image-component" data-sly-use.model="com.example.Image">
    <sly data-sly-call="${image @ source=model.src, description=model.altText}"
</div>

OSGI DECLARATIVE SERVICES ANNOTATIONS IN AEM

Hi,

AEM-8 Prefer cleaner @SlingServlet annotation.

This rule recommends to use @SlingServlet Annotation but as per OSGI Declarative services (OSGI R6) the new way to create Servlet is:
@component(
immediate = true,
service = Servlet.class,
property = {
"sling.servlet.resourceTypes=project/components/component"
}
)
@Designate(ocd = SampleOsgiServlet.Configuration.class)

e.g: https://gist.github.com/nateyolles/e1e809485cbb0ef1e04a445ddf53a6d7

I saw couple of more blogs and posts for the same.
Can you please help me with this issue?

SonarQube doesn't start with plugin

I have an issue with the plugin. Sonar starts the first time, creates database and works just fine. But the second time it doesn't start. There is not much info in log. I found a few lines with error messages.

ERROR web[o.a.c.c.C.[.[.[/]] Exception sending context initialized event to listener instance of class org.sonar.server.platform.PlatformServletContextListener
java.lang.NoClassDefFoundError: org/sonar/plugins/java/api/CheckRegistrar
ERROR web[jruby.rack] initialization failed
ERROR web[o.a.c.c.StandardContext] Error listenerStart
ERROR web[o.a.c.c.StandardContext] Context [] startup failed due to previous errors

Don't Introduce Extra Markup for HTL Instructions

Use existing HTML elements instead of adding extra sly tags.

<!--/* Bad - unnecessary elements*/-->
<sly data-sly-test="${model.visible}" data-sly-use="com.example.HeroModel">
    <div class="myComponent">
        <h1>${model.headline}</h1>
        <p>${model.text}</p>
    </div>
</sly>
 
<!--/* Good - existing markup reused */-->
<div class="myComponent"
     data-sly-test="${model.visible}"
     data-sly-use="com.example.HeroModel">
    <h1>${model.headline}</h1>
    <p>${model.text}</p>
</div>

If it's not possible to use an existing element, prefer sly tags over introducing superfluous markup that renders on the page.

<!--/* Bad - additional div rendered */-->
<div data-sly-use.model="com.example.Model" data-sly-use.templates="templates.html"></div>
 
 
<!--/* Bad - not immediately clear if the element is part of the markup or just a holder for HTL */-->
<div data-sly-use.model="com.example.Model" data-sly-use.templates="templates.html" data-sly-unwrap></div>
 
 
<!--/* Good - it's clear this element doesn't render */-->
<sly data-sly-use.model="com.example.Model" data-sly-use.templates="templates.html"></sly>

Make AEM-8 allow annotations from org.osgi.service.component.annotations

AEM-8 pertains to the use of SCR annotations. When the @Component and @Property annotations are used to describe a Sling Servlet, the rule recommends the use od @SlingServlet.

In our case, the rule tells us to replace the new Declarative Services annotations with @SlingServlet, which we don't even keep on the classpath as we've migrated from the SCR annotations.

Violating code:

package com.foo.bar.core.components.page;

import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.api.NameConstants;
import com.google.common.net.MediaType;
import java.io.IOException;
import javax.servlet.Servlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;


@Component(
  service = Servlet.class,
  property = {
    "sling.servlet.extensions=json",
    "sling.servlet.selectors=details",
    "sling.servlet.resourceTypes=" + NameConstants.NT_PAGE
  }
)
public class PageDetailsServlet extends SlingAllMethodsServlet {

  @Override
  protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
    throws IOException {
    final Resource pageContentResource = request.getResource().getChild(JcrConstants.JCR_CONTENT);
    final PageModel page = ResourceUtil.adaptTo(pageContentResource, PageModel.class);

    response.setContentType(MediaType.JSON_UTF_8.toString());
    response.getWriter().write(JsonUtils.toJson(page));
  }

}ย 

Rule AEM-15 shows issue at annotation level

Rule AEM-15 shows issue next to annotation, for example:
@Override // issue
public void synchronized increment() {...

Expected:
@Override
public void synchronized increment() {... // issue

SessionShouldBeLoggedOutTest is not authoratitive

The file used by SessionShouldBeLoggedOutTest has a mix of compliant and non-compliant methods but only checks that at least one method is non-compliant. This can lead to false positives/negatives. It would be better to break these out into separate test files and use parameterized tests in JUnit.

Avoid inline code

Avoid inline CSS and JS code. One of the primary drivers behind the introduction of HTL was to avoid scriptlets and mixing code in multiple languages. Place CSS and JS in separate files.

Sonar crash after restar

Hi,

I installer the official LTS Sonar images at https://hub.docker.com/_/sonarqube/.

The image version:

docker images | grep sonar
sonarqube                                lts                 cd4a4caa7b28        8 days ago          744 M

The JAVA version in the image:

docker exec -it sonarqube java -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-1~bpo8+1-b11)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)

And, when I install the plugin and restart my Sonar, I have this traces:

java.lang.NoClassDefFoundError: com/google/common/base/Functions
        at com.cognifide.aemrules.extensions.RulesLoader.<clinit>(RulesLoader.java:49) ~[na:na]
        at com.cognifide.aemrules.extensions.AemRulesRulesDefinition.define(AemRulesRulesDefinition.java:30) ~[na:na]
        at org.sonar.server.rule.RuleDefinitionsLoader.load(RuleDefinitionsLoader.java:54) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.rule.RegisterRules.start(RegisterRules.java:97) ~[sonar-server-5.6.6.jar:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
        at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.invokeMethod(ReflectionLifecycleStrategy.java:110) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.start(ReflectionLifecycleStrategy.java:89) ~[picocontainer-2.15.jar:na]
        at org.sonar.core.platform.ComponentContainer$1.start(ComponentContainer.java:320) ~[sonar-core-5.6.6.jar:na]
        at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.start(AbstractInjectionFactory.java:84) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.AbstractBehavior.start(AbstractBehavior.java:169) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.Stored$RealComponentLifecycle.start(Stored.java:132) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.Stored.start(Stored.java:110) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.potentiallyStartAdapter(DefaultPicoContainer.java:1016) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.startAdapters(DefaultPicoContainer.java:1009) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.start(DefaultPicoContainer.java:767) ~[picocontainer-2.15.jar:na]
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:141) ~[sonar-core-5.6.6.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevel.start(PlatformLevel.java:84) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevelStartup.access$001(PlatformLevelStartup.java:45) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevelStartup$1.doPrivileged(PlatformLevelStartup.java:80) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.user.DoPrivileged.execute(DoPrivileged.java:44) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevelStartup.start(PlatformLevelStartup.java:77) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.Platform.executeStartupTasks(Platform.java:201) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.Platform.doStart(Platform.java:114) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.Platform.doStart(Platform.java:99) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.PlatformServletContextListener.contextInitialized(PlatformServletContextListener.java:44) ~[sonar-server-5.6.6.jar:na]
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4812) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_131]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]
Caused by: java.lang.ClassNotFoundException: com.google.common.base.Functions
        at org.sonar.classloader.ParentFirstStrategy.loadClass(ParentFirstStrategy.java:39) ~[sonar-classloader-1.0.jar:na]
        at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:87) ~[sonar-classloader-1.0.jar:na]
        at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:76) ~[sonar-classloader-1.0.jar:na]
        ... 37 common frames omitted

Use implicit HTL contexts when possible

HTL is pretty good at inferring the display context. Only specify the display context when it's necessary. Check the specification for a list of display contexts.

<!--/* Bad, display context is superfluous in both cases. */-->
<img alt="${model.imageAlt @ context='attribute'}" src="${model.imageUrl @ context='uri'}" />
 
<!--/* Good, this has the same effect as the example above */-->
<img alt="${model.imageAlt}" src="${model.imageUrl}" />
 
<!--/* Good, we can specify a more specific context that what would be inferred by HTL */-->
<div data-service-url="${model.url @ context='uri'}">
    <!-- some HTML -->
</div>
 
<!--/* Acceptable, we expect to render something unusual. */-->
<div class="someWeirdComponent">
    ${model.script @ context='unsafe'}
</div>

Rule AEM-9 session based classes inside anonymous classes inside private methods should not be marked as issue

Session based classes inside anonymous classes inside constructors or afterCreated or inside private methods invoked from constructor or afeterCreated should not be marked as issue, for example:

class A {
  @Inject
  private ResourceResolver resourceResolver;

  @Override
  public void afterCreated() {
    List<String> list = find();
  }

  private List<String> find() {
    return FluentIterable.from(ImmutableList.<String>of("a", "b", "c"))
      .transform(new Function<String, String>() {
        @Override
        public void String apply(String s) {
          return resourceResolver.getResource(s).getValueMap("string", String.class);
        }
      }).toList();
  }
}

resourceResolver.getResource(s) should not be marked as an issue.

Cannot start SonarQube because of duplicated rule

When using current code from master I'm not able to start SonarQube:
ERROR web[][o.s.s.p.Platform] Background initialization failed. Stopping SonarQube java.lang.IllegalArgumentException: The rule 'AEM-11' of repository 'AEM Rules' is declared several times

Sling Model annotation with multiply adaptables property fail the build

Hi!
I found that if class have multiply adaptables property, like
@model(adaptables = {Resource.class, SlingHttpServletRequest.class})
it fail check with next message:

[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.0.2:sonar (default-cli) on project xxx: SonarQube is unable to analyze file : 'x:\xx\xx\Foo.java': org.sonar.java.model.expression.NewArrayTreeImpl cannot be cast to org.sonar.plugins.java.api.tree.Me
mberSelectExpressionTree -> [Help 1]

Single property, like @model(adaptables = SlingHttpServletRequest.class) works well.

Could someone check ? Thanks.

Clarify the phrase 'changeable method'

I've had a look at the code while trying to figure out how one would go about implementing a rule and I noticed we're using the phrase changeable method in context of the ModifiableValueMap rule (AEM-17) in both the docs and the code.

I find this choice of words confusing. Judging by the context, it seems to mean a method that changes the state of an object. I have never seen the phrase changeable method used in this context. The use of the adjective seems to imply that it is the method is the subject of a change while in reality, it's the object on whose behalf the method is invoked that may or may not change.

Is there something I'm missing? I'm wondering where the phrase originated. If its use is accidental, how about referring to those methods as mutators ?

Implement HTL Sensor to support HTL language

Implement a new sensor that will support writing new rules for HTL language. Consider list of following rules when making decision on how the analysis should be performed:

< list of rules to be updated here >

(parser / regular expressions / jsoup / ?)

Extend rule AEM-3 with additional classes

AEM-3 checks for the use of three non-thread-safe classes in field declarations in Servlets and Servlet Filters.

Out of the box, the ResourceResolver can be adapted to several more classes:, including:

  • TagManager
  • AssetManager
  • UserManager
  • Preferences

To my knowledge, these also shouldn't be cached in a Sevlet/Filter field and It looks like including them in the AEM-3 rule would be very simple.

Not sure how many of those are likely to be used in this context. I believe some of these cases might be too absurd to even include (like caching a User object in a Servlet field) while some actually tend to be used in Servlets (TagManager, AssetManager)

Your thoughts?

Incompatible with new SonarJava 5.8 plugin (on SonarQube 7.3)

When installed along with SonarJava 5.8 (Build 15699), Sonar analysis fails. I am getting this error during analysis:

15:18:31 [ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.3.0.603:sonar (default-cli) on project com.###.###.###: SonarQube is unable to analyze file : '/###/###/###.java': java.lang.reflect.InvocationTargetException: com.google.common.base.Preconditions.checkNotNull(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; -> [Help 1]

I am getting the very same error for each Java project that is analysed using SonarQube 7.3 / SonarJava 5.8 / AEM Rules for SonarQube 0.10 (and a snapshot build of 0.11 source from 10/19/2018)

Rolling back the SonarJava plugin to a previous release (5.7) fixes the issue (tested with a snapshot build of aEM Rules for SonarQube 0.11 of 10/19/2018).

Define constants per AEM version

  1. Review current constants and validate whether current list holds up.
  2. Find out whether there are significant differences between versions of AEM and constants.
  3. Based on findings, prepare and describe chunk of work to deal with that

Each AEM JavaDocs comes with page summarising all constant values:

https://helpx.adobe.com/experience-manager/6-4/sites/developing/using/reference-materials/javadoc/constant-values.html

https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/reference-materials/javadoc/constant-values.html

https://helpx.adobe.com/experience-manager/6-2/sites/developing/using/reference-materials/javadoc/constant-values.html

AEM 6.0 & 6.1 probably do not provide their own one-pagers, you have to check class by class.

Also, in the project there is a Groovy script that helps to list constants.

AEM-6 crashes with null pointer exception

The analysis process crashes in certain situations.

Stack:

Caused by: java.lang.NullPointerException
    at com.cognifide.rnd.aemrules.checks.visitors.FindRRDeclarationVisitor.isManuallyCreatedResourceResolver(FindRRDeclarationVisitor.java:48)
    at com.cognifide.rnd.aemrules.checks.visitors.FindRRDeclarationVisitor.visitAssignmentExpression(FindRRDeclarationVisitor.java:38)
    at org.sonar.java.model.expression.AssignmentExpressionTreeImpl.accept(AssignmentExpressionTreeImpl.java:86)
    at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
    at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitExpressionStatement(BaseTreeVisitor.java:101)
    at org.sonar.java.model.statement.ExpressionStatementTreeImpl.accept(ExpressionStatementTreeImpl.java:70)
    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.visitBlock(BaseTreeVisitor.java:85)
    at org.sonar.java.model.statement.BlockTreeImpl.accept(BlockTreeImpl.java:91)
    at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
    at com.cognifide.rnd.aemrules.checks.visitors.FindRRDeclarationVisitor.visitTryStatement(FindRRDeclarationVisitor.java:92)
    at org.sonar.java.model.statement.TryStatementTreeImpl.accept(TryStatementTreeImpl.java:174)
    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.visitBlock(BaseTreeVisitor.java:85)
    at org.sonar.java.model.statement.BlockTreeImpl.accept(BlockTreeImpl.java:91)
    at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
    at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitMethod(BaseTreeVisitor.java:80)
    at org.sonar.java.model.declaration.MethodTreeImpl.accept(MethodTreeImpl.java:193)
    at com.cognifide.rnd.aemrules.checks.ResourceResolverShouldBeClosed.findResolversInMethod(ResourceResolverShouldBeClosed.java:59)
    at com.cognifide.rnd.aemrules.checks.ResourceResolverShouldBeClosed.visitMethod(ResourceResolverShouldBeClosed.java:39)
    at org.sonar.java.model.declaration.MethodTreeImpl.accept(MethodTreeImpl.java:193)
    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:189)
    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:205)
    at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:42)
    at com.cognifide.rnd.aemrules.checks.ResourceResolverShouldBeClosed.scanFile(ResourceResolverShouldBeClosed.java:34)
    at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:121)
    at com.sonar.sslr.impl.ast.AstWalker.walkAndVisit(AstWalker.java:67)
    at org.sonar.java.ast.AstScanner.simpleScan(AstScanner.java:107)
    ... 71 more

Else statement is not covered with unit tests

In file

AEM-Rules-for-SonarQube/src/main/java/com/cognifide/aemrules/checks/resourceresolver/close/FindRRDeclarationVisitor.java

133-135 lines are not covered with unit tests. Please add new testing case or remove this statement if not needed.

Quick Link

Technical Debt

Hi,

Please correct me, but did not see technical debt defined for the AEM rules.

Is it something which we have to define of our own?

Thanks
Milind

Sonar Analysis fails if analyzed using AEM profiles

Hi,

If I analyze my project with default java profile "Sonar Way" it runs fine. But If I activate AEM rules in "Sonar way + AEM" profile and analyze project against it then gives me below error ...
01:04:24 [INFO] Source paths: pom.xml, src/main/java
01:04:24 [INFO] Test paths: src/test/java
01:04:24 [INFO] Binary dirs: target/classes
01:04:24 [INFO] Source encoding: windows-1252, default locale: en_US
01:04:24 [INFO] Index files
01:04:25 [INFO] 171 files indexed
01:04:25 [INFO] Quality profile for java: Sonar way + AEM
01:04:25 [INFO] Sensor Lines Sensor
01:04:25 [INFO] Sensor Lines Sensor (done) | time=27ms
01:04:25 [INFO] Sensor JavaSquidSensor
01:04:25 [INFO] Configured Java source version (sonar.java.source): 7
01:04:25 [INFO] JavaClasspath initialization
01:04:25 [INFO] JavaClasspath initialization (done) | time=1ms
01:04:25 [INFO] JavaTestClasspath initialization
01:04:25 [INFO] JavaTestClasspath initialization (done) | time=1ms
01:04:25 [INFO] Java Main Files AST scan
01:04:25 [INFO] 165 source files to be analyzed
01:04:38 [INFO] BUILD FAILURE
01:04:38 [INFO] ------------------------------------------------------------------------
01:04:38 [INFO] Total time: 03:33 min
01:04:38 [INFO] Finished at: 2017-06-16T01:04:38-04:00
01:04:38 [INFO] Final Memory: 83M/828M
01:04:38 [INFO] ------------------------------------------------------------------------
01:04:38 [ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.2:sonar (default-cli) on project redesign: SonarQube is unable to analyze file : org.sonar.java.model.expression.MemberSelectExpressionTreeImpl cannot be cast to org.sonar.plugins.java.api.tree.IdentifierTree -> [Help 1]
01:04:38 org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.2:sonar (default-cli) on project redesign: SonarQube is unable to analyze file :
01:04:38 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
01:04:38 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
01:04:38 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
01:04:38 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
01:04:38 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
01:04:38 at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
01:04:38 at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
01:04:38 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347)
01:04:38 at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)
01:04:38 at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582)
01:04:38 at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
01:04:38 at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
01:04:38 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
01:04:38 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
01:04:38 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
01:04:38 at java.lang.reflect.Method.invoke(Method.java:497)
01:04:38 at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
01:04:38 at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
01:04:38 at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
01:04:38 at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
01:04:38 Caused by: org.apache.maven.plugin.MojoExecutionException: SonarQube is unable to analyze file :
01:04:38 at org.sonarsource.scanner.maven.bootstrap.ExceptionHandling.handle(ExceptionHandling.java:36)
01:04:38 at org.sonarsource.scanner.maven.bootstrap.ScannerBootstrapper.execute(ScannerBootstrapper.java:81)
01:04:38 at org.sonarsource.scanner.maven.SonarQubeMojo.execute(SonarQubeMojo.java:122)
01:04:38 at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
01:04:38 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
01:04:38 ... 19 more
01:04:38 Caused by: org.sonar.squidbridge.api.AnalysisException: SonarQube is unable to analyze file :
01:04:38 at org.sonar.java.ast.JavaAstScanner.simpleScan(JavaAstScanner.java:96)
01:04:38 at org.sonar.java.ast.JavaAstScanner.scan(JavaAstScanner.java:63)
01:04:38 at org.sonar.java.JavaSquid.scanSources(JavaSquid.java:119)
01:04:38 at org.sonar.java.JavaSquid.scan(JavaSquid.java:113)
01:04:38 at org.sonar.plugins.java.JavaSquidSensor.execute(JavaSquidSensor.java:84)
01:04:38 at org.sonar.batch.sensor.SensorWrapper.analyse(SensorWrapper.java:57)
01:04:38 at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:58)
01:04:38 at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:50)
01:04:38 at org.sonar.batch.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:83)
01:04:38 at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:192)
01:04:38 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
01:04:38 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
01:04:38 at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:241)
01:04:38 at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:236)
01:04:38 at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:234)
01:04:38 at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:226)
01:04:38 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
01:04:38 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
01:04:38 at org.sonar.batch.task.ScanTask.execute(ScanTask.java:47)
01:04:38 at org.sonar.batch.task.TaskContainer.doAfterStart(TaskContainer.java:86)
01:04:38 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:142)
01:04:38 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:127)
01:04:38 at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:106)
01:04:38 at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:119)
01:04:38 at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:62)
01:04:38 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
01:04:38 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
01:04:38 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
01:04:38 at java.lang.reflect.Method.invoke(Method.java:497)
01:04:38 at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
01:04:38 at com.sun.proxy.$Proxy21.execute(Unknown Source)
01:04:38 at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:233)
01:04:38 at org.sonarsource.scanner.api.EmbeddedScanner.runAnalysis(EmbeddedScanner.java:151)
01:04:38 at org.sonarsource.scanner.maven.bootstrap.ScannerBootstrapper.execute(ScannerBootstrapper.java:78)
01:04:38 ... 22 more
01:04:38 Caused by: java.lang.ClassCastException: org.sonar.java.model.expression.MemberSelectExpressionTreeImpl cannot be cast to org.sonar.plugins.java.api.tree.IdentifierTree
01:04:38 at com.cognifide.aemrules.checks.visitors.FindSessionDeclarationVisitor.getMethodTree(FindSessionDeclarationVisitor.java:93)
01:04:38 at com.cognifide.aemrules.checks.visitors.FindSessionDeclarationVisitor.access$500(FindSessionDeclarationVisitor.java:41)
01:04:38 at com.cognifide.aemrules.checks.visitors.FindSessionDeclarationVisitor$CheckIfSessionCreatedManually.visitAssignmentExpression(FindSessionDeclarationVisitor.java:159)
01:04:38 at org.sonar.java.model.expression.AssignmentExpressionTreeImpl.accept(AssignmentExpressionTreeImpl.java:71)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitExpressionStatement(BaseTreeVisitor.java:101)
01:04:38 at org.sonar.java.model.statement.ExpressionStatementTreeImpl.accept(ExpressionStatementTreeImpl.java:65)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitBlock(BaseTreeVisitor.java:85)
01:04:38 at org.sonar.java.model.statement.BlockTreeImpl.accept(BlockTreeImpl.java:77)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitIfStatement(BaseTreeVisitor.java:107)
01:04:38 at org.sonar.java.model.statement.IfStatementTreeImpl.accept(IfStatementTreeImpl.java:124)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitBlock(BaseTreeVisitor.java:85)
01:04:38 at org.sonar.java.model.statement.BlockTreeImpl.accept(BlockTreeImpl.java:77)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitMethod(BaseTreeVisitor.java:80)
01:04:38 at com.cognifide.aemrules.checks.visitors.FindSessionDeclarationVisitor$CheckIfSessionCreatedManually.visitMethod(FindSessionDeclarationVisitor.java:148)
01:04:38 at org.sonar.java.model.declaration.MethodTreeImpl.accept(MethodTreeImpl.java:218)
01:04:38 at com.cognifide.aemrules.checks.visitors.FindSessionDeclarationVisitor.isManuallyCreatedSession(FindSessionDeclarationVisitor.java:88)
01:04:38 at com.cognifide.aemrules.checks.visitors.FindSessionDeclarationVisitor.findSessionsCreatedInMethods(FindSessionDeclarationVisitor.java:73)
01:04:38 at com.cognifide.aemrules.checks.visitors.FindSessionDeclarationVisitor.visitAssignmentExpression(FindSessionDeclarationVisitor.java:65)
01:04:38 at org.sonar.java.model.expression.AssignmentExpressionTreeImpl.accept(AssignmentExpressionTreeImpl.java:71)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitExpressionStatement(BaseTreeVisitor.java:101)
01:04:38 at org.sonar.java.model.statement.ExpressionStatementTreeImpl.accept(ExpressionStatementTreeImpl.java:65)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitBlock(BaseTreeVisitor.java:85)
01:04:38 at org.sonar.java.model.statement.BlockTreeImpl.accept(BlockTreeImpl.java:77)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitIfStatement(BaseTreeVisitor.java:107)
01:04:38 at org.sonar.java.model.statement.IfStatementTreeImpl.accept(IfStatementTreeImpl.java:124)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitBlock(BaseTreeVisitor.java:85)
01:04:38 at org.sonar.java.model.statement.BlockTreeImpl.accept(BlockTreeImpl.java:77)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at com.cognifide.aemrules.checks.visitors.FindSessionDeclarationVisitor.visitTryStatement(FindSessionDeclarationVisitor.java:132)
01:04:38 at org.sonar.java.model.statement.TryStatementTreeImpl.accept(TryStatementTreeImpl.java:171)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitBlock(BaseTreeVisitor.java:85)
01:04:38 at org.sonar.java.model.statement.BlockTreeImpl.accept(BlockTreeImpl.java:77)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitMethod(BaseTreeVisitor.java:80)
01:04:38 at org.sonar.java.model.declaration.MethodTreeImpl.accept(MethodTreeImpl.java:218)
01:04:38 at com.cognifide.aemrules.checks.SessionShouldBeLoggedOut.findSessionsInMethod(SessionShouldBeLoggedOut.java:81)
01:04:38 at com.cognifide.aemrules.checks.SessionShouldBeLoggedOut.visitMethod(SessionShouldBeLoggedOut.java:61)
01:04:38 at org.sonar.java.model.declaration.MethodTreeImpl.accept(MethodTreeImpl.java:218)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitClass(BaseTreeVisitor.java:69)
01:04:38 at org.sonar.java.model.declaration.ClassTreeImpl.accept(ClassTreeImpl.java:194)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitCompilationUnit(BaseTreeVisitor.java:55)
01:04:38 at org.sonar.java.model.JavaTree$CompilationUnitTreeImpl.accept(JavaTree.java:184)
01:04:38 at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
01:04:38 at com.cognifide.aemrules.checks.SessionShouldBeLoggedOut.scanFile(SessionShouldBeLoggedOut.java:56)
01:04:38 at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:115)
01:04:38 at org.sonar.java.ast.JavaAstScanner.simpleScan(JavaAstScanner.java:87)
01:04:38 ... 55 more
01:04:38 [ERROR]
01:04:38 [ERROR] Re-run Maven using the -X switch to enable full debug logging.
01:04:38 [ERROR]
01:04:38 [ERROR] For more information about the errors and possible solutions, please read the following articles:
01:04:38 [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
01:04:38 Sonar analysis completed: FAILURE

Can you please help me to figure out solution for this.
I am using SonarQube 5.6.6, SonarJava 4.9 & AEM rules plugin 0.8.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.