[英]How to use Android Classes on a Sonarqube custom rule
我正在嘗試為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!");
}
}
在另一條規則上,我嘗試獲取使用SharedPreferences的所有代碼情況,並使用以下邏輯:
@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!!");
}
}
當我在JUnit上運行測試時,它不起作用。 找到指定的Kind,符號名稱(應為“調用的方法”的名稱)和封閉類時,我已經進行了打印。 結果是:
====================== Kind Finded ======================
Name >>>>>>>>>>>>>null
Class >>>>>>>>>>>>> !unknownSymbol!
這是另一個文件的示例,在該文件中可以打印其他類和方法,而不會出現問題:
====================== 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類。 我已經嘗試將jar的Android庫和Sonarqube Android插件導入到我的項目中,但是沒有用。
這是我正在測試的目標文件(是的,我也嘗試將我的Rule代碼包導入目標中,但沒有用。我認為值得嘗試):
package jakhar.aseem.diva;
import org.sonar.template.java.checks.SharedPreferencesCheck;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class InsecureDataStorage1Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_insecure_data_storage1);
}
public void saveCredentials(View view) {
SharedPreferences spref = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor spedit = spref.edit(); // Noncompliant
EditText usr = (EditText) findViewById(R.id.ids1Usr);
EditText pwd = (EditText) findViewById(R.id.ids1Pwd);
spedit.putString("user", usr.getText().toString());
spedit.putString("password", pwd.getText().toString());
spedit.commit();
Toast.makeText(this,"3rd party credentials saved successfully!", Toast.LENGTH_SHORT).show();
}
}
因此,問題是:如何使測試識別Android類並驗證我的規則?
我正在使用SonarQube文檔中的以下模板來開發規則: https ://docs.sonarqube.org/display/PLUG/Writing+Custom+Java+Rules+101
任何幫助,我將不勝感激。
從現在開始,感謝您的關注。
-------------------編輯-------------------
我已經向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>
得到它了!
問題出在SonarQube依賴項的導入上。 我在pom.xml上添加了許多Android依賴項,並在更改后進行測試。 在此之后,仍然無法正常工作。 在一些搜索中,我發現負責解釋類的是android-maven-plugin。 當我通過Eclipse的pom接口導入時,總是會遇到一些錯誤,說明缺少一些arctifact。 發生此問題是因為遠程依賴項已損壞或不存在,所以我從依賴項下載了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!!");
}
}
}
我希望它可以幫助遇到相同或相似問題的人。
如果有人可以給出更好的解釋,那將是非常有幫助的。
非常感謝!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.