지난 6월말 이클립스의 3.4 버전 가니메데가 릴리스되었다. 가니메데는 이전 배포판인 칼리스토, 유로파와 마찬가지로 목성의 위성 이름이다. 가니메데는 이전 버전인 유로파보다 많은 23개의 프로젝트로 구성되어 있다. 많은 기능이 추가되고 개선되었지만 자바 개발자에게 필요한 기능 위주로 가니메데의 기능을 알아본다.
시작하기 전에
새로운 기능을 알아보기 전에 윈도 운영체제 사용자들이 겪을 치명적인 문제를 포함한 몇 가지 문제점과 가능한 해결책을 간략히 알아본다.
-
이클립스가 실행 되지 않는 문제
다운받은 가니메데 배포판의 종류에 따라서 ECLIPSE_HOME/eclipse.ini 파일에 기록된 메모리 크기 관련 설정값이 다르다. 보통은 윈도 버전의 이 클립스에서 메모리 부족 때문에 나타나는 현상으로 Java EE 버전이나 플러그인 개발 버전을 다운 받았다면, eclipse.ini 파일의 -Xmx512m를 – Xmx256으로 수정한다.
-
한글 깨짐 현상
일부 영문 전용 폰트에서 한글 깨짐 현상이 발생한다. 대표적으로 많은 개발자의 사랑을 받고 있는 ‘Bitstream Vera Sans Mono’을 이용하면 문제를 확인할 수 있다. 임시방편으로 영문 전용 폰트에 한글 폰트를 추가해 새로운 폰트를 만들어 사용하는 방법이 있다.
자바 개발환경 개선사항
새로운 리팩터링
자바 리팩터링에 ‘Extract Class(클래스 추출)’가 추가됐다. Extract Class는 한 클래스가 너무 많은 책임을 수행할 때, 책임을 다른 클래스로 분리하는 리팩터링이다.
리팩터링 책의 예제를 활용해보자. <리스트 1>은 리팩터링 전의 Person 클래스로 간단하지만 개인 정보와 연락처 정보 관리라는 두 가지 책임을 가진다. Extract Class로 연락처 관리의 책임을 추출해보자.
<리스트 1>Extract Class 리팩터링을 적용하기 전 Person 클래스
- package refactoring;
- public class Person {
- private String name;
- private String officeAreaCode;
- private String officeNumber;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getOfficeAreaCode() {
- return officeAreaCode;
- }
- public void setOfficeAreaCode(String officeAreaCode) {
- this.officeAreaCode = officeAreaCode;
- }
- public String getTelephoneNumberNumber() {
- return "( " + officeAreaCode + ") "+ officeNumber;
- }
- public String getOfficeNumber() {
- return officeNumber;
- }
- public void setOfficeNumber(String officeNumber) {
- this.officeNumber = officeNumber;
- }
- }
-
package refactoring;
public class Person {
private String name;
private String officeAreaCode;
private String officeNumber;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOfficeAreaCode() {
return officeAreaCode;
}
public void setOfficeAreaCode(String officeAreaCode) {
this.officeAreaCode = officeAreaCode;
}
public String getTelephoneNumberNumber() {
return "( " + officeAreaCode + ") "+ officeNumber;
}
public String getOfficeNumber() {
return officeNumber;
}
public void setOfficeNumber(String officeNumber) {
this.officeNumber = officeNumber;
}
}
먼저 Extract Class 메뉴를 선택한다. 최상단 메뉴나 <화면 1>과 같이 편집기 의 오른쪽 마우스 컨텍스트 메뉴에서 Refactor -> Extract Class를 선택한다.
<화면 1>Extract Class 메뉴 선택
Extract Class 메뉴를 선택하면 <화면 2>와 같이 설정 다이얼로그가 나온다. 설정 다이얼로그에서는 추출 대상 필드를 선택하고, 추출할 클래스 이름과 추출한 클래스의 객체를 참조할 필드 이름을 지정한다. 여기서는 연락처 정보와 관련된 officeAreaCode와 officeNumber 필드를 Telephone 클래스로 추출한다. Person 클래스가 참조하는 Telephone 클래스 인스턴스의 이름은 telephone으로 설정한다.
<화면 2>Extract Class 설정 다이얼로그
<리스트 2>와 <리스트 3>의 코드 로 리팩터링되었다. 위에서 선택한 두 필드를 가지고 있는 Telephone 클래스가 생성되었고, Person 클래스는 Telephone 클래스의 인스턴스를 필드로 가지고 이를 참조하도록 변경되었다. 이클립스가 자동으로 처리해주는 리팩터링 기능에서 특히 클래스간의 관계를 다루는 리팩터링에 대한 처리가 미흡한 편인데 편리한 리팩터링이 하나 더 추가되었다.
<리스트 2>Extract Class 리팩터링 적용 후 Person 클래스
- package refactoring;
- public class Person {
- private String name;
- private Telephone telephone = new Telephone();
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getOfficeAreaCode() {
- return telephone.getOfficeAreaCode();
- }
- public void setOfficeAreaCode(String officeAreaCode) {
- this.telephone.setOfficeAreaCode(officeAreaCode);
- }
- public String getTelephoneNumberNumber() {
- return "( " + telephone.getOfficeAreaCode() + ") "+ telephone.getOfficeNumber();
- }
- public String getOfficeNumber() {
- return telephone.getOfficeNumber();
- }
- public void setOfficeNumber(String officeNumber) {
- this.telephone.setOfficeNumber(officeNumber);
- }
- }
-
package refactoring;
public class Person {
private String name;
private Telephone telephone = new Telephone();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOfficeAreaCode() {
return telephone.getOfficeAreaCode();
}
public void setOfficeAreaCode(String officeAreaCode) {
this.telephone.setOfficeAreaCode(officeAreaCode);
}
public String getTelephoneNumberNumber() {
return "( " + telephone.getOfficeAreaCode() + ") "+ telephone.getOfficeNumber();
}
public String getOfficeNumber() {
return telephone.getOfficeNumber();
}
public void setOfficeNumber(String officeNumber) {
this.telephone.setOfficeNumber(officeNumber);
}
}
<리스트 3>Extract Class 리팩터링 적용 후 Telephone 클래스
- package refactoring;
- public class Telephone {
- private String officeAreaCode;
- private String officeNumber;
- public Telephone() {
- }
- public String getOfficeAreaCode() {
- return officeAreaCode;
- }
- public void setOfficeAreaCode(String officeAreaCode) {
- this.officeAreaCode = officeAreaCode;
- }
- public String getOfficeNumber() {
- return officeNumber;
- }
- public void setOfficeNumber(String officeNumber) {
- this.officeNumber = officeNumber;
- }
- }
-
package refactoring;
public class Telephone {
private String officeAreaCode;
private String officeNumber;
public Telephone() {
}
public String getOfficeAreaCode() {
return officeAreaCode;
}
public void setOfficeAreaCode(String officeAreaCode) {
this.officeAreaCode = officeAreaCode;
}
public String getOfficeNumber() {
return officeNumber;
}
public void setOfficeNumber(String officeNumber) {
this.officeNumber = officeNumber;
}
}
Breadcrumb
자바 편집기 영역에 추가된 기능 중 단연 돋보이는 기능은 ‘Breadcrumb’다. 노트북 등 화면이 크지 않은 환경에서 개발할 때는 편집기 영역을 최대화(커맨드 + M)해서 작업하는 경우가 많은데, Breadcrumb를 통해 현재 위치를 한눈에 볼 수 있고, 편집기의 최대화를 해제하고 ‘Package Explorer (패키지 탐색기)’등을 이용해서 다른 파일을 열어야 하는 불편함을 해소한다.
사용법은 정말 간단한데 화면 상단 툴바의 ‘Toggle Breadcrumb’를 선택하거나, <화면 3>과 같이 편집기의 컨텍스트 메뉴 중 ‘Show in Breadcrumb’를 선택하면 된다. 컨텍스트 메뉴에서 Breadcrumb를 비활성화 시킬 수 있는 방법은 없으니 참고하자. Breadcrumb를 비활성화 시키려면 상단 툴바의 토글 버튼을 이용하자.
<화면 3> Breadcrumb 활성화
Breadcrumb가 활성화되면 <화면 4>와 같이 편집기 상단에 현재 위치를 표시해주는 표시영역이 생긴다. 이 영역을 통해 최대화 상태의 편집기에서도 현재 위치를 한눈에 볼 수 있고, 최대화 상태에서도 편리하게 다른 파일을 열 수 있다.
<화면 4>Breadcrumb의 활성화와 다른 클래스로 이동하기
향상된 Call Hierarchy
이클립스를 사용하는 자바 개발자에게 인기 좋은 기능 중 하나가 ‘Call Hierarchy (호출 계층)’를 살펴보는 기능으로 호출 관계가 복잡한 함수의 호출 관계를 트리 구조로 보여준다. 이클립스 3.3까지는 호출자(caller)를 찾을 때, 특정 함수나 생성자를 사용하고 있는 함수를 찾는 기능만을 제공했다.
이 정도로도 편리한 기능이지만 코드에 존재하지 않는 기본 생성자를 호출해서 객체를 생성하는 위치를 찾으려면, 기본 생성자를 코드에 추가해서 찾아야 하는 단점이 있었다. 또, 상수나 필드를 사용하는 위치를 찾는 기능은 없기 때문에 검색 기능을 이용해서 찾아야 하는 불편함이 있었다.
이클립스 3.4에서는 클래스를 선택하고 ‘Call Hierarchy’를 찾아보면(CTRL + ALT + H) 모든 생성자를 호출하는 위치를 찾아준다. 기본 생성자가 코드 상에 존재하지 않아도 찾아주니 편리하다. 또, 상수나 필드를 사용하는 위치도 ‘Call Hierarchy’를 통해 보여주니 더 이상 불편하게 검색하지 않아도 된다. <화면 5>과 같이 모든 생성자와 상수에 대한 호출 계층을 확인할 수 있다.
<화면 5>향상된 Call Hierarchy. 모든 생성자의 호출 위치(상단)과 필드나 상수의 사용 위치(하단)를 확인할 수 있다.
실행 가능한 JAR 파일 내보내기
기존의 이클립스의 내보내기(Export) 기능에 실행 가능한 JAR(Runnable JAR) 파일을 내보낼 수 있는 기능이 추가되었다. 이를 통해 자바 실행 환경(Java Runtime Environment, JRE)이 설치 되었다면 JAR 파일을 더블클릭하는 것만으로 애플리케이션을 실행할 수 있다.
<리스트 4>는 “Hello Ganymede!”라는 메시지를 화면에 출력하는 단순한 자바 스윙 애플리케이션이다. 이 예제를 실행 가능한 형태의 JAR 파일로 배포해보자.
<리스트 4> main() 함수를 가지는 단순한 스윙 예제
- package runnable;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- public class HelloSwing extends JFrame {
- public HelloSwing() {
- setTitle("Eclipse 3.4 Ganymede");
- getContentPane(). add(new JLabel("Hello Ganymede!"));
- setSize(250, 100);
- }
- public static void main(String[] args) {
- new HelloSwing().setVisible(true);
- }
- }
-
package runnable;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class HelloSwing extends JFrame {
public HelloSwing() {
setTitle("Eclipse 3.4 Ganymede");
getContentPane(). add(new JLabel("Hello Ganymede!"));
setSize(250, 100);
}
public static void main(String[] args) {
new HelloSwing().setVisible(true);
}
}
<화면 6> 실행 가능한 JAR 파일 내보내기
‘File -> Export -> Java -> Runnable JAR file’옵션을 통해 실행 가능한 JAR 파일을 생성할 수 있다. 먼저, Launch Configuration 중에서 JAR 파일을 생성할 대상을 선택한다. 선택한 대상이 MANIFEST.MF 파일에서 Main-Class로 이용된다. 대상 경로와 파일이름을 선택하면 실행 가능한 파일을 생성한다. 생성된 JAR 파일을 더블클릭하면 <화면 7>과 같이 애플리케이션이 실행된다.
<화면 7>JAR로 실행한 애플리케이션
<리스트 5>와 같이 자동 생성된 MANIFEST.MF 파일 은 이전에도 사용자가 직접 작성할 수 있었다. 하지만 이클립스는 단지 MANIFEST.MF 파일을 자동 생성해주는 기능 이상을 제공한다.
<리스트 5>자동 생성된 MANIFEST.MF 파일
- Manifest-Version: 1.0
- Class-Path: .
- Main-Class: runnable.HelloSwing
-
Manifest-Version: 1.0
Class-Path: .
Main-Class: runnable.HelloSwing
예제는 외부 라이브러리를 사용하지 않으니 그리 복잡하지 않지만, 만약 애플리케이션을 구동하는 데 수많은 이클립스 프로젝트에 대한 참조와 라이브러리 파일이 필요하다면 사용자가 직접 작업하기에는 꽤나 복잡해진다. 그래서 이클립스의 실행 가능한 JAR파일 생성 기능은, 참조하는 프로젝트의 모든 클래스 파일과 포함된 모든 라이브러리의 압축을 해제한 클래스 파일을 함께 묶어주는 기능을 제공한다. 사용자는 압축을 해제한 형태로 라이브러리를 재배포하는 것이 라이센스를 위반 하는지만 주위를 기울이면 된다.
Outline 화면에서 코드 재배열하기
개요(Outline) 화면에서 코드의 구성 요소의 위치를 재배열 할 수 있는 기능이 이클립스 3.4에 조용히 추가되었다. 작업 중 추가한 한 뭉치의 코드에서 구성 요소간의 순서가 마음에 들지 않으면 하나씩 잘라내서 원하는 위치에 붙여넣는 작업을 반복하게 된다. 이제 개요 화면 에서 한눈에 전체 구조를 보면서 드래그 앤 드롭 기능을 이용해서 코드를 재배열 할 수 있다. <화면 8>에서 자바 메서드의 드래그 앤 드롭을 통한 위치 이동을 보여준다.
<화면 8> Outline에서 구성 요소의 드래그 앤 드롭
이때, Outline의 자동 정렬 기능 을 이용 중이라면 드래그 앤 드롭은 동작하지 않는다. 특정 요소의 위치를 옮길 때 요소와 요소 사이의 빈 줄 삽입 여부가 의도한 대로 처리되지 않을 수 있으니 처리가 필요하다면 주의하자. Outline에서의 재배치 기능은 자바 에디터뿐 아니라 XML 에디터에서도 지원한다. 앞으로 다양한 에디터 환경에서 지원할 것으로 기대된다.
리치 호버
특정 요소 위에 마우스를 가져다 두면 나타나는 JavaDoc 설명을 보여주는 것과 같은 호버 기능이 향상되었다. JavaDoc 호버는 <화면 9>의 상단 화면과 같이 JavaDoc 화면에서 보기, 외부 브라우저에서 보여주기 등 더 풍부한 기능을 제공한다. 리치 호버 기능이 정말 유용하게 사용되는 때는 디버그 상황에서다. <화면 9>의 하단 화면에서 볼 수 있듯이 복잡한 자료구조에 대한 값도 한 눈에 볼 수 있는 기능을 제공한다. 예전처럼 Variables 화면을 뒤지거나, Expressions 화면에 표현식을 입력해 봐야 하는 불편함이 해소되었다.
<화면 9> 향상된 호버 기능. JavaDoc 호버(상단)와 디버거 호버(하단)
저장 기본 동작 정의
아무리 팀에서 코드 형식을 정해놓고, 이클립스 자동 포맷에 맞춰서 만들어 두어도 자신만의 스타일에 익숙하다면 종종 잊어버리곤 한다. 또, 개발과정 중에 사용하다 남은 불필요한 Import 잔재를 한번에 없애고 싶지만 자동으로 처리해 주지 않으면(Organized Import 기능이 자동으로 처리해 주지만, 직접 명령을 수행해야 한다.) 역시 잊어버리기 쉽다.
이런 요구를 충족해 주는 기능으로 Save Actions 기능이 추가됐다. ‘Windows (윈도) /Eclipse (맥) -> Preferences -> Java -> Editor -> Save Actions’를 보면 저장 시 자동으로 문서 포맷 맞추기, 불필요한 Import 구문 정리하기 등의 기능을 제공한다. <화면 9>와 같이 저장 시 실행할 행동을 정의할 수 있으며, 문서 정렬은 전체 문서에 저장할 것인지 수정된 영역에만 적용할 것인지를 지정할 수 있다.
<화면 10 >저장 시 함께 처리할 행동 정의
Launch Configuration 내보내기/들여오기
Import(가져 오기)/Export(내보내기) 메뉴에 추가된 기능으로 그 동안의 실행 설정(Launch Configuration)을 XML 파일로 저장하고, 저장된 XML 파일을 가지고 오는 기능이 추가됐다.
이 설정은 JDK 버전을 여러 버전으로 맞춰놓고 작업하는 것(컴파일 레벨의 변경이 아니라 실제 JRE를 대체하면 전부 재빌드를 수행하므로 하나의 작업공간에서 모두 처리하기에는 번거롭다)과 같은 이유 등으로 이클립스를 여러 개 설치해 놓고 작업 하거나 작업 공간을 다시 구축해야 하는 경우 매번 복잡한 실행 설정을 하지 않아도 되기에 유용하다.
그 외 자바 개발 환경 개선사항
개발 중인 애플리케이션의 모든 메시지를 별도의 리소스 파일로 따로 뽑아서 관리한다면, 문자열 하나를 찾기 위해 키 값을 찾고, 리소스 파일을 열어서 다시 해당 키값으로 찾아가는 과정이 번거롭게 느껴진다. 가니메데에 새로 추가된 기능으로 리소스 파일로 바로 찾아가는 기능이 추가됐다.
이제 자바 빌드에서 멀티 코어 CPU를 지원한다. 기존의 프로젝트를 이클립스 3.4와 이전 버전의 이클립스에서 모두 새로 빌드해서 체감속도 향상을 느껴보자.
JUnit 테스트를 실행하면 이제 테스트케이스 별로 실행시간을 각각 표시해 준다. 오래 걸리는 테스트케이스를 따로 관리할 때 유용하다.
또, Content Assist 기능, Quick Fix 기능 등 에디터 영역이 전반적으로 편리해졌다.
자바 개발 환경외 주요 변경사항
여기서 다루는 내용은 이클립스 3.4의 자바 개발환경에서의 변경과 개선사항이지만, 자바 개발 환경 이외의 주요한 몇 가지 사항은 알아둘 가치가 있다. 물론 자바 개발과 관련 없는 가장 큰 변경 사항은 화려해진 시작 화면(스플래시 이미지)이다.
새로운 설치 /업데이트 서비스 – p2
기존에 업데이트 매니저를 이용해 플러그인을 설치하던 사용자라면 바로 알아차렸을 텐데, 이클립스의 플러그인 설치/업데이트 기능이 단순히 UI만 변경된 것이 아니라 완전히 새로 변경되었다.
다운로드 자동 재시도, 적합한 미러 자동 선택하기 등의 개선 사항이 있지만 무엇보다도, 기존 사용자들이 가장 불만을 가지고 있던 부분인 버전 의존성 확인 부분이 크게 개선되었다.
이클립스 소스 코드 보고 베끼기 - 플러그인 스파이
이클립스 3.4의 플러그인 개발 환경(Plug-in Development Environment, PDE) 에서 가장 눈에 띄는 기능은 ‘플러그인 스파이 (Plug-in Spy)’다. 이클립스를 사용하다 보면 플러그인 개발 자가 아닐지라도 , 어떻게 구현됐는지 코드 를 보고 싶은 경우가 있다. 기존에는 플러그인 개발자에게도 특정 영역의 코드를 찾아가는 작업이 쉽지 않았다. 이제 플러그인 스파이 덕분에 코드를 보고 싶은 관심 대상 화면을 선택한 후 ‘SHIFT +ALT+F1’을클릭하면 해당 화면이 정의된 플러그인과 해당 화면의 클래스 등 각종 정보를 쉽게 얻을 수 있다.
플러그인 스파이 기능을 활용하려면 PDE 관련 플러그인을 설치하거나 플러그인 개발자용 이클립스를 다운받아야 한다. 이클립스의 소스 코드를 참조해서 자신만의 플러그인을 만드는 내용에 대해서는 다음에 기회가 되면 자세히 알아보겠다.
자바스크립트 개발 툴킷
웹 개발 환경에서 가장 눈에 띄는 변화는 WTP 3.0에 새로 추가된 자바스크립트 개발 툴킷(JavaScript Development Toolkit, JSDT)이다. js 파일의 포맷팅 기능, 콜 계층 보기 지원 등의 기능이 눈에 띈다. 게다가 추가적인 자바스크립트 라이브러리의 지원을 위한 확장점도 제공하고 있으니, 자신만의 라이브러리를 지원하는 것도 용이하다. WTP 3.0에 포함된 기능이므로 WTP 3.0을 별도로 설치하거나 Java EE 버전 이클립스를 다운받으면 된다.
서브버전(SVN) 클라이언트 전쟁의 승자 –Subversive
가니메데에 서브버전 클라이언트로 Subversive 프로젝트가 채택되었다. 이미 그 전부터 예견된 일이었지만, 이로써 Subclipse보다 한 발 앞서 나가게 되었다.아직 서브버전 클라이언트를 결정하지 못했다면 Subversive를 도입해 보자. 승자라고 표현했지만, 정식 프로젝트로 합류가 빨랐을 뿐이지 아직 Subclipse가 사장되는 것은 아니 라는 점을 염두에 두자.
마치며
지금까지 이클립스 3.4 가니메데의 새로운 기능을 자바 개발자의 시각에서 알아보았다. 이클립스 는 새로운 버전이 나올 때 마다 하위 프로젝트의 규모가 계속 커지고 있 기에 새로운 기능을 모두 다루는 것은 현실적으로 불가능하다. 개인적으로는 여기서 소개한 내용 외에도 ECF 2.0 에 추가된 협업시스템을 이용한 인스턴스 메신저 와 짝 프로그래밍 지원 , DLTK프로젝트의 동적 언어 지원, 그리고 DSDP 프로젝트의 터미널 환경 지원 등 에 관심이 간다. 이처럼 자바 개발 환경 외에 새로운 기능 중에서도 자신에게 맞는 보석 같은 기능 들이 많이 숨겨져 있으니 간단히 한 번 살펴보는 것을 권한다 .
아직도 이클립스를 무거운 텍스트 에디터의 용도로 사용하 는 경우가 많은데, 시간을 조금만 투자하면 정말 훌륭한 IDE 로 활용할 수 있다. 필요한 기능부터 하나씩 적용해 나가보자 .
참고문헌
-
한눈에 보는 이클립스 가니메데
http://www.ibm.com/developerworks/kr/library/os-eclipse-ganymede/index.html?ca=drs-kr -
Eclipse 3.4 – New and Noteworthy
http://ganymede-mirror2.eclipse.org/eclipse/downloads/drops/R-3.4-200806172000/whatsnew3.4/eclipse-news.html -
Eclipse Ganymede: An in-depth look at JDT (Java Development Tools)