Java 프로젝트를 초기 구성하기 위해서 IntelliJ에서 제공하는 새 프로젝트를 활용한다. 하지만 많은 템플릿 중에서도 개인적으로 Gradle을 기반으로 Checkstyle, PMD, Findbugs를 함께 구성해서 사용한다.

  • 코딩 스타일 통일
  • 정적 분석으로 빨리 문제점 인지하기

이 두가지 목적을 위해서 플러그인을 함께 사용한다. 그리고 Gradle or Maven은 특별히 구분하지 않지만 다양한 시도가 가능한 Gradle을 조금 더 좋아한다. 하지만 아직도 Groovy 문법은 어색하고 모르겠다.

프로젝트를 시작할 때 가장 중요한 것은 코딩 스타일을 모두 맞추는 것이라고 생각한다. 코딩 스타일은 단순히 체크스타일도 있지만 설계에 관련된 개념도 함께 포함된다고 생각한다. 클래스는 Immutable 하게 생성한다를 위해

  • '생성자에서만 파라미터를 받아서 설정한다' 라던지
  • '변하지 않는 변수에는 모두 final을 붙인다' 라던지

이런 식의 코딩 스타일의 통일이 가장 중요하다고 생각한다. 그래서 그러한 기반이 되는 최소한의 툴로 Checkstyle, PMD, Findbugs을 활용한다.

Gradle Java 프로젝트

Gradle 기반으로 프로젝트를 구성하면 다음과 같은 파일 구조를 가진다.

Java_Project_Strcture

build.gradle, settings.gradle 두 개의 파일이 있다. 외부 라이브러리에 대한 의존성을 Maven Repository 등을 이용해서 배포파일을 기반으로 관리하면 문제가 없지만 사내에서 개발할 때는 Core 모듈 등을 코드레벨로 사용하는 경우도 있다. 혹은 한 프로젝트 내에서 모듈을 분리하는 경우에 Gradle의 settings.gradle이 유용하다.

위에 구조에서 gradle, src 등의 구조는 익숙한데 config는 처음 볼 수 있는데 이는 checkstyle을 위한 디렉토리이다. Gradle Checkstyle Plugin을 참고하면 config/checkstyle/checkstyle.xml의 경로에 checktyle을 설정하라고 표시한다.

정적 분석

checkstyle

Checkstyle은 코딩 스타일 규칙을 정의하여 체크해준다. IntelliJ IDEA 플러그인도 있어서 쉽게 코딩 스타일 오류를 찾고 수정할 수 있다. Checkstyle을 처음 사용할 때 가장 좋은 것은 많은 사람들이 사용하는 스타일 규칙이다. Java는 Google Checkstyle이 좋다고 생각한다.

개인적으로 Google Checkstyle에서 마음에 안 드는 2가지를 수정해서 사용한다.

  1. Indent: 2 -> 4 spaces
  2. Import Order: THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC

Indent는 C# 및 golang을 사용하며 4칸 공백이 명확하게 구분이 잘 되서 선호한다. 그리고 Java 개발 시 IntelliJ IDEA를 사용하는데 Google Checkstyle Import 구문 순서와 차이가 있어서 IntelliJ IDEA 스타일이 더 마음에 들어서 THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC을 적용해서 사용한다.

수정한 부분만 표시하면 다음과 같다.

// Indent
<module name="Indentation">
    <property name="basicOffset" value="4"/>
    <property name="braceAdjustment" value="0"/>
    <property name="caseIndent" value="4"/>
    <property name="throwsIndent" value="8"/>
    <property name="lineWrappingIndentation" value="8"/>
    <property name="arrayInitIndent" value="4"/>
</module>

...

// Import Order
<module name="CustomImportOrder">
    <property name="sortImportsInGroupAlphabetically" value="true"/>
    <property name="separateLineBetweenGroups" value="true"/>
    <property name="customImportOrderRules" value="THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC"/>
</module>

Google Checkstyle도 계속 업데이트 되기 때문에 참고하여 자신에게 적합한 스타일로 바꿔 사용하면 좋다.

pmd

PMD는 코드 분석을 제공하는 도구이다. 문법적으로 오류 가능성이 높은 항목들을 Rule 기반으로 체크해서 알려준다.

.../src/main/java/net/sourceforge/pmd/RuleSet.java:123  These nested if statements could be combined
.../src/main/java/net/sourceforge/pmd/RuleSet.java:231  Useless parentheses.

이러한 문법적으로 발생 가능한 오류를 체크해주기 때문에 개발자에게 한 번 더 자신이 작성한 코드의 위험성을 인지하게 해준다.

findbugs

FindBugs는 정적 분석을 제공하는 도구이다.

FindBugs (1.2.1-dev-20070506) Analysis for jdk1.7.0-b12

Scaffolding 이란, 참 편하긴 한데... Java는 어수선?

웹 프론트엔드 개발을 위해서 react.js, vue.js 등을 공부하면서 Scaffolding 이란 개념을 처음 알게되었다. 물론 Spring도 많은 starter를 제공하여 scaffolding을 제공하고 있다.

Scaffolding이란 일반적인, 혹은 특정한 기술들을 묶어서 사용하기 쉽게 제공해주는 기본 틀과 같은 개념이다. 이런 Scaffolding을 기반으로 프로젝트를 수행하면 처음 프로젝트를 사용하는 구성원이 쉽게 프로젝트에 적응 가능하다는 점이다. Scaffolding이 제공된다는 의미는 일반적으로 사람들이 많이 사용(혹은 협의된) 구조이기 때문에 통용되는 구조라고 생각된다.

물론 다양한 Scaffolding 이 존재하기 때문에 그 중에서 회사, 프로젝트에 가장 적합한 Scaffolding을 찾는 것은 프로그래머 혹은 아키텍트의 역할이라고 생각된다.

아직 자바를 접한지 3년밖에 안되는 뉴비라 아직까지는 좋은 구조를 찾고 있다. 왜 Java는 Scaffolding이 거의 없을까? 그런면에서 Frontend 쪽 생태계는 대단하다는 생각이 든다. Vue, React 등 대부분 이름있는 프레임워크는 다양한 Scaffolding이 지원되는 것이 부럽다.

Java에도 이런 Scaffolding이 많이 생겨나서 참고할 수 있는 구조가 많아지면 좋겠다.