Outsider's Dev Story: JAVA/Tools 카테고리 글 목록https://blog.outsider.ne.kr/Stay Hungry. Stay Foolish. Don't Be Satisfied.2024-03-15T13:16:33+09:00Textcube 1.10.7 : Tempo primoIntelliJ 12.0.x gradle 플러그인의 i18n.GradleBundle locale 오류Outsiderhttps://blog.outsider.ne.kr/9152013-03-07T02:09:29+09:002013-03-07T02:09:29+09:00<a href="http://www.gradle.org/" target="_blank">Gradle</a>로 구성된 프로젝트를 <a href="http://www.jetbrains.com/idea/" target="_blank">IntelliJ</a>에서 임포트하던 중 오류가 발생했다. 정확한 원인은 알 수 없지만 나한테만 발생하는 것으로 보아 특성 환경에 기인한 플러그인의 버그라고 생각된다.(Gradle 플러그인은 내장되어있다.)<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1375847206.gif" alt="Import 도중 No project file is defined 오류" height="290" width="550" /></div><br>Gradle 프로젝트를 임포트하려고 하자 <font color="#CC9900">"No project file is defined"</font>라고 나오면서 임포트가 진행이 되지 않는다. 검색을 해보니 이미 <a href="http://youtrack.jetbrains.com/issue/IDEA-96239" target="_blank">IntelliJ에 보고된 이슈</a>이고 난 OSX였지만 윈도우에서도 동일한 오류가 발생하는 듯하다. (윈도우에서도 해결책이 같은지 모르지만) Gradle project의 경로 앞에 <font color="#FF7635">file://</font>를 붙혀주면 된다. 즉, 위에서 <font color="#FF7635">/Users/projects/build.gradle</font>를 <font color="#FF7635">file://Users/projects/build.gradle</font>로 바꾸어주면 이 오류를 피할 수 있다. <br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1164345463.gif" alt="Import 도중 Locale 관련 오류가 발생한 화면 " height="162" width="400" /></div><br>문제를 해결한 줄 알았더니 Next를 누르자 위와 같이 <font color="#CC9900">"Can't find bundle for base name i18n.GradleBundle, locale ko_KR"</font>가 발생한다. Gradle 플러그인에서 로케일 파일을 로드하지 못한 것인데 ko_KR이 맞기는 한데 Gradle 플러그인에 ko_KR용 로케일 프로퍼티가 존재하지 않는것도 맞다. 정확한 이유는 모르지만 <a href="http://stackoverflow.com/questions/12025635/how-can-i-change-the-locale-used-by-intellij-idea" target="_blank">검색결과 </a>Gradle 플러그인이 IntelliJ의 로케일 설정을 제대로 불러오지 못하는 버그로 발생하는 것으로 보인다.(그래도 어떻게 불러와서 저런 문제가 생기는지는 모르겠다.) 어쨌든 이 이슈 또한 <a href="http://youtrack.jetbrains.com/issue/IDEA-100671" target="_blank">IntelliJ에 보고된 이슈</a>이다.(IntelliJ 12.1에서 수정된다고 한다.)<br><br>이런 저런 해결책(?)들이 오가긴 하지만 사실 아무것도 통하지 않고 Gradle 플러그인을 현재 개발중인 버전으로 교체해야 한다. 교체방법은 <a href="http://confluence.jetbrains.com/display/IDEADEV/Gradle+integration#Gradleintegration-Preassembledset%28applicablefortheIJv.12%29" target="_blank">IntelliJ 위키</a>에 나와 있다. 간단히 설명하면<br><br><ul><li><font color="#FF7635">$IDE_INSTALLATION_DIR/plugins/gradle/lib</font> 아래 있는 파일을 백업해 준다.(혹시 모르니...) jar 파일이 2개정도 있다.</li><li>위키에 있는 <font color="#FF7635">gradle-libs.zip</font> 파일을 다운받아서 압축을 푼다음 jar파일을 모두 해당 위치에 복사한다.(jar 파일이 한 10개쯤 되는데 별도로 배포되는 플러그인이라서 그런것 같다.)</li><li>IntelliJ를 재시작한다.</li></ul><br>위의 두 이슈 모두 개발중인 버전에서는 문제없이 프로젝트를 임포트할 수 있다.(IntelliJ 12.1이 언제 나올지는 모르지만...)<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1066353729.gif" alt="개발버전의 새로운 Gradle 플러그인 임포트 화면 " height="248" width="400" /></div><br>참고로 임포트 화면도 위와같이 변경이 되었다.(이 버그때문에 내 반나절이 날라갔다. ㅠㅠ)<br><p><strong><a href="https://blog.outsider.ne.kr/915?commentInput=true#entry915WriteComment">댓글 쓰기</a></strong></p>JRebel에서 핫스왑할 대상 폴더 지정하기Outsiderhttps://blog.outsider.ne.kr/8342012-09-07T01:25:50+09:002012-09-07T01:25:50+09:00사람마다 호불호가 좀 갈리기는 하지만 나는 익숙해져서 이젠 <a href="http://zeroturnaround.com/software/jrebel/" target="_blank">JRebel</a>없이는 자바로 웹개발하기 힘든정도가 되었다. 한창 잘 쓰고 있었는데 언젠가부터(5.0 업데이트정도 쯤이 아닌가 한데 버전을 일일이 확인하지 않아서.) 톰캣을 띄울때 갑자기 JUnit관련 클래스를 찾을 수가 없다는 오류가 나오기 시작했다. 오류만 엄청 나오고 JUnit을 사용하는 코드는 톰캣에서 실행하는 코드와는 상관없으므로 톰캣을 정상적으로 잘 동작했기 때문에 귀차니즘에 처리를 안하고 미뤄두고 있었다. 하지만 빠르게 출력되는 로그에서 Exception 로그가 찍힐 때마다 본능적인 움찔거림이 발생하는 것은 어쩔수 없기에 신경이 많이 쓰여서 몇일전에 해결을 했다.<br><pre class="line-numbers"><code class="language-java">
10:39:38.121 [Thread-7hread] WARN org.springframework.core.type.classreading.AnnotationAttributesReadingVisitor - Failed to classload type while reading annotation metadata. This is a non-fatal error, but certain annotation metadata may be unavailable.
java.lang.ClassNotFoundException: org.junit.Before
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1676)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)
at org.springframework.core.type.classreading.RecursiveAnnotationAttributesVisitor.visitEnd(AnnotationAttributesReadingVisitor.java:167)
...
</code></pre><br>위와 같은 오류메시지가 출력된다. 이유는 정확히 모르겠지만 테스트 코드쪽의 JUnit 어노테이션들의 클래스를 로딩못해서 발생하는 오류로 보였다. 그래서 검색하다가 핫스왑에 사용할 대상폴더를 <font color="#FF7635">rebel.xml</font>에서 설정할 수 있다는 것을 알게 되었다.<br><pre class="line-numbers"><code class="language-xml">
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">
<classpath>
<dir name="/home/outsider/projects/example/target/classes">
</dir>
<dir name="/home/outsider/projects/example/target/test-classes">
</dir>
</classpath>
<web>
<link target="/">
<dir name="/home/outsider/projects/example/target/m2e-wtp/web-resources">
</dir>
</link>
<link target="/">
<dir name="/home/outsider/projects/example/src/main/webapp">
</dir>
</link>
</web>
</application>
</code></pre><br>JRebel을 써본 사람은 알겠지만 <font color="#FF7635">rebel.xml</font>은 메뉴를 통해서 프로젝트에 생성하기 때문에 사실 한번도 저 파일을 열어본적이 없다. JRebel을 버전업한 것 외에는 초기부터 <font color="#FF7635">rebel.xml</font>을 건드린 적은 없는것 같은데(프로젝트를 재생성하면서 새로 추가했는지도...) 갑자기 왜 테스트 클래스쪽에서 오류가 발생하는지는 모르겠지만 <font color="#FF7635"><dir name="/home/outsider/projects/example/target/test-classes"></font> 부분을 제거하면 더이상 기존의 오류가 발생하지 않는다. 원하는 클래스가 핫스왑이 되지 않거나 불필요한 오류가 나오면 <font color="#FF7635">rebel.xml</font>을 수정하면 되겠다.<br><p><strong><a href="https://blog.outsider.ne.kr/834?commentInput=true#entry834WriteComment">댓글 쓰기</a></strong></p>Eclipse의 리소스 검색 대상에서 제외시키기Outsiderhttps://blog.outsider.ne.kr/7892012-05-25T02:31:55+09:002012-05-25T02:31:55+09:00Eclipse에서 Open Resource(Ctrl + Shift + R)은 코딩 중에 쉽게 여러 파일을 왔다갔다 하는 유용한 기능중 하나입니다. 큰 프로젝트 일수록 프로젝트내에 많은 리소스들이 생성되는데 많은 파일 중 이름이 겹치는 파일이 있거나 하는 경우 리소스를 찾을 때 후보군이 많이 나와서 귀찮게 됩니다. 저 같은 경우는 메이븐의 멀티모듈 프로젝트를 사용하는데 최상위 프로젝트를 내려받고 여기서 서브 프로젝트를 생성했기 때문에 결과적으로는 전체 프로젝트에서 같은 파일이 최상위 프로젝트와 실제 프로젝트 두 곳에 포함되었습니다. 이는 리소스를 찾을 때마다 2개씩 나와서 항상 불편했었는데 이 리소스 대상에서 제외시킬 수 있습니다.<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1070837009.gif" alt="Properties창의 Derived 속성 설정화면 " height="369" width="550" /></div><br>프로젝트의 폴더나 패키지등에서 우측클릭을 하고 Properties 메뉴에 들어가면 Resource부분에 Derived라는 속성을 볼 수 있습니다. 이 속성을 체크하면 해당 리소스는 파생된 리소스로 인식해서 Open Resource의 대상에서 제외되게 됩니다.<br><p><strong><a href="https://blog.outsider.ne.kr/789?commentInput=true#entry789WriteComment">댓글 쓰기</a></strong></p>Java 프로젝트에 Travis CI 적용하기Outsiderhttps://blog.outsider.ne.kr/7822012-05-06T00:52:26+09:002012-05-06T00:52:26+09:00연속에서 <a href="http://travis-ci.org" target="_blank">Travis CI</a> 이야기를 계속 하게되네요. 만지기 시작한 김에 이것저것 해보느라고요. ㅎ 이전 포스팅에서도 얘기했듯이 이전에는 스크립스성 언어만 지원했지만 3월부터 <a href="http://about.travis-ci.org/blog/announcing_support_for_java_scala_and_groovy_on_travis_ci/" target="_blank">Java를 포함한 Scala와 Groovy에 대한 지원이 추가</a>되었습니다.<br><br>마침 <a href="http://www.springsprout.org/" target="_blank">봄싹</a>에서 친분이 있는 개발자 몇명이 <a href="https://github.com/spring-sprout/egov-data" target="_blank">egov-data</a>라는 프로젝트를 시작했습니다. egov-data는 <a href="http://www.springsource.org/spring-data" target="_blank">Spring Data</a>를 <a href="http://www.egovframe.go.kr/" target="_blank">전자정부프레임워크</a>에 적용하는 프로젝트입니다. 저는 iBatis와 Hibernate를 둘 다 안해봤기 때문에 당장 도울것도 없어서 소스는 공부용으로 종종 보기나 해야겠다 생각하다가 이번에 Travis CI를 egov-data에 적용하기로 했습니다. 봄싹은 서버가 있어서 허드슨이나 젠킨스로 CI를 돌릴 수 있긴 하지만 회사도 아닌데 CI서버를 설치하고 관리하는 건 꽤나 쉽지 않아서 Travis CI를 커밋빌드용으로 사용하기로 했습니다.<br><br><br><br><br><font style="font-weight: bold;" size="5">Github의 Service Hooks 설정</font><br>Travis CI를 사용하려면 Sevice Hooks를 켜주어야 하는데 egov-data같은 경우는 제 Github 계정에 포함된 저장소가 아니라 <a href="https://github.com/spring-sprout" target="_blank">SpringSprout</a>라는 봄싹의 Organization용 계정에 포함된 저장소입니다.(Organization은 Github에서 지원하는 사용자들의 그룹을 묶어주는 기능입니다.) 아직 Travis CI에서는 Organization 저장소의 자동연결을 지원하지 않기 때문에 Organization 소유자라고 하더라도 Travis CI에서는 자신의 저장소로 나타나지 않습니다.<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1154857171.gif" alt="egov-data의 Service Hooks 설정" height="402" width="550" /></div><br>그래서 위 화면처럼 <span style="color: rgb(204, 153, 0);">Admin의 Service Hooks에 가서 Travis에 대한 Hooks를 직접 Active로 설정하고 정보를 입력해서 켜주어야 합니다. </span>특정사용자의 정보를 입력하면 되고 Travis CI의 토큰은 Travis CI의 Profile 페이지에서 찾을 수 있습니다. <br><br><br><br><br><font style="font-weight: bold;" size="5">.travis.yml 설정</font><br>자바프로젝트에 Travis CI를 적용하는 부분은 <a href="http://about.travis-ci.org/docs/user/languages/java/" target="_blank">Building a Java project</a>에 잘 나와 있습니다. 이 문서에도 나와있듯이 <span style="color: rgb(204, 153, 0);">OpenJDK 6을 사용하고 기본으로 Maven 3와 Gradle, Ant 1.7을 지원하고 있습니다. 그래서 Gradle 설정파일인 build.gradle없고 프로젝트 루트경로에 <span style="color: rgb(255, 118, 53);">pom.xml</span>이 존재한다면 <span style="color: rgb(255, 118, 53);">mvn test</span>로 테스트를 수행합니다.</span> 그래서 일반적인 Maven 프로젝트라면 다음과 같은 간단한 .travis.yml만 추가하면 Travis CI를 연결할 수 있습니다.<br><pre class="line-numbers"><code class="language-yml">
# .travis.yml
language: java
</code></pre><br>하지만 egov-data는 실제로는 egov-data-ibatis와 egov-data-hibernate라는 2개의 프로젝트가 하나의 저장소로 있는 구조입니다.(스프링 데이터도 이런식으로 종류별로 나누어져 있는데 어찌보면 별도의 프로젝트가 같은 저장소에 있다고 할 수 있습니다.) 그래서 저장소 루트에는 <span style="color: rgb(255, 118, 53);">pom.xml</span>이 없고 각 프로젝트 폴더안에만 각각 <span style="color: rgb(255, 118, 53);">pom.xml</span>이 존재합니다. 각 프로젝트 디렉토리로 이동해서 mvn test를 실행해야 하는데 <span style="color: rgb(255, 118, 53);">.travis.yml</span>에서는 이런 복잡한 명령어를 사용하기가 별로인것 같아서 다음과 같은 Makefile을 만들었습니다.<br><pre class="line-numbers"><code class="language-clike">
test:
cd egov-data-ibatis; \
mvn test
cd egov-data-hibernate; \
mvn test
.PHONY: test
</code></pre><br>처음에는 쉘스크립트를 따로 짰다가 Makefile로 관리하는게 더 일반적이라고 생각해서 위와 같이 작성했습니다. <br><pre class="line-numbers"><code class="language-yml">
# .travis.yml
language: java
script: "make test"
branches:
only:
- master
</code></pre><br>그리고 <span style="color: rgb(204, 153, 0);"><span style="color: rgb(255, 118, 53);">.travis.yml</span>에서 테스트 스크립트가 Makefile을 사용하도록 <span style="color: rgb(255, 118, 53);">make test</span>로 변경하고 master 브랜치에 대해서만 테스트하도록 지정했습니다. </span><br><br><br><br><br><font style="font-weight: bold;" size="5">travis-lint로 .travis.yml 유효성 검사하기</font><br>이전 글들에서는 따로 언급하지 않았었지만 .travis.yml 파일의 <a href="http://lint.travis-ci.org/" target="_blank">유효성을 체크할 수 있는 웹서비스</a>를 제공하고 있습니다. 웹서비스를 이용하는 것이 번거롭다면 다음과 같이 <span style="color: rgb(204, 153, 0);">gem을 이용해서 로컬에 <span style="color: rgb(255, 118, 53);">travis-lint</span>를 설치해서 사용할 수 있습니다.</span><br><pre class="line-numbers"><code class="language-shell">
$ gem install travis-lint
</code></pre><br><span style="color: rgb(204, 153, 0);"><span style="color: rgb(255, 118, 53);">travis-lint</span>를 설치하면 터미털에서 다음과 같이 <span style="color: rgb(255, 118, 53);">.travis.yml</span>의 유효성을 검사할 수 있습니다.</span> 경로없이 명령어만 입력하면 루트 경로의 .travis.yml을 검사하고 그렇지 않다면 경로를 지정해 주어야 합니다.<br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1054374299.gif" alt="터미널에서 travis-lint 사용하는 화면 " height="47" width="550" /></div><br>그 밖에 Travis CI에 대한 내용은 이전에 올린 <a href="http://blog.outsider.ne.kr/781" target="_blank">node.js 프로젝트에 Travis CI 적용하기</a>에서 설명했으므로 따로 언급하지 않습니다.<br><p><strong><a href="https://blog.outsider.ne.kr/782?commentInput=true#entry782WriteComment">댓글 쓰기</a></strong></p>Grep Console : 이클립스 콘솔 이쁘게 보기Outsiderhttps://blog.outsider.ne.kr/7272012-01-11T23:52:57+09:002012-01-11T23:52:57+09:00큰 프로젝트를 개발하다보니 이클립스 콘솔에 출력되는 수많은 로그를 뒤지는 것도 보통 일이 아니었습니다. 개발과정에서는 디버깅을 위해 로그레벨을 높여서 사용하므로 엄청난 양의 로그가 출력되고 그 중에서 필요한 부분을 찾으려면 수없이 스크롤하고 텍스트 검색을 해야했습니다. 더군다나 로그메시지는 자세히 보지 않으면 비슷비슷해 보이기 때문에 집중해서 보지 않으면 찾기도 쉽지 않았습니다. <br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1040003479.gif" alt="이클립스 콘솔에 출력된 로그 메시지" height="292" width="550" /></div><br>다 똑같이 출력되니까 로그 메시지 뒤지는데도 상당한 시간이 소비되었는데 얼마전에 콘솔의 메시지를 종류별로 다양한 색으로 보여주는 플러그인이 있다는 걸 알게되었습니다. <a href="http://logback.qos.ch/" target="_blank">Logback</a>을 쓴다면 사용할 수 있는 <a href="http://logback.qos.ch/consolePlugin.html" target="_blank">Logback Console Plugin for Eclipse</a>도 있었지만 좀더 범용적으로 쓸 수 있는 <a href="http://marian.musgit.com/projects_grepconsole.php" target="_blank">Grep Console</a>을 선택했습니다. 이클립스를 Indigo(3.7)버전을 쓴다면 이클립스 마켓플레이스에서 존재하므로 바로 설치할 수 있습니다.<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1237207894.gif" alt="이클립스 마켓플레이스의 Grep Console" height="281" width="550" /></div><br>이클립스를 3.6이하의 버전을 사용한다면 <span style="color: rgb(204, 153, 0);">[Help] - [Install New Software]</span>에서 <a href="http://eclipse.musgit.com" target="_blank">http://eclipse.musgit.com</a>를 추가하고 설치할 수 있습니다. <br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1232459109.gif" alt="Grep Console이 설치된 콘솔" height="224" width="463" /></div><br>설치가 완료되면 위처럼 콘솔에 우측에 <span style="color: rgb(204, 153, 0);">(?) </span>아이콘이 생성됩니다. 이 아이콘을 클릭하면 다음과 같은 Grep Expression 관리화면이 나타납니다.<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1312901906.gif" alt="Grep Expression 관리화면 " height="348" width="550" /></div><br><span style="color: rgb(204, 153, 0);">Grep Console은 정규표현식을 사용해서 로그메시지를 구분하고 각 규칙마다 원하는 색을 지정할 수 있는 구조로 되어있습니다.</span> 처음에는 아무 규칙도 등록되어 있지 않으므로 Add를 눌러서 규칙을 등록하면 됩니다. 위처럼 정규표현식 규칙을 등록합니다. 정규표현식에서 괄호로 그룹을 3개 만들었으므로 규칙에서 Whole Line과 그룹 3개가 나타납니다. <span style="color: rgb(204, 153, 0);">Whole Line은 정규표현식으로 잡힌 라인전체에 대한 설정이고 그룹별로도 다른 설정을 할 수 있습니다.</span> 기본적인 로그레벨에 대한 구분은 다음 정규식을 이용해서 할 수 있습니다.<br><br><div style="margin-left: 40px;"><span style="color: rgb(255, 118, 53);">(.*)(TRACE)(.*)</span><br style="color: rgb(255, 118, 53);"><span style="color: rgb(255, 118, 53);">(.*)(DEBUG)(.*)</span><br style="color: rgb(255, 118, 53);"><span style="color: rgb(255, 118, 53);">(.*)(ERROR)(.*)</span><br style="color: rgb(255, 118, 53);"><span style="color: rgb(255, 118, 53);">(.*)(FATAL)(.*)</span><br style="color: rgb(255, 118, 53);"><span style="color: rgb(255, 118, 53);">(.*)(INFO)(.*) </span><br></div><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1323754176.gif" alt="콘솔에서 선택한 텍스트로 Grep Console를 추가하는 화면" height="357" width="550" /></div><br>위처럼 로그메시지에서 블락을 설정하고 마우스의 우측클릭을 하면 <span style="color: rgb(204, 153, 0);">Add Grep Expression</span>이라는 메뉴가 나서 현재 선택한 텍스트를 기준으로 바로 정규표현식을 생성할 수 있습니다. 물론 이는 기본적인 정규표현식이므로 세밀한 제어를 하려면 정규표현식을 수정해야 합니다. 위 그림은 하이버네이트에 대한 로그를 따로 구분하기 위해서 설정했습니다.<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1206906385.gif" alt="Grep Console 규칙별로 다르게 표시된 콘솔" height="348" width="550" /></div><br>이제 위처럼 로그가 구분되어 나오기 때문에 쉽게 찾고자 하는 로그를 구분해서 볼 수 있습니다. <span style="color: rgb(204, 153, 0);">Grep Console은 정규표현식을 사용하기 때문에 필요한 만큼 다양하게 설정할 수 있어서 출력로그의 규칙성만 찾으면 자유롭게 등록해서 사용할 수 있습니다.</span><br><p><strong><a href="https://blog.outsider.ne.kr/727?commentInput=true#entry727WriteComment">댓글 쓰기</a></strong></p>