Java 如何在自定义规则上使用Android类

Java 如何在自定义规则上使用Android类,java,android,plugins,sonarqube,rules,Java,Android,Plugins,Sonarqube,Rules,我正在尝试为SonarQube Java插件开发一个自定义规则,它将在其中分析Android代码。我已经创建了一些规则,这些规则只标识Java的基本功能,如下例所示: @Override public void visitNode(Tree tree){ MethodInvocationTree method = (MethodInvocationTree) tree; Symbol symbol = method.symbol(); if (symbol.name() != nu

我正在尝试为SonarQube Java插件开发一个自定义规则,它将在其中分析Android代码。我已经创建了一些规则,这些规则只标识Java的基本功能,如下例所示:

@Override
public void visitNode(Tree tree){
  MethodInvocationTree method = (MethodInvocationTree) tree;
  Symbol symbol = method.symbol();

  if (symbol.name() != null && symbol.name().equalsIgnoreCase("createTempFile")){
      reportIssue(method.firstToken(), "Criação de arquivo temporário identificada. Analisar!");
  }

}
在另一条规则中,我尝试获取使用SharedReference的代码的所有情况,并使用以下逻辑:

@Override
public List<Kind> nodesToVisit() {
  return ImmutableList.of(Kind.METHOD_INVOCATION);
}

@Override
public void visitNode(Tree tree){
    MethodInvocationTree kindTree = (MethodInvocationTree) tree;
    Symbol symbol = (Symbol) kindTree.symbol();

    TypeSymbol classe = symbol.owner().enclosingClass();

    if (classe != null && classe.equals("SharedPreferences")){
        reportIssue(kindTree.firstToken(), "SharedPreferences sendo utilizado no código. Analisar!!");
    }

}
下面是一个带有另一个文件的示例,其中它可以毫无问题地打印其他类和方法:

====================== Kind Finded ======================
Name >>>>>>>>>>>>>createTempFile
Class >>>>>>>>>>>>> File
====================== Kind Finded ======================
Name >>>>>>>>>>>>>setReadable
Class >>>>>>>>>>>>> File
====================== Kind Finded ======================
Name >>>>>>>>>>>>>setWritable
Class >>>>>>>>>>>>> File
====================== Kind Finded ======================
Name >>>>>>>>>>>>>write
Class >>>>>>>>>>>>> Writer
似乎在我运行测试时,JUnit或Maven无法从代码中识别Android类。我已经尝试将Android库和Sonarqube Android插件的jar导入到我的项目中,但没有成功

这是我正在测试的目标文件(是的,我也尝试在目标中导入我的规则代码包,但没有成功。我认为值得一试):

所以问题是:我如何让测试识别Android类并验证我的规则

我使用SonarQube文档中的以下模板来制定规则:

任何帮助,我都会非常感激

从现在起,感谢您的关注

-------------------编辑-------------------

我已经向Maven添加了一些android依赖项,但仍然不起作用。 遵循我的项目的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.sonar.samples</groupId>
<artifactId>java-custom-rules-template</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>sonar-plugin</packaging>

<properties>
    <sonar.version>5.6.3</sonar.version>
    <java.plugin.version>4.2.1.6971</java.plugin.version>
    <sslr.version>1.21</sslr.version>
</properties>

<name>Berghem Custom Rules</name>
<description>Criação de Rules Customizadas para avaliação de códigos Java</description>

<dependencies>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->

    <dependency>
        <groupId>org.sonarsource.sonarqube</groupId>
        <artifactId>sonar-plugin-api</artifactId>
        <version>${sonar.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.java</groupId>
        <artifactId>sonar-java-plugin</artifactId>
        <type>sonar-plugin</type>
        <version>${java.plugin.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.java</groupId>
        <artifactId>java-frontend</artifactId>
        <version>${java.plugin.version}</version>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.sslr-squid-bridge</groupId>
        <artifactId>sslr-squid-bridge</artifactId>
        <version>2.6.1</version>
        <exclusions>
            <exclusion>
                <groupId>org.codehaus.sonar.sslr</groupId>
                <artifactId>sslr-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.codehaus.sonar</groupId>
                <artifactId>sonar-plugin-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.codehaus.sonar.sslr</groupId>
                <artifactId>sslr-xpath</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.java</groupId>
        <artifactId>java-checks-testkit</artifactId>
        <version>${java.plugin.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.sslr</groupId>
        <artifactId>sslr-testing-harness</artifactId>
        <version>${sslr.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.2</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.easytesting</groupId>
        <artifactId>fest-assert</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>0.9.30</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.android.tools</groupId>
        <artifactId>common</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools</groupId>
        <artifactId>dvlib</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools</groupId>
        <artifactId>sdk-common</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools</groupId>
        <artifactId>sdklib</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.sonar</groupId>
        <artifactId>sonar-check-api</artifactId>
        <version>4.5.1</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.sonar-plugins.java</groupId>
        <artifactId>java-checks</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>org.sonarsource.java</groupId>
        <artifactId>java-checks</artifactId>
        <version>4.2.1.6971</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.sonar.sslr-squid-bridge</groupId>
        <artifactId>sslr-squid-bridge</artifactId>
        <version>2.6</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.sonar</groupId>
        <artifactId>sonar-plugin-api</artifactId>
        <version>4.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools.lint</groupId>
        <artifactId>lint-checks</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools.lint</groupId>
        <artifactId>lint-api</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools.lint</groupId>
        <artifactId>lint</artifactId>
        <version>22.4.2</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
            <artifactId>sonar-packaging-maven-plugin</artifactId>
            <version>1.17</version>
            <extensions>true</extensions>
            <configuration>
                <pluginKey>java-template-custom</pluginKey>
                <pluginName>Java Template Custom Rules</pluginName>
                <pluginClass>org.sonar.template.java.JavaCustomRulesPlugin</pluginClass>
                <sonarLintSupported>true</sonarLintSupported>
                <sonarQubeMinVersion>5.6</sonarQubeMinVersion> <!-- allow to depend on API 6.x but run on LTS -->
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

4.0.0
org.sonar.samples
java自定义规则模板
1.0-快照
声纳插件
5.6.3
4.2.1.6971
1.21
伯格姆海关规则
《爪哇战争规则》
org.sonarsource.sonarqube
声纳插件api
${sonar.version}
假如
org.sonarsource.java
声纳java插件
声纳插件
${java.plugin.version}
假如
org.sonarsource.java
java前端
${java.plugin.version}
org.sonarsource.sslr-squid-bridge
sslr squid桥
2.6.1
org.codehaus.sonar.sslr
sslr堆芯
org.codehaus.sonar
声纳插件api
org.codehaus.sonar.sslr
sslrpath
org.slf4j
jcl-over-slf4j
org.slf4j
slf4j api
org.sonarsource.java
java检查测试工具包
${java.plugin.version}
测试
org.sonarsource.sslr
sslr测试线束
${sslr.version}
测试
org.slf4j
slf4j api
1.6.2
朱尼特
朱尼特
4.11
测试
org.easytesting
节日断言
1.4
测试
回写
回归经典
0.9.30
测试
com.android.tools
常见的
22.4.2
com.android.tools
dvlib
22.4.2
com.android.tools
sdk通用
22.4.2
com.android.tools
sdklib
22.4.2
org.codehaus.sonar
声纳检查api
4.5.1
org.codehaus.sonar-plugins.java
java支票
2
org.sonarsource.java
java支票
4.2.1.6971
org.codehaus.sonar.sslr-squid-bridge
sslr squid桥
2.6
org.codehaus.sonar
声纳插件api
4.5.1
com.android.tools.lint
皮棉格
22.4.2
番石榴
番石榴
19
com.android.tools.lint
皮棉原料药
22.4.2
com.android.tools.lint
绒毛
22.4.2
org.sonarsource.sonar-packaging-maven-plugin
声纳封装maven插件
1.17
真的
java模板自定义
Java模板自定义规则
org.sonar.template.java.JavaCustomRulesPlugin
真的
5.6
org.apache.maven.plugins
maven编译器插件
3.6.0
1.8
1.8
明白了

问题在于SonarQube依赖项的导入。我在pom.xml上添加了很多Android依赖项,并在修改后进行了测试。在这之后,仍然没有工作。在一些搜索中,我发现负责解释类的是android maven插件。当我通过Eclipse的pom接口导入时,总是会出现一些错误,说缺少一些arctifacts。发生此问题的原因是远程依赖项已损坏或不存在,因此我从依赖项下载了jar文件,并创建了一个文件
target/test jars
。这样,maven就可以识别外部依赖项并继续JUnit的测试

为了验证信息,我已经在规则检查文件中打印了类的属性:

package org.sonar.template.java.checks;

import com.google.common.collect.ImmutableList;

import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Symbol.TypeSymbol;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import org.sonar.plugins.java.api.tree.Tree.Kind;

import java.util.List;

@Rule(
    key = "SharedPreferencesRule",
    name = "Utilização de SharedPreferences no código",
    description = "Para cada utilização de SharedPreferences, é feito um alerta para revisar o que está sendo armazenado.",
    priority = Priority.CRITICAL,
    tags = {"attention point", "security"})
public class SharedPreferencesCheck extends IssuableSubscriptionVisitor {

    @Override
  public List<Kind> nodesToVisit() {
    return ImmutableList.of(Kind.METHOD_INVOCATION);
  }

  @Override
  public void visitNode(Tree tree){
      System.out.println("====================== Kind Finded ======================");

      MethodInvocationTree kindTree = (MethodInvocationTree) tree;

      Symbol symbol = (Symbol) kindTree.symbol();

      TypeSymbol classe = symbol.owner().enclosingClass();

      System.out.println("Name >>>>>>>>>>>>> " + symbol.name());
      System.out.println("Enclosing >>>>>>>>>>>>> " + classe);

      if (classe != null && classe.equals("SharedPreferences")){
          reportIssue(kindTree.firstToken(), "SharedPreferences sendo utilizado no código. Analisar!!");
      }

  }
}
包org.sonar.template.java.checks;
导入com.google.common.collect.ImmutableList;
导入org.sonar.check.Priority;
导入org.sonar.check.Rule;
导入org.sonar.plugins.java.api.semantic.Symbol;
导入org.sonar.plugins.java.api.semantic.Symbol.TypeSymbol;
导入org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
导入org.sonar.plugins.java.api.tree.*;
导入org.sonar.plugins.java.api.tree.tree.Kind;
导入java.util.List;
@统治(
key=“SharedReferencesRule”,
name=“Utilização de SharedReferences no código”,
description=“共享参考资料的实用性,以及对军备审查的警示。”,
优先级=优先级。关键,
标签={“注意点”,“安全性”})
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.sonar.samples</groupId>
<artifactId>java-custom-rules-template</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>sonar-plugin</packaging>

<properties>
    <sonar.version>5.6.3</sonar.version>
    <java.plugin.version>4.2.1.6971</java.plugin.version>
    <sslr.version>1.21</sslr.version>
</properties>

<name>Berghem Custom Rules</name>
<description>Criação de Rules Customizadas para avaliação de códigos Java</description>

<dependencies>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->

    <dependency>
        <groupId>org.sonarsource.sonarqube</groupId>
        <artifactId>sonar-plugin-api</artifactId>
        <version>${sonar.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.java</groupId>
        <artifactId>sonar-java-plugin</artifactId>
        <type>sonar-plugin</type>
        <version>${java.plugin.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.java</groupId>
        <artifactId>java-frontend</artifactId>
        <version>${java.plugin.version}</version>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.sslr-squid-bridge</groupId>
        <artifactId>sslr-squid-bridge</artifactId>
        <version>2.6.1</version>
        <exclusions>
            <exclusion>
                <groupId>org.codehaus.sonar.sslr</groupId>
                <artifactId>sslr-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.codehaus.sonar</groupId>
                <artifactId>sonar-plugin-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.codehaus.sonar.sslr</groupId>
                <artifactId>sslr-xpath</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.java</groupId>
        <artifactId>java-checks-testkit</artifactId>
        <version>${java.plugin.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.sonarsource.sslr</groupId>
        <artifactId>sslr-testing-harness</artifactId>
        <version>${sslr.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.2</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.easytesting</groupId>
        <artifactId>fest-assert</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>0.9.30</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.android.tools</groupId>
        <artifactId>common</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools</groupId>
        <artifactId>dvlib</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools</groupId>
        <artifactId>sdk-common</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools</groupId>
        <artifactId>sdklib</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.sonar</groupId>
        <artifactId>sonar-check-api</artifactId>
        <version>4.5.1</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.sonar-plugins.java</groupId>
        <artifactId>java-checks</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>org.sonarsource.java</groupId>
        <artifactId>java-checks</artifactId>
        <version>4.2.1.6971</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.sonar.sslr-squid-bridge</groupId>
        <artifactId>sslr-squid-bridge</artifactId>
        <version>2.6</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.sonar</groupId>
        <artifactId>sonar-plugin-api</artifactId>
        <version>4.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools.lint</groupId>
        <artifactId>lint-checks</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools.lint</groupId>
        <artifactId>lint-api</artifactId>
        <version>22.4.2</version>
    </dependency>
    <dependency>
        <groupId>com.android.tools.lint</groupId>
        <artifactId>lint</artifactId>
        <version>22.4.2</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
            <artifactId>sonar-packaging-maven-plugin</artifactId>
            <version>1.17</version>
            <extensions>true</extensions>
            <configuration>
                <pluginKey>java-template-custom</pluginKey>
                <pluginName>Java Template Custom Rules</pluginName>
                <pluginClass>org.sonar.template.java.JavaCustomRulesPlugin</pluginClass>
                <sonarLintSupported>true</sonarLintSupported>
                <sonarQubeMinVersion>5.6</sonarQubeMinVersion> <!-- allow to depend on API 6.x but run on LTS -->
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
package org.sonar.template.java.checks;

import com.google.common.collect.ImmutableList;

import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.semantic.Symbol;
import org.sonar.plugins.java.api.semantic.Symbol.TypeSymbol;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.*;
import org.sonar.plugins.java.api.tree.Tree.Kind;

import java.util.List;

@Rule(
    key = "SharedPreferencesRule",
    name = "Utilização de SharedPreferences no código",
    description = "Para cada utilização de SharedPreferences, é feito um alerta para revisar o que está sendo armazenado.",
    priority = Priority.CRITICAL,
    tags = {"attention point", "security"})
public class SharedPreferencesCheck extends IssuableSubscriptionVisitor {

    @Override
  public List<Kind> nodesToVisit() {
    return ImmutableList.of(Kind.METHOD_INVOCATION);
  }

  @Override
  public void visitNode(Tree tree){
      System.out.println("====================== Kind Finded ======================");

      MethodInvocationTree kindTree = (MethodInvocationTree) tree;

      Symbol symbol = (Symbol) kindTree.symbol();

      TypeSymbol classe = symbol.owner().enclosingClass();

      System.out.println("Name >>>>>>>>>>>>> " + symbol.name());
      System.out.println("Enclosing >>>>>>>>>>>>> " + classe);

      if (classe != null && classe.equals("SharedPreferences")){
          reportIssue(kindTree.firstToken(), "SharedPreferences sendo utilizado no código. Analisar!!");
      }

  }
}