코드 한 줄의 기록

자바 프로젝트 구조 완벽 가이드: 소스에서 바이너리까지 빌드 흐름 쉽게 이해하기 본문

JAVA

자바 프로젝트 구조 완벽 가이드: 소스에서 바이너리까지 빌드 흐름 쉽게 이해하기

CodeByJin 2025. 9. 20. 16:17
반응형

자바(Java)로 개발할 때 가장 먼저 마주하게 되는 과제는 프로젝트 구조소스 → 컴파일 → 실행의 흐름을 파악하는 것입니다. IDE를 사용하면 한 번에 처리되지만, 그 내부에서는 어떤 과정이 일어나는지 제대로 이해하지 못하면 문제 해결이 어려워집니다. 이번 글에서는 자바 프로젝트를 구성하는 디렉터리 구조부터 javacjava 명령으로 컴파일하고 실행하는 과정을 단계별로 살펴보며, 실제로 커맨드라인에서 바이너리(.class, .jar)를 생성하고 구동하는 실전 팁을 공유합니다.

자바 프로젝트 기본 디렉터리 구조

1. 전통적인 디렉터리 레이아웃

my-java-project/
├─ src/
│  └─ main/
│     ├─ java/           # 자바 소스 코드
│     └─ resources/      # 설정 파일, 템플릿 등
├─ lib/                  # 외부 라이브러리(.jar)
├─ build/                # 컴파일 결과(.class, .jar)
└─ docs/                 # 문서
  • src/main/java: 애플리케이션 소스 코드를 넣는 최상위 위치
  • src/main/resources: XML, 프로퍼티, 정적 파일
  • lib: Gradle/Maven을 사용 안 할 경우 수동으로 관리하는 라이브러리 폴더
  • build: 컴파일 결과물이 모이는 디렉터리. 직접 javac -d build 형태로 지정

이 구조는 Maven 또는 Gradle 표준과 유사하기에, 수동 빌드든 빌드 도구를 사용하든 자연스럽게 이식됩니다.

 

2. 패키지와 디렉터리 대응

자바 클래스는 package com.example.app;과 같은 패키지를 선언하면 폴더 구조와 일치해야 합니다.
예를 들어 com.example.app.Main 클래스의 소스 파일은:

src/main/java/com/example/app/Main.java

 

위치에 존재해야 컴파일러가 정상적으로 찾을 수 있습니다.

javac로 컴파일하기

1. 단일 파일 컴파일

간단한 HelloWorld 예제로 시작해 봅시다.
Hello.java

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}

 

터미널에서

javac Hello.java

 

실행 결과로 Hello.class가 생성됩니다.

 

2. 다중 소스 컴파일

패키지를 사용하거나 여러 파일을 컴파일할 때는 소스 루트와 출력 디렉터리를 지정해야 합니다.

javac -d build/classes src/main/java/com/example/app/*.java
  • -d build/classes: .class 파일을 build/classes 경로에 패키지 구조대로 생성
  • src/main/java/com/example/app/*.java: 컴파일할 소스 파일

3. 라이브러리 의존성 추가

외부 라이브러리가 있을 땐 -classpath (또는 -cp) 옵션을 사용합니다.

javac -d build/classes -classpath "lib/gson-2.8.9.jar" \
    src/main/java/com/example/app/*.java

 

여러 개의 JAR은 OS별 경로 구분자로 연결
- macOS/Linux: :
- Windows: ;

.class 파일을 실행하는 java

컴파일된 클래스를 실행하려면 java 명령을 사용합니다.

java -classpath build/classes com.example.app.Main
  • -classpath build/classes: .class를 찾을 클래스패스 지정
  • com.example.app.Main: 실행할 클래스의 FQN(fully qualified name)

라이브러리가 필요하면 컴파일할 때처럼 JAR 경로를 포함

java -classpath "build/classes:lib/*" com.example.app.Main

 

lib/*를 쓰면 lib 폴더 내 모든 JAR을 포함합니다.

JAR(Java ARchive) 패키징

1. 매니페스트 파일 없이 간단 패키징

컴파일 후 클래스를 JAR로 묶어 배포하면 실행이 편리합니다.

jar cvf app.jar -C build/classes .

  • c: create
  • v: verbose
  • f: file name 지정
  • -C build/classes .: build/classes 디렉터리 내부의 모든 파일을 포함

2. 실행 가능한 JAR 만들기

Main-Class 정보를 매니페스트에 지정해야 합니다.

  • 매니페스트 파일 작성 (manifest.txt)
    Main-Class: com.example.app.Main
  • JAR 생성
    jar cvfm app.jar manifest.txt -C build/classes .
  • 실행
    java -jar app.jar

Gradle/Maven 사용 없이 이해하는 빌드 흐름

IDE나 빌드 도구 없이도, 커맨드라인에서 위 단계를 순차적으로 따라가면 빌드가 어떻게 일어나는지 확실히 알 수 있습니다.
1. 소스 수정 → 2. javac 컴파일 → 3. .class 생성 → 4. jar 패키징 → 5. java 실행

실제 프로젝트에서는 스크립트(쉘, 배치)나 Gradle/Maven 플러그인을 통해 이 과정을 자동화합니다. 하지만 수작업 경험을 통해 내부 동작 방식을 이해하면, 빌드 오류·클래스패스 문제 해결이 훨씬 수월해집니다.

실전 팁과 주의사항

  • 클래스패스 관리: 너무 길어지면 쉘 스크립트나 환경 변수(CLASSPATH)로 분리하세요.
  • 패키지 구조: 소스 루트(src/main/java)를 기준으로 패키지를 정리해야 합니다.
  • 버전별 JDK 차이: JDK 9 이후부터 모듈 시스템이 추가되어 --module-path 옵션이 등장했습니다. 모듈을 쓰지 않는다면 기존 클래스패스를 그대로 사용해도 무방합니다.
  • 빌드 디렉터리 분리: 소스(src)와 컴파일 결과(build)는 분리해 두어야 클린(clean) 빌드가 가능합니다.
  • 바이너리 배포: 복수의 JAR을 배포할 땐, ‘의존성 포함(fat jar)’ 방식 또는 라이브러리 묶음(라이브러리 폴더 및 스크립트 제공) 방식을 선택하세요.

자바 커맨드라인 빌드는 복잡해 보이지만, 소스 구조컴파일/패키징/실행의 순서를 차근차근 이해하면 훨씬 친숙해집니다. 위 과정을 직접 따라 해 보고, Gradle이나 Maven에서도 어떤 단계가 자동화되어 있는지 비교해 보면 자연스럽게 지식을 체득할 수 있습니다.

 

이 글이 자바 프로젝트 구조빌드 플로우를 공부하는 데 도움이 되길 바라며, 여러분의 현업 개발에도 유용한 가이드가 되기를 기원합니다.

 

Java 컴파일과 실행 과정 완벽 가이드: JVM 작동 원리 이해하기

Java는 “Write Once, Run Anywhere”를 실현한 언어로, 소스 코드를 컴파일하고 JVM이 실행하는 독특한 구조를 갖추고 있습니다. 이 글에서 Java 컴파일러와 JVM의 내부 동작 과정을 단계별로 살펴보고, 개

byteandbit.tistory.com

반응형