Visual Studio Code에서 Java 애플리케이션 만들기
Visual Studio Code에서 Java 애플리케이션 만들기
IDE(통합 개발 환경)는 코드 개발, 테스트, 디버깅 등 다양한 유틸리티를 제공해서 애플리케이션을 빠르게 만들 수 있게 도와줘요. 범용 IDE로 인기가 높아진 Visual Studio Code에서도, Oracle Java Platform Extension을 설치하면 첫 Java 프로젝트를 쉽게 개발할 수 있어요. 이 글에서는 VS Code에서 Java 프로젝트를 만들고, 코드를 작성·실행·디버깅하며 리팩터링까지 해보는 전체 흐름을 살펴볼게요.
본문
IDE(Integrated Development Environment, 통합 개발 환경)는 코드 개발, 테스트, 디버깅 기능 등 여러 유틸리티를 제공하여 애플리케이션을 빠르게 프로그래밍할 수 있게 해줘요. 범용 IDE로 점점 인기를 얻고 있는 Visual Studio Code를 사용하면, Oracle Java Platform Extension을 설치하는 것만으로 첫 Java 프로젝트를 쉽게 개발할 수 있어요.
설정(Setup)
Oracle Java Platform Extension은 Visual Studio Code Marketplace에서 받을 수 있어요. Visual Studio Code에서 직접 Code 메뉴를 통해 설치할 수 있어요: Code > Settings > Extensions.
명령 팔레트(command palette)를 이용해 새 프로젝트를 만들거나 (View > Command Palette > Java: New Project), 기존 Maven(pom.xml) 또는 Gradle(build.gradle, gradle.properties) 프로젝트 파일이 있는 폴더를 열 수도 있어요. 메뉴 View > Command Palette > Java: New Project를 거쳐 Java with Maven 옵션을 선택해서 새 Maven 프로젝트를 만들어볼게요. 프로젝트를 저장할 디렉터리를 지정하라는 프롬프트가 나타나고(예: concatenate), 그다음 패키지 이름을 입력하면 돼요.
확장 프로그램은 기본 pom.xml과, 소스 폴더가 정의된 Maven 프로젝트의 기본 디렉터리 구조를 생성해줘요. pom.xml 파일은 프로젝트를 빌드하는 데 필요한 대부분의 정보를 담고 있는 단일 설정 파일이에요.
시스템에 JDK가 없다면 확장 프로그램이 JDK를 구하는 것을 도와줘요. Visual Studio Code 메뉴에서 View > Command Palette > Download, install, and Use JDK를 선택하고, 거기 나열된 JDK 중 하나를 설치하거나 운영체제의 기존 JDK 바이너리를 가리키도록 설정하면 돼요. 이 작업은 사용자 설정(user settings)을 업데이트해요. 다른 JDK를 사용하고 싶다면 View > Command Palette > Preferences: Open User Settings (JSON)에 접근해 jdk.jdkhome 설정을 직접 수정하면 돼요.
참고
이 확장 프로그램은 최소 JDK 11 이상을 요구해요.
Oracle Java Platform 확장을 실행하는 것과 같은 JDK로 프로젝트를 빌드하고, 실행하고, 디버그할 수 있어요. 확장 프로그램은 다음 위치에서 JDK를 찾아요.
jdk.jdkhomejava.homeJDK_HOME환경 변수JAVA_HOME환경 변수- 현재 시스템 PATH
다음으로, 생성된 프로젝트를 살펴볼게요.
프로젝트 탐색기(Project Explorer)
Visual Studio Code의 탐색기에서 프로젝트를 시각화할 수 있어요. concatenate 프로젝트의 목표는 두 리스트의 교집합(intersection)을 구하는 거예요. 여러분의 프로그램은 리스트들을 인자로 받아 그 교집합을 계산해야 해요. Concatenate.java 클래스에 이를 구현하기 위해 다음 코드를 추가할게요.
public class Concatenate {
public static void main(String[] args) {
if (args.length < 2) {
IO.println("You need to provide 2 lists as arguments. You provided " + args.length);
throw new UnsupportedOperationException("You need to provide 2 lists as arguments");
}
List<Integer> firstSeries = List.of(args[0].split(",")).stream()
.map(Integer::valueOf).collect(Collectors.toList());
List<Integer> secondSeries = List.of(args[1].split(",")).stream()
.map(Integer::valueOf).collect(Collectors.toList());
List<Integer> elements = extractCommonElements(firstSeries, secondSeries);
IO.println(elements);
}
public static List<Integer> extractCommonElements(List<Integer> list1, List<Integer> list2) {
Set<Integer> intersection = new HashSet<>(list1);
intersection.retainAll(list2);
if (list1.get(0).equals(list2.get(0))) {
intersection.add(list1.get(0));
}
if (list1.get(list1.size() - 1).equals(list2.get(list2.size() - 1))) {
intersection.add(list1.get(list1.size() - 1));
}
return intersection.stream().toList();
}
}
Visual Studio Code의 탐색기 외에도, Oracle Java Platform 확장 프로그램은 프로젝트 구조의 개요를 보여주는 Project Explorer를 제공해요. 이 기능은 Java 패키지 구조 탐색을 단순화하는 것을 목표로 해요.
이것을 사용해 Maven/Gradle Java 프로젝트를 정리(clean)하고, 컴파일하고, 테스트하고, 디버그하고, 실행할 수 있어요.
디버거와 실행 구성(Launch Configurations)
Oracle Java Platform Extension의 실행 구성은 JDK 11 이상을 사용하는 Java 애플리케이션의 디버깅과 실행을 지원해요. Run main | Debug main 코드 렌즈를 선택하거나 Run and Debug 활동 패널에서 실행 구성/디버거를 호출할 수 있어요.
실행 구성과 디버거 구성 모두 다음 동작을 지원해요.
- Pause (일시 중지)
- Step over (한 줄씩 실행, 메서드는 건너뜀)
- Step into (메서드 안으로 들어감)
- Step out (메서드 밖으로 나옴)
- Restart (재시작)
- Stop/Disconnect (중지/연결 해제)
Run and Debug 보기에서 드롭다운 목록의 Java+를 선택한 다음 실행 아이콘을 클릭하면 실행 구성을 사용자 정의할 수 있어요.
기본 실행 구성은 launch.json 파일에 있어요. 이용 가능한 프로세스 중에서 선택하거나, JDWP로 실행 중인 JVM에 연결할 포트를 입력하여 디버거 작업을 연결할 수 있어요. Windows 운영체제에서는 Attach to Shared Memory를 선택할 수도 있어요.
이미지: Attach to port & attach to process
Explorer 보기의 Run Configuration 패널로 가서 프로그램 인자, VM 옵션, 환경 변수를 수정하거나 작업 디렉터리를 설정할 수 있어요. 예를 들어 Program Arguments에 "31,20,15,17" "20,19,17,45"를 추가하면 인자를 사용해 애플리케이션을 실행할 수 있어요.
코드 리팩터링(Code Refactoring)
Java 애플리케이션을 유지 관리하는 일은 보통 기능 요구 사항을 바꾸지 않으면서 내부 코드를 개선하기 위해 많은 작은 변경을 하는 것을 포함해요. 예를 들어 JDK 21 이상을 사용한다면, .get(0)을 선택하고 마우스 오른쪽 클릭으로 Change all occurrences를 통해 SequencedCollection 메서드인 getFirst()를 사용하도록 변경할 수 있어요.
마찬가지로 get(list1.size() - 1)의 모든 발생을 SequencedCollection 메서드인 getLast()로 리팩터링할 수 있어요. extractCommonElements 메서드의 코드는 다음과 같이 돼요.
// works with JDK >= 21
public static List extractCommonElementsAlternative(List list1, List list2) {
Set intersection = new HashSet<>(list1);
intersection.retainAll(list2);
if (list1.getFirst().equals(list2.getFirst())) {
intersection.add(list1.getFirst());
}
if (list1.getLast().equals(list2.getLast())) {
intersection.add(list1.getLast());
}
return intersection.stream().toList();
}
개발 속도를 높이기 위해 Source Action 컨텍스트 메뉴로 클래스에 메서드를 생성할 수 있어요.
Source Action 컨텍스트 메뉴는 Java 소스에서 import 정리(organize imports)를 지원해요. 게다가 VSCode View > Command Palette > Preferences: Open User Settings > Extensions > Java로 가서 jdk를 검색하면 아임포트 최적화 전략을 개선할 수 있어요. Jdk > Java > Imports 옵션을 이렇게 설정할 수 있어요.
Count For Using Star Import- 별표(star) import를 사용할 클래스 수. 기본값은 999예요.Count For Using Static Star Import- 정적 별표(static star) import를 사용할 멤버 수. 기본값은 999예요.Groups- import 문의 그룹(패키지 접두사로 지정)과 정렬 순서. 그룹 내 import 문은 알파벳순으로 정렬돼요.
View > Command Palette > Preferences: Open User Settings > Extensions > Java > On Save: Organize Imports로 가서 체크박스를 선택하면, 문서를 저장할 때 import 정리 동작을 선택할 수 있어요.
더 많은 리팩터링 제안은 Show code 전구(bulb)와 Refactor 컨텍스트 메뉴를 통해 볼 수 있어요. 메서드의 매개변수를 변경, 추가, 이동, 제거할 수 있는 전용 양식을 통해 메서드의 매개변수를 바꾸는 것 같은 더 복잡한 리팩터링도 수행할 수 있어요.
멤버를 한 클래스에서 다른 클래스로 옮기기로 결정했다면 Refactor > Move 컨텍스트 메뉴에서 할 수 있어요.
또한 이 확장 프로그램은 다음 리팩터링도 지원해요.
- 생성자와 메서드 인자의 리팩터링
hashCode/equals및toString()생성- 표현식을 지역 변수에 할당
- 표현식을 지역 변수로 추출
- 선언과 할당으로 분리
- 클래스 멤버를 위/아래로 끌어올리기
- 불필요한 변수 인라인화
- 클래스를 다른 패키지로 이동
- 인터페이스/메서드 추출
- 상수/메서드를 static import로 변환하여 교체
for/try-catch/switch()/while()블록의 리팩터링
리팩터링이 최종 사용자의 기능을 깨지 않고 소프트웨어 품질을 개선하려는 과정이라면, 테스트는 버그 없는 애플리케이션을 만들고 있다는 확신을 얻는 데 도움을 줘요.
테스트 코드(Test Code)
Show code 전구를 통해 테스트를 생성하고, Source Actions...를 선택한 다음 Generate Tests... 옵션을 고르면 돼요.
클래스 이름과 테스트할 메서드를 확인하라는 프롬프트가 표시돼요. 선택을 확인하면 생성된 테스트 클래스에는 비어 있거나 실패하는 메서드들이 포함돼요. 여러분의 목표는 클래스의 각 메서드가 동작을 제대로 평가하는 테스트를 갖는 것이므로, 생성된 일부 메서드의 실행을 제외/건너뛰려면 @Disabled 애노테이션을 추가하면 돼요. extractCommonElements 메서드를 검증하도록 생성된 테스트 중 하나를 수정해볼게요.
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ConcatenateTest {
/**
* Test of extractCommonElements method, of class Concatenate.
*/
@Test
public void testExtractCommonElements() {
IO.println("extractCommonElements");
List list1 = Arrays.asList(31,20,15,17);
List list2 = Arrays.asList(20,19,17,45);
List expResult = Arrays.asList(17, 20);
List result = Concatenate.extractCommonElements(list1, list2);
assertEquals(expResult, result);
}
}
확장 프로그램은 프로젝트의 모든 테스트를 실행하고, 결과를 검토하며, 소스 코드로 이동해 특정 테스트를 실행할 수 있는 Test Explorer 보기를 제공해요.
코드 문서화하기(Document Code)
Oracle Java Platform 확장 프로그램은 미리 형식이 잡힌(preformatted) 미리 채워진(prepopulated) JavaDoc 주석 삽입을 제안하며 문서 작성에 도움을 줘요. 메서드 시그니처 위에 /**를 입력하면 IDE가 JavaDoc 완성을 제안해요. 이 동작은 모든 인자가 준비된 JavaDoc 주석을 만들어줘요.
생성된 javadoc은 다음과 비슷할 거예요.
/**
*
* @param list1
* @param list2
* @return
*/
public static List extractCommonElements(List list1, List list2) {}
프로젝트 발전시키기(Evolving the project)
다른 Java 버전에서 실행되는 프로젝트가 있다면, 사용하는 각 런타임 버전에 대해 프로필을 연결할 수 있어요. 프로필이 만들어지면 그 settings.json을 사용자 정의하고 jdk.jdkhome 값을 정의할 수 있어요.
여러분의 프로젝트처럼 Oracle Java Platform Extension도 계속 개선되고 진화할 거예요. 이 프로젝트는 오픈소스이므로 커뮤니티 기여와 피드백을 환영해요. 기여 가이드를 확인하고, Java로 매끄러운 개발자 경험을 제공하려는 우리의 노력에 함께해주세요.
더 알아보기 (Learn more)
- Visual Studio Code Marketplace - Oracle Java Platform — 확장 프로그램 설치 페이지
- Oracle Java Platform Extension 기여 가이드 — 오픈소스 프로젝트 참여 방법
- Getting Started with Java — Java 입문 과정