> ## Content Index
> Fetch the complete content index at: https://www.popit.kr/llms.txt
> Use this file to discover other available public pages before exploring further.

# Java 개발자를 위한 Maven + SonarQube + Docker로 시작하는 코드 정적 분석
- URL: https://www.popit.kr/java-maven-sonarqube-docker-static-analysis/
- Published: 2018-02-06T04:45:46.000Z
- Updated: 2018-02-26T23:17:42.000Z
- Author: 유 영모
- Tags: #소프트웨어, Java, 코드 정적 분석, SonarQube

켄트 벡Kent Beck은 자신의 책 [익스트림 프로그래밍Extreme Programming](http://www.yes24.com/24/goods/2126201?scode=032&OzSrank=1&ref=popit.kr)에서 5 가치\[1\] 를 이야기 했는데 그중 하나가 피드백Feedback이다.

> 한번에 완벽하게 해결하기를 바라는 것보다 점진적 개선에 만족하기 때문에 우리는 피드백을 이용해 목표에 점점 더 가까이 다가간다. 피드백은 여러 가지 형식으로 우리에게 들어온다. - 익스트림 프로그래밍 47 쪽

더 나은 코드를 만들기 위해서는 피드백이 필수이다. 어떻게 하면 효과적인 피드백을 받을 수 있을까?

필자는 코드 정적 분석 도구의 사용이 효과적인 피드백 중 하나라고 생각한다.

정적 분석 도구는 코드를 분석하여 여러 가지로 지적(?)을 한다. 개발자는 정적 분석 도구로부터의 피드백을 통해 자신의 코드를 뒤돌아 볼수 있는 계기를 가질 수 있으며 더 나아가 개선까지 이어질 수 있다.

![이미지 출처 : http://www.yeahwrite.org/?p=3322](https://www.popit.kr/content/images/wp/2018/02/image2018-2-1_9-33-15-600x357.png)

이미지 출처 : http://www.yeahwrite.org/?p=3322

정적 분석 도구의 종류는 프로그래밍 언어만큼이나 많다.\[2\] 이 글은 그중에서도 [SonarQube](https://www.sonarqube.org/?ref=popit.kr)를 소개한다.

# [SonarQube](https://www.sonarqube.org/?ref=popit.kr)

예전에는 Sonar라고 했지만 지금은 SonarQube로 이름을 바꾸었다.\[3\]

![https://www.sonarqube.org/](https://www.popit.kr/content/images/wp/2018/02/image2018-1-31_9-2-57-600x312.png)

https://www.sonarqube.org/

[SonarSouce](https://www.sonarsource.com/?ref=popit.kr)에서 만든 [SonarQube](https://www.sonarqube.org/?ref=popit.kr)는 코드를 분석하여 중복, 테스트 커버리지, 코드 복잡도, 버그, 보안 취약성 등을 리포팅 해주며, IDE([Eclipse](https://en.wikipedia.org/wiki/Eclipse%5F%28software%29?ref=popit.kr), [Visual Studio](https://en.wikipedia.org/wiki/Microsoft%5FVisual%5FStudio?ref=popit.kr), [IntelliJ IDEA](https://en.wikipedia.org/wiki/IntelliJ%5FIDEA?ref=popit.kr)), 빌드 도구([Maven](https://en.wikipedia.org/wiki/Apache%5FMaven?ref=popit.kr), [Ant](https://en.wikipedia.org/wiki/Apache%5FAnt?ref=popit.kr), [Gradle](https://en.wikipedia.org/wiki/Gradle?ref=popit.kr), [MSBuild](https://en.wikipedia.org/wiki/MSBuild?ref=popit.kr)), CIContinuous Integration 도구([Atlassian Bamboo](https://en.wikipedia.org/wiki/Bamboo%5F%28software%29?ref=popit.kr), [Jenkins](https://en.wikipedia.org/wiki/Jenkins%5F%28software%29?ref=popit.kr), [Hudson](https://en.wikipedia.org/wiki/Hudson%5F%28software%29?ref=popit.kr))와 통합하여 사용할 수 있다. 이에 더해 단일 프로그래밍 언어만 분석 가능한 것이 아니라 다양한 프로그래밍 언어로 만든 코드를 분석할 수 있다.\[4\]

자세한 SonarQube 리포팅 결과는 아래 체험 사이트에서 확인할 수 있다.

![https://sonarcloud.io/explore/projects](https://www.popit.kr/content/images/wp/2018/02/image2018-2-1_10-27-11-600x597.png)

https://sonarcloud.io/explore/projects

# [Docker](https://www.docker.com/?ref=popit.kr)로 SonarQube 서버 설치 하기

Docker 개념이 생소하다면 [김형준](https://www.popit.kr/author/babokim/)님의 글([개발자가 처음 Docker 접할때 오는 멘붕 몇가지](https://www.popit.kr/docker-first-encounter-confusions/))을 읽어 보기를 권한다.

Docker가 설치되어 있지 않다면 아래 URL에서 다운로드해 설치한다.

- [https://docs.docker.com/install/](https://docs.docker.com/install/?ref=popit.kr)

[SonarQube는 Docker 이미지](https://hub.docker.com/%5F/sonarqube/?ref=popit.kr)를 제공한다. Docker 이미지를 다운로드하여 SonarQube 서버를 시작해 보자.  

```sh
// SonarQube Docker 이미지 다운로드
$ docker pull sonarqube
// SonarQube 서버 시작
$ docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 sonarqube
```

정상적으로 SonarQube 서버가 시작되었다면 [http://localhost:9000/](http://localhost:9000/?ref=popit.kr)에 접속해 보면 아래와 같은 화면이 나타난다.

![image2018-2-1_15-41-1](https://www.popit.kr/content/images/wp/2018/02/image2018-2-1_15-41-1-600x259.png)

# Java [Maven](http://maven.apache.org/?ref=popit.kr) 프로젝트를 SonarQube 정적 분석하기

이 글에서는 [Java 언어(1.8)](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html?ref=popit.kr)로 만든 코드를 분석하며, 빌드 도구로는 Maven을 사용한다.

먼저 분석할 Java 코드를 준비해 보자.

[필자의 GitHub](https://github.com/YooYoungmo/gs-spring-boot?ref=popit.kr)에 올라가 있는 [Spring Boot 프로젝트(Building an Application with Spring Boot)](https://spring.io/guides/gs/spring-boot/?ref=popit.kr) 체크아웃 받는다.(참고로 Spring Boot를 몰라도 된다. 이 글에서는 정적 분석 예제 코드로만 쓸 뿐이다)

- [https://github.com/YooYoungmo/gs-spring-boot.git](https://github.com/YooYoungmo/gs-spring-boot.git?ref=popit.kr)

이제 Maven으로 SonarQube로 정적 분석을 실행해 보자.

Maven이 설치되어 있지 않다면 아래 URL을 참고하여 설치한다.

- [https://maven.apache.org/download.cgi](https://maven.apache.org/download.cgi?ref=popit.kr)

Maven의 [settings.xml](http://maven.apache.org/settings.html?ref=popit.kr) 파일에 SonarQube 서버 설정을 추가한다.

참고로 settings.xml 파일 위치는 2개다. 둘 중 하나에 추가하면 된다.(해당 디렉토리에 settings.xml 파일이 없다면 새로 만들면 된다.)

- Maven 설치 디렉토리 : ${maven.home}/conf/settings.xml
- 사용자 홈 디렉토리 : ${user.home}/.m2/settings.xml

```xhtml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
    <pluginGroups>
        <pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
    </pluginGroups>
    <profiles>
        <profile>
            <id>sonar</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <!-- Optional URL to server. Default value is http://localhost:9000 -->
                <sonar.host.url>
                  http://localhost:9000
                </sonar.host.url>
            </properties>
        </profile>
     </profiles>
</settings>
```

체크아웃 받은 프로젝트 디렉토리(pom.xml 이 존재하는 디렉토리)에서 Maven Goal을 실행한다.  

```sh
mvn sonar:sonar
```

오류 없이 실행되었다면 SonarQube 서버([http://localhost:9000](http://localhost:9000/?ref=popit.kr))에서 예제 프로젝트(gs-spring-boot)가 분석된 것을 확인할 수 있다.

![image2018-2-6_10-27-10](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_10-27-10-600x278.png)

![image2018-2-6_10-27-52](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_10-27-52-600x179.png)

# IntelliJ와 SonarQube 서버 통합

[SonarSouce](https://www.sonarsource.com/?ref=popit.kr)는 SonarQube 서버와 IDE와 통합해서 사용할 수 있는 [SonarLint](https://www.sonarlint.org/?ref=popit.kr)를 IDEIntegrated Development Environment의 플러그인Plugin 형태로 제공한다.

![https://www.sonarlint.org/](https://www.popit.kr/content/images/wp/2018/02/image2018-1-31_9-38-21-600x259.png)

https://www.sonarlint.org/

SonarLint를 사용하면 IDE에서 정적 분석을 실행할 수 있고 코드 편집창에서 정적 분석 결과 확인할 수 있어 편하다.

IDE 중 하나인 IntelliJ에 SonarLint를 설치해 보고, SonarQube 서버와 통합해 보자.

## SonarLint 설치

1 Preferences 창을 연다

2 SonarLint Plugin을 인스톨한다(Plugins | Browse repositories.. | SonarLint)

![image2018-2-6_10-57-37](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_10-57-37-464x600.png)

## SonarLint와 SonarQube 서버 연결

1 SonarLint 창을 연다(View|Tools Windows|SonarLint)

2 SonarQube서버와 연결한다

![image2018-2-6_11-7-54](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_11-7-54-600x325.png)

![image2018-2-6_11-11-19](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_11-11-19-600x398.png)

![image2018-2-6_11-13-4](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_11-13-4-600x263.png)

![image2018-2-6_11-14-12](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_11-14-12-600x556.png)

## SonarLint로 정적 분석 실행

컨텍스트 메뉴에서 Analyze|Analyze All File with SonarLint 선택하면 전체 파일을 분석한다.

![image2018-2-6_11-17-4](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_11-17-4-600x566.png)

분석 결과는 SonarLint 창에서 확인할 수 있다.

![image2018-2-6_11-19-42](https://www.popit.kr/content/images/wp/2018/02/image2018-2-6_11-19-42-600x339.png)

# Maven 멀티 모듈로 프로젝트가 구성되어 있다면

Maven 멀티 모듈일 경우 테스트 커버리지가 측정되지 않는 경우가 있다. 이 경우에는 아래와 같이 설정해 주면 된다.  

```xhtml
<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>ymyoo</groupId>
    <artifactId>article-module-root</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modules>
        <module>...</module>
        <module>...</module>
        <module>...</module>
    </modules>
    <packaging>pom</packaging>
 
    <properties>
        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
        <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
        <sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
        <sonar.language>java</sonar.language>
    </properties>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <configuration>
                    <destFile>${sonar.jacoco.reportPath}</destFile>
                    <append>true</append>
                </configuration>
                <executions>
                    <execution>
                        <id>agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
```

# 주석

\[1\] [5 개 가치(Value)](http://www.extremeprogramming.org/values.html?ref=popit.kr)는 단순성(Simplicity), 의사소통(Communication), 피드백(Feedback), 존중(Respect), 용기(Courage)이다.

\[2\] [https://en.wikipedia.org/wiki/List\_of\_tools\_for\_static\_code\_analysis](https://en.wikipedia.org/wiki/List%5Fof%5Ftools%5Ffor%5Fstatic%5Fcode%5Fanalysis?ref=popit.kr)

\[3\] 일반적으로 Sonar 라고 하면 음향탐지장비로 알려져 있다.([https://ko.wikipedia.org/wiki/%EC%86%8C%EB%82%98](https://ko.wikipedia.org/wiki/%EC%86%8C%EB%82%98?ref=popit.kr))

\[4\] [https://en.wikipedia.org/wiki/SonarQube](https://en.wikipedia.org/wiki/SonarQube?ref=popit.kr)

# 참고 자료

- [https://abstracta.us/blog/software-testing/code-analysis-part-2-analyzing-code-with-sonarqube/](https://abstracta.us/blog/software-testing/code-analysis-part-2-analyzing-code-with-sonarqube/?ref=popit.kr)
- [https://abstracta.us/blog/software-testing/sonarqube-alternatives/](https://abstracta.us/blog/software-testing/sonarqube-alternatives/?ref=popit.kr)
- [https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Maven](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Maven?ref=popit.kr)