Maven Project에 SonarQube 적용

Violet_Evgadn·2023년 4월 25일
0

CI&CD 자동화

목록 보기
26/28

1. Maven Project에 Plugin 추가

pom.xml의 태그 사이에 Sonarqube에 대한 Dependency를 추가해줘야 한다.

<dependency>
    <groupId>org.sonarsource.scanner.maven</groupId>
    <artifactId>sonar-maven-plugin</artifactId>
    <version>3.5.0.1254</version>
</dependency>

Plugin의 version은 https://mvnrepository.com/artifact/org.sonarsource.scanner.maven/sonar-maven-plugin 사이트에서 원하는 버전을 활용하자. 필자는 최신 버전을 활용하겠다.

2. SonarQube token 생성

My Account > Security > User Token Section에서 SonarQube token을 생성할 수 있다.

위 창까지 접속했다면 Generate Tokens 부분에 Name, Type, Expires in을 선택한 후 Generate 버튼을 클릭한다.

  • Name : SonarQube Token 이름
  • Type : User Token 선택
  • Expires in : Token 유효 기간

버튼을 클릭하여 만들어진 Token은 이후 재확인할 수 없기 때문에 꼭 발급된 Token 값을 잘 기억해두도록 하자.

3. SSH Server 접근 & Maven 설치

Maven Project를 SonarQube를 통해 정적 분석을 하고 싶다면 먼저 maven 실행이 가능해야 한다.

따라서 maven 패키지가 Server 상에 설치되어 있어야 한다.

yum install maven

이후 mvn --version을 입력하였 때 아래와 같이 버전 정보가 나온다면 설치가 성공한 것이다.

4. Maven Project를 SSH Server에 클론

git clone https://github.com/idj7183/CI-CD-project.git

이전에 사용했던 CI-CD-project를 Clone 하겠다.

5. Maven에서 SonarQube를 통해 Build

mvn sonar:sonar -Dsonar.host.url=http://[실행 환경 IP]:9000 -Dsonar.login=[the-sonar-token]

주의해야 할 점은 -Dsnoar.host.url에 "실행 환경의 IP 주소"를 입력해야 한다는 점이다.

우리는 SonarQube Server에 접속하여 정적 분석을 수행해야 한다. 그런데 우리는 SonarQube Server에 어떻게 접속하는지 고민해볼 필요가 있다.

"localhost:9000"이라는 의미는 내 컴퓨터의 IP 주소에서 9000 Port Number를 통해 SonarQube Server에 접속할 수 있다는 의미이다. 즉, Maven Project 입장에서 "어떤 IP 주소의 9000 Port를 통해 SonarQube Server에 접속 가능한가"가 중요해진다.

만약 Maven Project가 실행 환경에 존재한다면 localhost로도 접속 가능하겠으나 만약 AWS EC2 같은 SSH Server나 Container에서 실행할 경우 "Maven Project 입장에서의 localhost ≠ 실행 환경 IP"이기 때문에 내가 원하는 SonarQube Server에 접속할 수가 없다.

따라서 실행환경 주소 IP를 넣어줘야 하는 것이다.

[the-sonar-token]에는 2번 과정에서 생성 후 복사했던 Token 값을 대입하면 된다.

6. "localhost:9000"에 접속하여 분석 결과 확인

성공!


SonarQube 사용 시 발생할 수 있는 문제들

MissingProjectException

이 문제는 조금 어이없는 실수로 생겼는데 생각보다 많이 발생시켰던 에러여서 한 번 정리하고 넘어가도록 하자.

SonarQube는 "명령어를 입력하는 현재 Directory"의 작업물에 대해 정적 분석을 수행한다. 즉, 현재 Directory에 pom.xml이 존재해야지만 SonarQube를 통한 정적 분석이 가능해진다는 것이다.

만약 pom.xml이 없는 Directory에서 SonarQube Build 명령을 내릴 경우 빌드를 수행하지 못해 SonarQube에서도 정적 분석이 실패하는 문제가 발생할 수 있다.

PluginContainerException

org/sonar/batch/bootstrapper/EnvironmentInformation has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

위 에러 문구 중 가장 중요한 문구는 바로 이 부분이다.

직역을 해보자면 현재 Java Runtime Version이 52.0까지밖에 인식하지 못하는데 SonarQube에서는 55.0 Version의 Class file이 필요하므로 컴파일을 수행하지 못한다는 의미이다.

여기에서 55 = Java 11, 52 = Java 8이다.

즉, 모든 걸 고려해봤을 때 SonarQube는 Java 11 이상 버전으로 Compile 가능하지만 실제 내가 사용하는 Java Version은 8이므로 컴파일이 불가능해진다는 의미이다.

그렇다면 실제 Server의 Java version이 8인지 확인해보자.

이제 문제의 원인을 찾았으니 해결은 쉽다. SonarQube를 실행할 때만 Java 8을 11 버전으로 Upgrade 시킨 뒤 SonarQube 수행이 끝나면 다시 8로 원상복구 시키면 되는 것이다.

Parameter나 pom.xml 변경 등을 통해 이 과정을 조금 더 간략화시킬 수 없을까 많이 고민해봤으나 결국 방법이 보이지 않아 그냥 Java Version을 11로 아예 바꿔 실습을 진행했다.

Pipeline에서는 "tools" 구문을 통해 jdk 설정을 쉽게 해 줄 수 있으므로 서버에 어떤 jdk 버전을 활용하는지 몰라도 SonarQube를 정상적으로 수행시킬 수 있다.


정적 분석 수행해보기

SonarQube 빌드 과정에 대해서는 배웠으니 실제로 코드 상 문제를 발생시켜 정적 분석을 잘 수행하는지 알아보자.

1. Controller 문제 발생시키기

private final Logger logger = LoggerFactory.getLogger(WelcomeController.class);

@GetMapping("/")
public String index(Model model) {
    // logger.debug("Hello World");

    System.out.println("Hello World");

    return "index";
}

여기에서 발생할 수 있는 문제 코드는 2가지이다.

먼저 logger를 선언해놨음에도 불구하고 사용하지 않은 Code Smell이 발생하였다.

두 번째로 Logger 대신 sysout을 활용했다. sysout을 활용하면 코드 상에 문제점은 존재하지 않으나 Logger와는 달리 I/O에 대한 리소스를 계속해서 활용하기 때문에 리소스 낭비로 인한 성능 저하 문제를 발생시킬 수 있다. 따라서 Log에 대해선 sysout보다는 Logger를 활용한다.

2. SonarQube를 통해 빌드시키기

mvn sonar:sonar -Dsonar.host.url=http://[실행 환경 IP]:9000 -Dsonar.login=[the-sonar-token]

이전에 빌드했을 때와 완전히 같은 명령이다.

이젠 localhost:9000으로 접속하여 빌드 결과를 살펴보자.

3. 빌드된 프로젝트 문제점 찾기

Failed 된 프로젝트를 선택하면 위와 같은 창이 뜬다. SonarQube는 이 코드가 3개의 Code Smell이 존재하고 있다고 판단했다.

그렇다면 어떤 부분에서 Code Smell이 발생하였는지 알아보기 위해 왼쪽의 On New Code의 빨간 네모 칸을 클릭해보자.

Logger라는 Field를 선언하고서도 사용하지 않았으니 삭제해달란 요청과 sysout에 대한 경고문, 그리고 주석을 제거해달라는 요청이다.

각각의 Section을 클릭하면 어떤 파일, 어떤 부분에서 코드 상 문제점이 발생했으며 이를 어떻게 처리하면 좋을지 알려준다.

profile
혹시 틀린 내용이 있다면 언제든 말씀해주세요!

0개의 댓글