허드슨, 지속적인 통합 도구

프로젝트를 진행할 때 업무 단위별로 팀을 나눠서 개발을 하고 난 뒤 오픈 한 달 전부터 코드를 통합하는 작업을 따로 했던 시기가 있었습니다. 이때 팀 간의 인터페이스가 맞지 않아서 이를 수정해서 맞추는 작업에 굉장히 많은 노력과 시간이 들었습니다.
전체 프로젝트 팀의 소스를 매일 매일 합쳐서 큰 문제가 생기기 전에 매일매일 소스를 빌드하는 방법이 가능해졌습니다. CVS, SVN과 같은 버전관리 시스템을 적용하고, 이 장에서 설명할 허드슨과 같은 지속적인 통합(Continuous Integration) 도구를 사용하면 손쉽게 프로젝트를 관리할 수 있습니다.

허드슨은 http://hudson-ci.org 사이트에서 정보를 얻을 수 있습니다. 오픈소스로 태어났지만 썬을 인수한 오라클과의 운영 이슈로 허드슨의 원 개발자가 자바닷넷(http://java.net)을 떠나 깃허브(https://github.com/jenkins)로 자리를 옮겨서 동일한 제품을 만들었습니다. 젠킨스(Jenkins)이며 http://jenkins-ci.org 사이트를 통해서 공개되고 있습니다. 두 제품의 사용법은 동일합니다.

표준프레임워크 개발환경 서버를 설치하면 톰캣이 설치됩니다. 톰캣의 webapps/ 폴더에 hudson.war 파일이 위치합니다. 톰캣이 실행되면 자동으로 압축이 풀리면서 hudson 사이트가 준비됩니다.

<그림> hudson.war 파일 위치


윈도우7에서는 서비스에 등록된 톰캣을 일반 cmd창에서 실행할 수 없습니다. 권한이 없기 때문이죠. cmd창을 관리자 모드로 실행하고, net start tomcat6 명령으로 실행할 수 있습니다. 만약 실행중이라면 "요청한 서비스가 이미 시작되었습니다."라는 메시지를 보게 될 것입니다.

<그림> 관리자 모드 톰캣 서비스 시작



브라우저를 통해서 http://localhost:7070 페이지로 접속하면 자동을 /hudson 컨텍스트로 이동합니다. 허드슨이 준비가 완료된 화면입니다. 왼쪽 메뉴에서 새 작업을 클릭합니다.

<그림> 허드슨 페이지 접속


새 작업 화면에서는 프로젝트명과 스타일을 정합니다. ok.egov 라고 프로젝트명을 입력합니다. 작업 스타일은 메이븐을 사용하기 때문에, 두 번째 항목인 Build a maven2/3 project 를 선택합니다. ok 버튼을 클릭하면 메이븐 기반의 프로젝트를 다루는 작업이 만들어집니다.



[INFO] [war:war {execution: default-war}]
[INFO] Packaging webapp
[HUDSON] Archiving C:\eGovFrameSvr\hudson\jobs\ok.egov\workspace\pom.xml to C:\eGovFrameSvr\hudson\jobs\ok.egov\modules\ok$egov\builds\2013-07-02_07-12-51\archive\ok\egov\1.0.0\pom.xml
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Cannot construct org.apache.maven.plugin.war.util.WebappStructure as it does not have a no-args constructor
---- Debugging information ----
message             : Cannot construct org.apache.maven.plugin.war.util.WebappStructure as it does not have a no-args constructor
cause-exception     : com.thoughtworks.xstream.converters.reflection.ObjectAccessException
cause-message       : Cannot construct org.apache.maven.plugin.war.util.WebappStructure as it does not have a no-args constructor
class               : org.apache.maven.plugin.war.util.WebappStructure
required-type       : org.apache.maven.plugin.war.util.WebappStructure
path                : /webapp-structure
line number         : 1
-------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Trace
com.thoughtworks.xstream.converters.ConversionException: Cannot construct org.apache.maven.plugin.war.util.WebappStructure as it does not have a no-args constructor
---- Debugging information ----
message             : Cannot construct org.apache.maven.plugin.war.util.WebappStructure as it does not have a no-args constructor
cause-exception     : com.thoughtworks.xstream.converters.reflection.ObjectAccessException
cause-message       : Cannot construct org.apache.maven.plugin.war.util.WebappStructure as it does not have a no-args constructor
class               : org.apache.maven.plugin.war.util.WebappStructure
required-type       : org.apache.maven.plugin.war.util.WebappStructure
path                : /webapp-structure
line number         : 1
-------------------------------
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:63)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:45)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:46)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:117)
	...
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:722)
Caused by: com.thoughtworks.xstream.converters.reflection.ObjectAccessException: Cannot construct org.apache.maven.plugin.war.util.WebappStructure as it does not have a no-args constructor
	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.newInstance(PureJavaReflectionProvider.java:59)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.instantiateNewInstance(AbstractReflectionConverter.java:257)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:124)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:56)
	... 43 more
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Tue Jul 02 07:12:57 KST 2013
[INFO] Final Memory: 20M/49M
[INFO] ------------------------------------------------------------------------
channel stopped
Finished: FAILURE


이 에러 메시지는 maven war plugin 이 Java7을 지원하지 못하기 때문이라고 합니다. jdk1.6으로 내리거나 아래 플러그인을 pom.xml에 추가해야 합니다.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
</plugin>

from: http://stackoverflow.com/questions/7539970/cannot-construct-org-apache-maven-plugin-war-util-webappstructure-as-it-does-not




eGovFrameSvr 서버 2.0.0에는 jdk1.5가 포함되어 있고, hudson의 세팅은 여기에 맞춰져 있습니다. 그래서 jdk1.6이상으로 맞춰진 프로젝트는 컴파일 되지 않는 이슈가 있습니다.


[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 10 source files to C:\eGovFrameSvr\hudson\jobs\ok.egov\workspace\target\classes
[HUDSON] Archiving C:\eGovFrameSvr\hudson\jobs\ok.egov\workspace\pom.xml to C:\eGovFrameSvr\hudson\jobs\ok.egov\modules\ok$egov\builds\2013-07-01_15-22-31\archive\ok\egov\1.0.0\pom.xml
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
Failure executing javac, but could not parse the error:
javac: invalid target release: 1.6
Usage: javac <options> <source files>
where possible options include:
  -g                         Generate all debugging info
  -g:none                    Generate no debugging info
  -g:{lines,vars,source}     Generate only some debugging info
  -nowarn                    Generate no warnings
  -verbose                   Output messages about what the compiler is doing
  -deprecation               Output source locations where deprecated APIs are used
  -classpath <path>          Specify where to find user class files
  -cp <path>                 Specify where to find user class files
  -sourcepath <path>         Specify where to find input source files
  -bootclasspath <path>      Override location of bootstrap class files
  -extdirs <dirs>            Override location of installed extensions
  -endorseddirs <dirs>       Override location of endorsed standards path
  -d <directory>             Specify where to place generated class files
  -encoding <encoding>       Specify character encoding used by source files
  -source <release>          Provide source compatibility with specified release
  -target <release>          Generate class files for specific VM version
  -version                   Version information
  -help                      Print a synopsis of standard options
  -X                         Print a synopsis of nonstandard options
  -J<flag>                   Pass <flag> directly to the runtime system



[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 31 seconds
[INFO] Finished at: Mon Jul 01 15:24:06 KST 2013
[INFO] Final Memory: 17M/31M
[INFO] ------------------------------------------------------------------------
Waiting for Hudson to finish collecting data
channel stopped
Finished: FAILURE


이를 해결하려면 허드슨 관리에서 JDK의 버전을 1.6 이상으로 맞춰 줘야 합니다. 메인 페이지에서 Hudson 관리 > Configure System > JDK 섹션으로 이동합니다.




수정 후에는 이상없이 빌드될 것입니다.



월급받고 오픈소스 개발하는 사람들 아닌가 생각들 정도입니다.
kohsuke님이 메인 개발자인 것으로 알고 있습니다.
Hudson때도 중심이셨죠.

 
오라클이 hudson을 eclipse에 위탁했던 소식에 이어서 Jenkins측에서는 Hudson과의 재결합에 대해서 크게 관심 두지 않는다고 합니다. 오픈소스 역사에서 길이 남을 에피소드 같습니다. 아직 진행중이구요.
https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Hudson+Reconciliation+Requirements
 
1.395.1 버전의 plugin management에서 이런 화면이 나옵니다.

 
씁쓸합니다. 오라클 너무 하는 것 아닌가요.

Update Site도 변했습니다.


 
사이트도 http://jenkins-ci.org/ 와 예전 http://hudson-ci.org/ 입니다.


 
 
http://www.okjsp.pe.kr:8080/ 허드슨을 이용해서 사이트를 관리를 하고 있습니다. SVN에 소스를 커밋하면 1시간마다 또는 즉시 운영에 반영할 수 있는 시스템이고, 1시간마다 테스트케이스를 돌리기 때문에 언제 문제가 발생했는지 모니터링할 수 있는 지속적인 통합(Continuous Integration) 도구입니다.
관련해서 포스팅한 글도 조금 있지요. http://okjsp.tistory.com/tag/hudson

오늘 RSS를 통해서 본 것인데, 충격적이라 포스팅합니다.

허드슨은 http://hudson.dev.java.net 에서 오픈소스로 진화하고 있었는데, 이게 java.net을 떠나서 github로 둥지를 바꿨다고 합니다. http://www.infoq.com/news/2011/01/hudson-jenkins 
위 글에 따르면 oracle 관리 아래 java가 들어간 이후로 java.net의 대대적인 개편이 있었고, 이게 서비스를 마이너스로 만들었다고 합니다. 그래서 Github로 이전했다네요.

예전엔 http://hudson-ci.org/ 와 화면이 같았었습니다.


Oracle had applied for the Hudson trademark on October 29th, when the developers were in progress of moving the code off to GitHub.

from: http://www.infoq.com/news/2011/01/hudson-jenkins 
프로젝트 이름을 바꾸는 이유는 오라클이 Hudson으로 상표를 만들고 있는 것 같습니다. 으악~ 이거 뭐... 영어사전의 모든 단어로 상표권을 만들 기세입니다.

이름을 바꾸지 않고도 잘 해결되었으면 좋겠습니다. 혼동이 가중되지 않도록 말이죠.
개인적인 심정으로는 그냥 IBM이 Sun을 가져갔으면 더 발전적이지 않았을까 생각됩니다.

오라클은 나중에 영화나 미드 시리즈를 만들어도 흥행할 것 같습니다. 드라마를 쓰고 있네요. 파란만장 자바 이야기.

허드슨의 건승을 기원합니다.

2000년 12월 5일 시작한 http://www.okjsp.pe.kr 사이트의 9주년 기념 세미나입니다.(유료입니다)

회비 2만원(현장 납부, 영수증 처리됩니다.)

이클립스와 Hudson을 통한 사이트 개발 노하우를 공유합니다.

1: 이클립스 웹개발
2: Hudson 활용한 프로젝트 관리
3: OKJSP 통계와 2010년 계획

작게 기념하려고 합니다.

 

신청주소:

http://www.onoffmix.com/e/kenu/1238

JUnit을 이용한 테스트케이스를 실행한 결과를 api형태의 보고서로 또는 그래픽으로 비주얼하게 보여줄 수 있습니다.

http://www.okjsp.pe.kr/docs/report 에서 확인할 수 있습니다.

아울러 hudson에서도 다른 형태의 리포트가 나옵니다.
우측 상단의 파란색 그래프입니다.

더 자세한 정보도 볼 수 있습니다.

http://www.okjsp.pe.kr:8080/job/okjsp%20site%20build/

아주 오래 미뤄왔던 일을 해내었습니다. 이제 버그 잡아야겠습니다.
버전이 제법 빠르게 올라갑니다.
https://hudson.dev.java.net


번역하시는 분홍콩의 대학원에서 공부하시는 김성훈(http://sestory.tistory.com/)님으로 알고 있습니다. 적용되니까 한결 나아보입니다.

1.262 버전에서는 job을 죠브라고 번역이 되어 있었습니다.

1.282로 업그레이드 안내표시가 보여서 결행했습니다.

용량차이가 보입니다.

"새 작업" 깔끔해 졌습니다.

김성훈님 수고 정말 감사합니다.

+ Recent posts