허니몬의 IT 이야기

출처 : [한빛미디어] 2006-07-10 10:37

저자: Ed Burnette, 한동훈 역

가리발디: 이것들을 시도해 본 적 있어?
미스 크레이머: 그게 뭔데?
가리발디: 나도 몰라. 번역기에 따르면, 이건 성욕을 일으키는 것이거나 바닥 왁스야. 해볼만한 가치가 있는지는 모르겠어.
- 바빌론 5, "감염"

역주: 여성들에게 성욕을 유발시키는지 테스트 하기 위해 윗입술에 향을 발라주면서 하는 거짓말로 가장 흔한 것이 "새로운 바닥 왁스의 향을 시험하는 것"이라고 하는 데서 기인한 표현인 듯.

이클립스(Eclipse)는 자바 프로그래밍을 위한 인기있는 통합 개발 도구(IDE)이며, 데스크톱이나 서버 응용프로그램을 개발하기 위한 풍부한 기능을 제공하는 클라이언트 플랫폼으로, 다양한 툴들을 통합하는 프레임워크로서 C++이나 루비(Ruby) 같은 다양한 언어들을 위한 개발 환경으로도 사용된다. 이클립스 오픈소스 커뮤니티는 비즈니스 인텔리전스(BI)에서 소셜 네트워킹에 이르기까지 수십개의 프로젝트를 책임지고 있다. 또한, 이클립스는 이들 프로젝트를 관리하는 비영리 단체의 이름이기도 하다.(이게 바닥 왁스가 아니라고 확신하고 있지만, 이클립스 자동차, 축구 팀, 껌의 브랜드이다)

역주: 2006년에 미츠비시에서 새로운 승용차 브랜드, 이클립스를 내놓았다. 이클립스 축구 클럽이 있으며, 물론, 이클립스 껌도 있다.

이클립스 버전 3.2는2006년 6월 30일에 연이어 발표되는 10개의 이클립스 프로젝트의 첫번째에 해당한다. 이 기사는 이클립스 IDE에 중점을 두며, 특히 JDT(Java Development Tools)에 대해 설명한다.

JDT 만들기

JDT의 계보는 1996년 경에 스몰톡(Smalltalk)으로 작성된 비주얼 에이지 포 자바(VAJ)로 거슬러 올라간다. VAJ에서는 입력하는 대로 모든 것이 컴파일되고, 메모리에서 모든 것이 해석된다. 이러한 설계는 긴 코드에 적합하지 못하며, 확장하기 어려우며, 파일 정보를 재생성하는 것이 어려웠다.

1999년에 IDE 팀은 비주얼 에이지 마이크로 에디션(VAME)을 개발하기 시작했다. 모든 게 자바로 작성되었으며, 사용자 인터페이스에는 표준 위짓 툴킷(SWT)를 사용했다. VAME는 임베디드 영역을 위해 설계되었다. VAME는 표준 자바 VM을 사용했고, 파일 시스템에 작업공간(workspace)를 유지했다. 그러나, 파일과 폴더 이름은 읽기 나쁜 UUID로 되어 있었다.

VAME의 점진 컴파일러(incremental compiler)는 VAJ 보다 약 10배 정도 더 빨랐다. 여기서 사용된 모델은 상태 기반으로 구축되었다.(소스 기반으로 되어 있는 이클립스와는 반대다) VAME는 플러그인을 사용해서 확장할 수 있는 Rapier라는 저장소 시스템(repository system)을 갖고 있었다.

VAME는 커뮤니티에서 그리 많은 이목을 끌지 못했지만, 개발자들이 다음 프로젝트 즉, 이클립스에 심어놓을 좋은 아이디어를 많이 갖고 있었다. 2001년에 이클립스 1.0이 발표되었다. 이클립스 1.0은 "안되는 게 없는 IDE"로 소개되었다. 초기부터 이클립스와 JDT는 다른 개발 툴을 위한 플랫폼으로 구축되었다.

작업공간(workspace)는 디스크에 저장되었고, 다른 툴에서 열 수 있다. 이클립스 1.0은 독점적인 작업 공간을 사용하는 대신 CVS와 통합되어 있다.

이클립스는 이전 세대와 중요한 차이점 즉, 오픈소스다. 사용자 커뮤니티는 폭발적으로 증가했으며, 스스로 성장할 수 있게 되었다. 이클립스 3.2에서 새로운 기능이나 향상된 기능들의 대부분은 이클립스 사용자들이 채워넣은 개선들의 직접적인 결과물이다. 3.1이후로 3만개 이상의 수정 사항과 개선 사항들이 있었다. 이를 나열하는 것은 지나치게 길기도 하고, 지루하기도 하므로, 대부분의 자바 개발자들에게 중요한 몇 가지만 중점적으로 살펴보기로 하자.

이클립스 컴파일러

JDT의 가장 강력한 기능은 javac와 완벽하게 호환되는 내장형 점진 자바 컴파일러다. 이클립스에서 Ant와 javac를 사용하게 설정한 경우에도 IDE에서 문제에 대한 표식(problem marker)를 표시할 수 있다.(3.2의 새로운 기능). 이클립스 컴파일러는 보다 나은 소스 분석과 보다 빠른 처리 시간을 제공한다.

JDT 컴파일러는 본래 VAME를 위해 쓰여졌으며, 이클립스를 위해 수정되었다. 이는 개발자들이 로봇공학에 대한 아시모프의 3원칙 이후로 패턴처럼 된 "컴파일의 3원칙"으로 부르는 것을 토대로 구축되었다.

  1. 정확성(Correctness): 컴파일러는 소스 프로그램에 위해를 가하지 않아야 한다
  2. 효율성(Efficiency): 첫번째 법칙을 위배하지 않는 한 컴파일러는 빨라야 한다.
  3. 편의성(Friendliness): 컴파일러는 첫번째와 두번째 법칙을 위배하지 않는 한 사용자가 프로그래밍 오류를 수정하는 것을 도와야 한다.
역주: "로봇", "파운데이션" 같은 장편외에 영화 "바이센테니얼맨"의 원작인 "200살을 맞은 사나이" 등으로 잘 알려진 과학자이자 다작의 문필가였던 아이작 아시모프가 1940년에 만든 로봇 3원칙(The Laws of Robotics)은 이후 로봇 공학자들에게 있어 로봇의 기본 원칙으로 자리 잡았다. 1985년에는 0원칙이 추가된 "수정된 로봇 3원칙"이 발표되었습니다.

로봇 3원칙 (The Laws of Robotics)

제1원칙 (First Law): 로봇은 인간에게 해를 끼쳐서는 안되며, 위험에 처해있는 인간을 방관해서도 안된다.

제2원칙 (Second Law): 제1원칙에 위배되지 않는 경우 로봇은 인간의 명령에 반드시 복종해야만 한다.

제3원칙 (Third Law) : 제1원칙, 제2원칙에 위배되지 않는 경우 로봇은 자기 자신을 보호해야만 한다.

정확성: 자바 컴파일러를 설계할 때는 스펙을 따라야 하며, 스펙의 "정신"도 따라야 한다. 홀로 올바른 것(right alone)이 되어서는 안된다. 따라서, JDT 개발자들은 Sun의 컴파일러를 비롯해서 다른 컴파일러들의 동작 방식과 합의를 이루기 위해 수년간 작업해왔다. 정확성은 이클립스 3.2에서 15,000개 이상의 단위 테스트를 통해 검사되었다.

효율성: 수천개의 프로젝트와 수백만 줄의 코드를 표준으로 하였다. 이와 같은 표준은 수 많은 가정을 내제하고 있는 것이다. 예를 들어, 메모리 사용량은 예측 가능해야하며, 균형을 이뤄야 한다. 이클립스 3.2는 적극적인 최적화를 통해 이를 최대한 다듬어왔다. 예를 들어, 개발자들은 비트 연산을 사용해서 플로우 그래프(flow graph)를 재작성했으며, 전체 시간을 20%에서 4%로 낮췄다.

편의성: 오류 보고는 예술이다. 줄 번호로는 충분하지 않다. 2차 오류는 최소화되었다. 예를 들어, 어떤 파일에서 세미콜론(;)을 잊었다면, 이 파일에 의존하는 다른 파일에 영향을 주지 않는다. 향상된 정적 분석은 오류들의 패턴을 발견한다. 이클립스는 또한 정확성을 위해 Javadoc을 검사한다.

3.2 발표로 이클립스 컴파일러는 Java SE 6.0과 호환이 가능하다. 이클립스는 자바 6 카테고리를 지원하며, 자바6가 발표되지도 않았는데도 StackMapTable 특성을 지원한다. 뿐만 아니라, 컴파일러는 실행해보기도 전에 코드에 있는 문제들을 발견하는 것을 도와주는 새로운 분석 도구들을 갖고 있다. VAJ는 세가지 분석도구를 갖고 있었으며, 3.2 컴파일러는 45가지 분석도구를 갖고 있다. 이들 중에 새로운 것은 탐지와 관련된 것이다.
  1. 명백히 null인 변수의 사용
  2. null에 대한 불필요한 검사
  3. 메서드 매개변수에 우발적인 할당
  4. switch case가 이전 case로 부터 실행되는 경우
  5. 비제네릭 형식 사용
  6. 사용하지 않는 레이블
  7. 불필요한 $NON-NLS$ 태그
이들 대부분은 사용하지 않음이 기본 설정이다. 또, @SuppressWarnings 어노테이션을 사용해서 이런 기능을 사용하지 않을 수 있다.

이클립스 없이 이클립스 컴파일러를 사용하고 싶다면, 3.2에서는 개별 다운로드를 이용하면 된다. 명령줄 매개변수는 javac와 호환되며, 1M 정도만 다운로드하면 된다. 이클립스 컴파일러는 오픈 소스이며, 아파치 톰캣이나 그외 함께 번들된 소프트웨어를 포함한 많은 프로젝트들도 오픈 소스이다.

편집

개발 도구의 가장 기본적인 기능은 편집이다. 대부분의 시간을 편집기에서 보내며, 편집기는 편해야 하며, 불편해서는 안되며, 또한 강력해야 한다. 이맥스에서 소스 언어에 대한 기본적인 지식을 갖고 있으며, 구문 강조 기능을 제공한 이래로 모든 편집기가 갖고 있는 기능을 갖고 있다. JDT는 자바 모델을 사용해서 이 문제를 해결한다. 예를 들어, JDT는 클래스와 인스턴스 변수의 차이점을 알고 있으며, 이들을 다른 색상으로 구별할 수 있다. 호출하는 함수가 폐기된 함수(obsolete 또는 deprecated)이면 소스 코드 코멘트에서 이를 알려줄 수 있으며, 살펴볼 코드 부분을 밑줄과 함께 강조해준다.

자바 편집기의 가장 강력한 기능은 Ctrl + Space(콘텐트 보조)다. 객체의 메서드가 기억나지 않거나, 클래스의 정확한 철자를 모를 때가 있지 않은가? Ctrl + Space를 누르면 이클립스는 현재 위치에서 사용할 수 있는 모든 목록을 제공한다. 예를 들어, "LongJavaName"과 같은 긴 이름을 가진 식별자를 입력한 경우는 없는가? 이제, "LJN"으로 입력하고 Ctrl + Space를 누르면 이클립스는 무것을 의미하는지 알 수 있다. 이를 "낙타표기법 완성(CamelCase completion)"이라 부른다. 이는 Ctrl + Shift + T, 형식 검색에도 동작한다.

"StringBuffer buffer = new StringBuffer();"와 같은 표현들을 입력한 적이 있는가? 이제, 스스로 이를 반복하지 마라. 3.2에서는 대신에 "SB"를 입력하고 Ctrl + Space, Space, Ctrl + Space, " = new", Ctrl + Space, "();"를 입력하면 된다. 16번의 키 입력으로 47번의 키 입력을 대신할 수 있다. 변수 이름에 다른 접두어를 사용하고 싶은가? 문제 없다. 두번째 Ctrl - Space를 누르기 전에 원하는 접두어를 입력하면 된다. 예를 들어, 3.2에서는 "Element root" + Ctrl + Space는 그림1과 같이 "Element rootElement"로 완성된다.

그림1
그림1. 콘텐트 보조(Ctrl + Space)는 3.2에서 더욱 똑똑해졌다. 낙타표기법 완성을 지원하며, 이미 입력한 문자들을 기억한다.

여기, 또 다른 시간 절약이 있다. 3.2에서 Ctrl + Space는 사용 패턴에 기초해서 제안 항목을 동적으로 재배열한다. 예를 들어, 항상 List 변수에 ArrayList 인스턴스를 할당한다면, 재빨리 이 항목을 선택할 수 있도록 ArrayList가 목록의 첫번째에 위치한다. 코드 완성은 JavaDocs에서도 동작하며, 긴 이름들을 기억하지 않아도 @links를 생성하거나 참조할 수 있다.

"이 줄에 문제가 있다는 것을 IDE가 스스로 알만큼 영리하다면 왜 그걸 수정하지 않는 걸까?"라고 질문해본 적은 없는가? 이클립스는 Quick Fix라는 기능이 있다. 문제가 있는 줄에 커서를 옮겨놓고 Ctrl + 1을 누르면 이클립스는 이를 수정하기 위한 제안을 제공한다.

이클립스의 새로운 릴리스는 새로운 Quick Fix를 제공한다. 예를 들어, 3.2에서는 raw 형식을 사용할 때 경고를 받았다면, 해당 줄에 커서를 위치하고 Ctrl + 1을 누르면 "Add type parameters"와 같은 fix가 선택된다. 또한 3.2에서 Quick Fix는 같은 파일에서 많이 발생한 공통된 문제들을 개별적으로 다루지 않고, 한 번에 처리할 수 있다.

추천하고 싶은 한 가지 기능은 "타입 이름 변경(Rename Type)"이다. 여러분이 나와 같은 개발자라면, 변수나 메서드를 타입 이름에 맞게 지어줄 것이다. 예를 들어, Bar 타입을 갖고 있다면, 변수 이름은 fBar, 메서드는 CreateBar처럼 지을 것이다.(그림2) 문제는 Bar를 다른 이름으로 변경할 때, 바꿔야할 것들이 너무나 많다는 점이다. 3.2에서는 변경하려는 타입과 유사한 이름을 가진 변수, 메서드 변경 기능을 제공한다. 이 기능은 3.2에서 내가 좋아하는 기능이다.

그림2
그림2. 이클립스 3.2는 타입 이름을 변경할 때, 비슷한 이름을 가진 변수 및 메서드 이름 변경을 제공한다.

실행

일부 IDE에서는 "주 프로젝트(main project)"를 하나 설정해야 하며, 프로그램을 실행하기 위해 실행 명령(Run command)를 사용한다. 이클립스는 이런식으로 동작하지 않는다. 이클립스에서는 명령줄 매개변수, 클래스 경로, JRE 버전과 같이 코드를 디버깅하거나 테스트하거나, 실행하는 데 필요한 모든 세부 사항들을 저장한 "시작 설정파일(Launch configurations)"들의 목록을 갖고 있다. 이클립스 3.2에서는 필터링 사용과 실행 환경을 통해 시작 설정 파일을 보다 쉽게 관리할 수 있다.

필터링은 관심있는 항목들만 목록에 나타내기 때문에 설정에 드는 수고를 줄일 수 있다. 실행 환경은 "J2SE-1.4" 같은 일반적인 이름을 사용하는 자바 런타임의 사용 가능성을 기술한다. 이클립스는 지정한 환경의 요구사항에 맞거나 그 보다 더 나은 환경을 제공하는 JRE를 선택할 수 있다.

개발동안 하나 이상의 테스트 슈트를 실행하고 있는가? 3.2에서는 동시에 실행할 수 있는 슈트를 여러 개 지정할 수 있으며, 이전 실행의 히스토리를 이용해서 이전 실행 결과를 살펴볼 수 있다. 이클립스 3.2는 JUnit 4.0도 지원한다.

팀으로 작업하기

코드 작성을 하면서 누가, 왜 여기에 이런 코드를 넣었는가 궁금해본 적이 있는가? 이클립스 3.2는 CVS 히스토리를 읽어들여서 현재 파일에 누가 무엇을 했는지, 적절한 색상을 이용한 주석을 보여준다(그림3) 변경된 블록 위에 마우스를 가져가면, 변경사항에 대한 개발자 이름, 날짜, 코멘트를 보여준다. 또한, 다른 파일들에서도 같은 개정번호로 되어있는 변경된 부분들을 강조해준다.

그림3
그림3. CVS Quick Diff 주석은 파일에 대해 누가 무엇을 했는지 주석으로 보여준다. 영역 위로 마우스를 가져가면 개정 사항에 대한 세부 내용을 보여준다.

여러분이 다른 사람의 코드를 호출해서 사용하고 있으며, 새로운 버전이 나오기 전까지 모든 것이 잘 동작한다. 그리고 나면, 호출하는 코드에 맞춰 내가 작성한 프로그램을 수정할 때 까지 해당 코드가 폐기되었다는 경고, 심지어는 컴파일러 오류까지 나타난다. 나는 여러분이 이런 경험이 있을 거라 믿는다. 이클립스 3.2는 이런 문제를 줄여주기 위해 "리팩토링 스크립트"라는 기능을 제공한다.

물론, 리팩토링은 동작을 변경하지 않으면서 소스 코드에 변화를 가하는 것을 의미한다. 예를 들어, 철자가 틀린 필드, 새로운 매개변수가 추가된 메서드등이 있을 수 있다. 이클립스는 여러분이 변경된 코드의 개발자인 경우 이런 변경사항을 자동화하는 기능을 지원한다. 이는 변경된 코드를 사용하는 고객들에게도 유용하다.
모든 리팩토링 동작은 히스토리에 기록된다. 이클립스 3.2에서는 이런 히스토리를 스크립트로 작성할 수 있고, 이를 나중에 재생할 수 있다. CVS에 스크립트를 저장할 수 있고, JAR 파일을 사용하는 사용자는 새로운 버전을 사용할 때 동일한 변경을 재생할 수 있도록 JAR 파일 안에 포함시킬 수도 있다. 이는 patch나 diff를 적용하는 것과는 다르다. 패치는 그들이 생성한 특정 소스 파일에 대해서만 동작한다. 리팩토링 스크립트는 리팩토링한 API를 사용하는 모든 소스 파일에 대해서 동작한다.

다른 사람들이 사용하는 API를 유지보수하는 것은 어려운 작업이며, 이제 이클립스가 이런 작업을 쉽게 해줄 수 있다. 메서드 이름을 변경할 때 이클립스 3.2는 이전 메서드를 그대로 남겨둘 것인지, 폐기된(deprecated)으로 표시할지, 새로운 메서드 호출로 돌려놓을 것인지를 물을 수 있으며, 이 메서드를 호출하는 모든 호출자에 이런 변경사항을 자동으로 적용하는 리팩토링 스크립트를 만들지를 묻는다.

코드 위생

이클립스는 전체 팀에서 코딩 표준(code formatting standards)를 적용하게 해주는 매우 강력한 코드 포매터가 오랜기간 사용되었다. 버전 3.2는 새로운 Clean Up 마법사를 두어 이를 더욱 발전시켰다.(그림4)마법사가 할 수 있는 작업들에는 다음과 같은 것이 있다.
  1. 사용되지 않는 import 제거
  2. 사용하지 않는 private 메서드, 생성자 제거
  3. 누락된 @Override, @Deprecated 주석 추가
  4. 누락된 $NON-NLS$ 추가 또는 불필요한 경우 제거
  5. 모든 for 루프를 향상된for 루프로 변환
  6. 제어 문의 본문을 블록으로 변환
  7. 불필요한 캐스트 제거
  8. Serializable과 Externalizable 클래스에 시리얼 버전 ID 추가
Clean Up 마법사는 자바 파일 하나, 패키지, 전체 프로젝트에 대해서 실행할 수 있다

그림4
그림4. Clean Up 마법사는 전체 프로젝트에서 일관된 코딩 표준을 지키도록 해준다.

결론

자바 프로그래머는 다른 언어나 플랫폼 보다 더 폭넓은 개발환경 선택권을 갖고 있다. 내가 단언할 수는 없지만, 이클립스는 마이크로소프트와 같은 단일 회사가 할 수 없는 부분을 사용자의 열정과 정력이 만들어낸 결과다. 이유가 무엇이든, 이클립스는 NetBeans, IDEA, JDeveloper, JBuilder를 포함한 다른 개발환경과 경쟁하고 있다. 3.2 발표와 함께 이클립스는 Java IDE의 경계를 한 단계 더 나아갔으며, 이는 여러분이 어떤 도구를 선택하든 간에, 모든 자바 개발자에게 유익한 일이 될 것이다.

참고자료
  1. Eclipse home page
  2. Callisto home page
  3. JDT home page
  4. Author's blog
Ed Burnette는 노스 캐롤라이나 주, 캐리(Cary)에 살고 있는 전문 개발자이자 저자이다.