윈도우에서 그레들을 실행해본 적이 없어서(;;) 몰랐던 문제가 이번에 발생을 했다. 인코딩 문제…
다양한 개발환경을 가진 팀이 개발을 할떄도 신경써야 하는 부분이기도 하다. 이클립스의 파일 인코딩을
‘UTF-8’로 바꿨을 때도 이와 유사한 상황이 벌어지지 않을까 하는 생각이 들지만… 그건 그때 가서
살펴보도록 한다.

그레들이 실행될 때, 운영체제의 시스템설정들이 그대로 적용된다. 유닉스나 리눅스에서는 UTF-8로 인코딩이
유지가 되니까 별 무리가 없지만, 윈도우는 MS949 인코딩 처리가 되기에 문제가 발생했다.

발생한 문제는 다음과 같다.

발생문제

클래스 컴파일 시 한글주석을 넣은 클래스들에서 아래의 메시지를 뿌리며 컴파일이 진행되지 않았다.

  • error: unmappable character for encoding MS949
  • error: unclosed string literal

아무런 옵션없이 gradle을 실행하면 다음과 같이 encoding 관련한 오류가 발생을 한다.

C:\Users\ihoneymon\workspace\rocking-the-rest-api\src\main\java\kr\pe\ihoney\jco
\restapi\web\support\converter\AbstractEntityConverter.java:16: error: unmappabl
e character for encoding MS949
 * JPA Entity ?대옒??蹂?솚???꾪븳 異붿긽?대옒??
                      ^
C:\Users\ihoneymon\workspace\rocking-the-rest-api\src\main\java\kr\pe\ihoney\jco
\restapi\web\support\converter\AbstractEntityConverter.java:16: error: unmappabl
e character for encoding MS949
 * JPA Entity ?대옒??蹂?솚???꾪븳 異붿긽?대옒??
                       ^
C:\Users\ihoneymon\workspace\rocking-the-rest-api\src\main\java\kr\pe\ihoney\jco
\restapi\web\support\converter\AbstractEntityConverter.java:16: error: unmappabl
e character for encoding MS949
 * JPA Entity ?대옒??蹂?솚???꾪븳 異붿긽?대옒??
                        ^
C:\Users\ihoneymon\workspace\rocking-the-rest-api\src\main\java\kr\pe\ihoney\jco
\restapi\service\impl\CommunityServiceImpl.java:39: error: unclosed string liter
al
        Member manager = memberService.save(new Member(community.getName() + "
愿?━??, community, community.getCreatedBy()));
                                                                             ^
C:\Users\ihoneymon\workspace\rocking-the-rest-api\src\main\java\kr\pe\ihoney\jco
\restapi\service\impl\CommunityServiceImpl.java:39: error: ')' expected
        Member manager = memberService.save(new Member(community.getName() + "
愿?━??, community, community.getCreatedBy()));

                                            ^
2 errors
:generateQueryDSL FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':generateQueryDSL'.
> Compilation failed; see the compiler error output for details.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug
option to get more log output.

BUILD FAILED

Total time: 6.63 secs

ihoneymon@IHONEYMON-VIRPC ~/workspace/rocking-the-rest-api (master)
$


윈도우에서는 기본적으로 MS949 을 사용하고 있는데, UTF-8로 작성한 소스코드를 가져와 컴파일하면 위와 같은 문제가 발생한다.

해결방법

gradle을 실행할 때 기본적으로 줄 수 있는 옵션에 file.encoding 을 추가하는 것이다. 윈도우 시스템설정-환경변수에서

GRADLE_OPTS=-Dfile.encoding=UTF-8

을 추가하면 된다.

환경변수 설정을 하고 배쉬나 커맨드라인을 닫고 재실행하여 진행하면 적용된다.

이클립스eclipse의 Gradle 플러그인이 제대로 정리가 된 듯 싶다. 정말 오랜만에 Eclipse를 가지고 코딩을 해볼 생각으로 그레들 플러그인을 설치하려고 이클립스 마켓플레이스에서 그레들을 검색해보니 떡하니 Gradle IDE Pack을 제공하고 있다. 메이븐보다는 그레들을 이용한 빌드/배포를 해보고 싶은 욕심을 품는다.

이클립스는 참 좋은 도구다.




그레들gradle(http://www.gradle.org/)에 대해서 발표했던 것이 작년이었다. 그 후 그레들은 마구마구 버전업을 하더니 2.1 버전이 나오는 상황에 이르렀다. 그러나 여전히 국내에는 그레들보다는 메이븐이 강세를 이루고 있고 그레들에 관련된 글도 많이 부족한 상황이다. 그레들이 가지고 있는 강점들이 우리나라에서는 쉽게 부각되지 못하고 있는 점이 참 아쉽다.


그레들에 대한 관심을 키워가면서 그레들에 대한 내용들을 정리해보고자 한다.

위키로 해야할지 어떻게 해야할지 고민중이지만...ㅎ 고민은 적게하고 빨리 진행해야지.



메이븐을 활용하고 있는 자바프로젝트들이라면 그레들로 이동하는 것이 쉽지 않을까? 몇몇 특수한 상황에서 문제들이 생긴다고 하지만, 그 외의 대부분의 경우는 별 문제가 없지 않을까? 그런 생각을 잠시 해본다.

Gradle에서 참조표현(Reference expression, ${variable}) 사용하기

요즘 이해력이 많이 딸린다. 하아.
역시 책과 레퍼런스를 살펴보는 것이 제일 좋군.

groovy를 기반으로 작성되는 대부분의 문자열은 작은 따옴표(‘’)를 사용한다. 이 문자열은 GString을 사용할 수 없다.

이 내용이 나의 삽질을 야기시켰다.

ext {
    versions = [
      springframework: '4.0.3.RELEASE'
    ]
}

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.5'
    compile 'org.springframework:spring-core:${versions.springframework}'
    testCompile 'junit:junit:4.11'
}

위의 내용으로 작성하면 어떻게 될까?

$ gradle dependencies

문제가 생긴다. ㅡ_-)> 화면에서 보는 것처럼, 내가 생각했던 것과는 다르게 ${versions.springframework}에 ‘4.0.3.RELEASE’가 주입되지 않는다. 그냥 문자열 그대로 나온다.

왜 그런거냐!!!

라고 분노하며 내팽개쳤다가 최근에 다시 꺼내어 살펴보았다. 이제는 마음의 여유가 있는지라 왜 그런지 경우를 하나하나 살펴봤다.

사실, 참고서적과 API를 봤다면 수월하게 이해하고 넘어갔을 텐데… 지금까지도 남아있는 일단 실행해보고 보자.

라는 안일함이 나의 시간을 허비 시켰다. 허어…

Groovy and GString 을 살펴보면 GString이라고 하는 항목을 볼 수 있다. 이 GString이 적용되는 것은 큰 따옴표(“”)에 사용했을 때다.

하아… 바보다.

ext {
    versions = [
      springframework: '4.0.3.RELEASE'
    ]
}

dependencies {
    compile 'org.slf4j:slf4j-api:1.7.5'
    compile "org.springframework:spring-core:${versions.springframework}"
    testCompile 'junit:junit:4.11'
}


잊지말자!

참조표현(${})를 사용하기 위해서는 큰 따옴표(“”)를 이용해서 문자열을 선언해야 GString으로 인식되어 처리한다는 것을!!



2014/02/26 - [Java/Tools] - [Gradle] gradle init --type java-library

이전 포스팅에서 설명했던 그레들을 이용해서 자바프로젝트를 초기화해보자.

gradle init --type java-library

실행결과는 다음과 같다

.
├── README.md
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   └── java
    │       └── Library.java
    └── test
        └── java
            └── LibraryTest.java

7 directories, 9 files
  • gradle-wrapper.jar: 운영체제에 그레들이 설치되어 있지 않아도 JDK가 설치되어 있다면 래퍼를 통해서 실행이 가능하다.
  • gradlewgradlew.bat: 운영체제에서 실행가능한 스크립트로 리눅스, 유닉스 계열은 gradlew, 윈도우는gradlew.bat를 실행하면 된다. 그레들 래퍼를 사용할 때 필요한 그레들과 자바에 대한 환경설정을 할 수 있으며, 이는 개발팀 공통 적용이 가능해진다. 파일을 열어보면 위에 보이는 gradle-wrapper.jar을 classpath로 지정하여 실행된다는 것을 확인할 수 있다.

    즉, 운영체제에 설치된 그레들이 아니라, 현재 프로젝트 내에 있는 gradle-wrapper를 중심으로 그레들 실행이 된다는 이야기다.

  • build.gradle: 메이븐의 pom.xml과 같은 기능을 하는 빌드스크립트이며, 그루비groovy를 DSL로 채용하여 그루비의 문법을 사용한 동적인 빌드 스크립트를 작성하고, 의존성dependency 설정이 가능하다는 장점을 제공한다.
  • settings.gradle: 프로젝트 설정 및 멀티프로젝트에 대한 설정을 할 수 있다.
    • 참고: Settings

      build.gradle과 settings.gradle이 프로젝트 루트경로(/)에 존재하는 경우에는 그레들을 이용한 프로젝트 초기화가 적용되지 않는다.

이제 build.gradle에 있는 apply plugin: 'java'를 살펴보도록 하자.

apply plugin: 'java': 그레들 자바 플러그인 사용 선언

build.gradle 상단 부분을 보면 다음과 같은 항목을 볼 수 있을 것이다.

// Apply the java plugin to add support for Java
apply plugin: 'java'

주석으로 알 수 있듯이 java를 사용하기 위한 java plugin을 사용한다는 것을 선언한 것이다.

그레들은 플러그인을 추가하면, 그 플러그인에 선언되어 있는 태스크task들도 추가된다. 추가된 태스크를 확인하는 방법은 다음과 같다.

gradle tasks

자바 플러그인을 설치하고 나면 Build tasks가 추가된다.

ihoneymon@gradle-starter (master)$ gradle tasks
:tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles classes 'main'.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles classes 'test'.

Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Help tasks
----------
dependencies - Displays all dependencies declared in root project 'gradle-starter'.
dependencyInsight - Displays the insight into a specific dependency in root project 'gradle-starter'.
help - Displays a help message
projects - Displays the sub-projects of root project 'gradle-starter'.
properties - Displays the properties of root project 'gradle-starter'.
tasks - Displays the tasks runnable from root project 'gradle-starter'.

Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.

Rules
-----
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
Pattern: clean<TaskName>: Cleans the output files of a task.

To see all tasks and more detail, run with --all.

BUILD SUCCESSFUL

Total time: 3.875 secs

메이븐을 접해본 사람이라면, ‘메이븐의 build lifecycle과 유사한 것 같은데?’라고 생각할수도 있다.

간단하게 test 태스크를 실행해보자.

./gradlew test

별다른 변화는 없다. 그냥 보면 심심하니까 테스트를 실패해보자. 소스코드를 다음과 같이 수정하고


테스트를 실행하면 다음과 같이 AssertionError 가 발생했다는 메시지와 함께 테스트가 실패한 곳을 표시한다.


이렇게 간단하게 gradle의 java 플러그인을 살펴봤다. 다음에는 간단하게 태스크를 작성하고 실행해보도록 하겠다. 그레들 플러그인을 설치하여 추가되는 태스크 외에도 사용자가 태스크 스크립트를 작성하여 실행할 수 있으며, 빌드에 지정한 태스크를 실행되도록 할 수도 있다.

참고사항


+ Recent posts