맨위로가기

클래스패스

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

클래스패스는 자바 가상 머신(JVM)이 클래스 파일을 찾도록 돕는 경로 설정으로, 자바 애플리케이션 실행에 필수적이다. JVM은 부트스트랩 클래스, 확장 클래스, 사용자 정의 클래스 순으로 클래스를 검색하며, 클래스패스가 잘못 설정되면 `NoClassDefFoundError` 또는 `ClassNotFoundException` 오류가 발생할 수 있다. 클래스패스는 환경 변수(CLASSPATH), 명령줄 인수(-classpath 또는 -cp), JAR 파일의 매니페스트 파일, 그리고 자바 6 이상에서 와일드카드(*)를 사용하여 설정할 수 있다. 운영체제에 따라 클래스패스 구분자가 다르며, 유닉스 계열은 콜론(:), 윈도우는 세미콜론(;)을 사용한다.

2. 클래스패스의 역할 및 중요성

자바 프로그램을 실행할 때, 자바 가상 머신(JVM)은 클래스를 동적 로딩 방식으로 찾아서 로드한다. 이는 클래스의 바이트코드가 해당 클래스가 프로그램 내에서 처음 사용되는 시점에 로드됨을 의미하는 지연 로딩(lazy loading) 방식이다. 클래스패스는 바로 이 과정에서 JVM에게 필요한 클래스 파일(.class 파일)이나 클래스가 담긴 Jar 파일을 파일 시스템의 어느 위치에서 찾아야 하는지 알려주는 중요한 경로 설정 정보이다.

클래스패스가 올바르게 설정되지 않으면, JVM은 실행에 필요한 클래스를 찾지 못하게 되고, 이는 `NoClassDefFoundError`나 `ClassNotFoundException`과 같은 실행 시간 오류로 이어질 수 있다. 따라서 자바 애플리케이션이 정상적으로 동작하기 위해서는 정확한 클래스패스 설정이 필수적이다.

JVM은 다음과 같은 정해진 순서에 따라 클래스를 검색하고 로드한다.

# 부트스트랩 클래스: 자바 플랫폼의 가장 기본적인 클래스들이다. 자바 클래스 라이브러리의 공개 클래스와 이 라이브러리들이 작동하는 데 필요한 내부 클래스들이 포함된다. 이 클래스들은 JVM 자체에 내장되어 있거나 특별한 위치에 있어 별도의 클래스패스 설정 없이 자동으로 로드된다.

# 확장 클래스: 자바 런타임 환경(JRE) 또는 JDK의 확장 디렉토리(일반적으로 jre/lib/ext/)에 위치한 패키지들이다. 자바 플랫폼의 표준 기능을 확장하는 라이브러리들이 여기에 해당하며, 이 클래스들 역시 기본적으로 JVM이 인식한다.

# 사용자 정의 클래스 및 라이브러리: 개발자가 직접 작성하거나 외부 라이브러리 형태로 사용하는 클래스들이다. JVM이 이 클래스들을 찾기 위해서는 반드시 클래스패스에 해당 클래스 파일이 있는 디렉토리나 Jar 파일의 경로가 명시적으로 지정되어 있어야 한다.

기본적으로 JDK의 표준 API 패키지들과 확장 클래스들은 별도의 설정 없이 사용할 수 있다. 하지만 사용자가 정의한 모든 패키지와 라이브러리는 명령줄 인자(-cp 또는 -classpath), 환경 변수(CLASSPATH), 혹은 Jar 파일 내의 Manifest 파일에 정의된 Class-Path 속성을 통해 그 위치를 클래스패스에 명시적으로 설정해주어야 한다.

3. 클래스패스 설정 방법

자바 애플리케이션을 실행하거나 컴파일할 때, JVM이나 자바 컴파일러(javac)는 필요한 클래스 파일이나 JAR 파일을 찾아야 한다. 이때 참조하는 경로를 클래스패스라고 부른다. 클래스패스는 여러 가지 방법으로 설정할 수 있다.

주요 설정 방법은 다음과 같으며, 각 방법에 대한 자세한 내용은 아래 하위 섹션에서 다룬다.


  • 환경 변수: 운영체제의 `CLASSPATH` 환경 변수를 이용해 시스템 전역 또는 사용자별로 설정하는 방법이다.
  • 명령줄 인수: `java` 또는 `javac` 명령어 실행 시 `-classpath` 또는 `-cp` 옵션을 사용하여 특정 실행에만 적용하는 방법이다.
  • 매니페스트 파일: JAR 파일 내부에 포함된 `MANIFEST.MF` 파일의 `Class-Path` 속성을 통해 해당 JAR 파일 실행 시 필요한 라이브러리 경로를 지정하는 방법이다.
  • 와일드카드 사용: 자바 6 버전부터 지원되는 방식으로, 특정 디렉토리 안의 모든 JAR 파일을 `*` 문자를 사용하여 한 번에 클래스패스에 추가하는 방법이다.

3. 1. 환경 변수

`CLASSPATH`라는 이름의 환경 변수를 사용하여 클래스패스를 설정할 수도 있다. 이 환경 변수는 시스템 전체 또는 사용자별로 클래스 로딩 경로를 지정하는 데 사용된다. 운영체제에 따라 경로를 구분하는 문자가 다른데, Windows에서는 세미콜론(;)을 사용하고, 리눅스 및 macOS에서는 콜론(:)을 사용한다.

예를 들어, 여러 경로를 포함하여 클래스패스를 설정하는 방법은 다음과 같다.

  • Windows:



set CLASSPATH=.;C:\myprogram;D:\myprogram\lib\supportLib.jar


  • Linux/macOS:



export CLASSPATH=.:/myprogram:/myprogram/lib/supportLib.jar



단일 디렉터리를 클래스패스로 설정하고 자바 애플리케이션을 실행하는 간단한 예시는 다음과 같다. (Windows 기준)



D:\myprogram> set CLASSPATH=D:\myprogram

D:\myprogram> java org.mypackage.HelloWorld



Java 애플리케이션을 시작할 때 사용하는 `-classpath` (또는 `-cp`) 옵션은 `CLASSPATH` 환경 변수보다 우선순위가 높다. 즉, `-classpath` 옵션을 사용하면 환경 변수에 설정된 `CLASSPATH` 값은 무시된다. 만약 `-classpath` 옵션과 `CLASSPATH` 환경 변수 둘 다 지정하지 않으면, 현재 작업 디렉터리(`.`)가 기본 클래스패스로 사용된다. 예를 들어, 현재 작업 디렉터리가 `D:\myprogram` (Windows) 또는 `/home/user/myprogram` (Linux/macOS)이라면, 해당 디렉터리가 자동으로 클래스패스로 간주되므로 별도로 지정할 필요가 없다.

그러나 클래스패스를 명시적으로 설정할 때는 현재 디렉터리(`.`)를 포함하는 것이 권장된다. 이렇게 해야 현재 디렉터리에 있는 클래스 파일들도 JVM이 찾을 수 있다.

이러한 클래스패스 설정 규칙은 Java 실행기(`java`)뿐만 아니라 Java 컴파일러인 javac에도 동일하게 적용된다. 경우에 따라 특정 JDK 버전을 사용하도록 지정하기 위해 `JAVA_HOME` 환경 변수도 함께 설정하거나 확인해야 할 수 있다.

3. 2. 명령줄 인수

`java` 명령어를 실행할 때 `-classpath` 또는 단축형인 `-cp` 옵션을 사용하여 클래스패스를 지정할 수 있다. 이 방법은 특정 프로그램을 실행할 때 임시로 클래스패스를 설정하고자 할 때 유용하다.

예를 들어, `org.mypackage`라는 패키지에 다음과 같은 클래스가 포함되어 있다고 가정해 보자.

  • `HelloWorld` (메인 클래스)
  • `SupportClass`
  • `UtilClass`


이 패키지를 정의하는 클래스 파일들은 물리적으로 특정 디렉토리(예: 윈도우의 `D:\myprogram` 또는 리눅스의 `/home/user/myprogram`) 아래의 `org\mypackage` (또는 `org/mypackage`) 경로에 저장된다.

파일 구조는 다음과 같다.



`java` 명령어를 호출하여 `org.mypackage.HelloWorld` 클래스를 실행하려면, JVM에게 클래스 파일들이 위치한 기본 경로(패키지 구조가 시작되는 상위 디렉토리)를 알려주어야 한다. 이때 `-classpath` 또는 `-cp` 옵션을 사용한다.



여기서 각 부분은 다음을 의미한다.


  • `java`: 자바 런타임 실행 도구이다. (javac, javadoc 등과 같은 SDK 도구 중 하나이다.)
  • `-classpath D:\myprogram` (또는 `-cp /home/user/myprogram`): 프로그램에서 사용하는 패키지들의 루트 디렉토리 경로를 설정한다.
  • `org.mypackage.HelloWorld`: 실행할 메인 클래스의 전체 이름이다.


만약 프로그램이 `D:\myprogram\lib\` 디렉토리에 있는 `supportLib.jar`라는 JAR 파일 형태의 라이브러리를 사용한다면, 클래스패스에 해당 JAR 파일의 경로도 포함시켜야 한다. 파일 구조가 다음과 같다고 가정하자.



D:\myprogram\

|

  • --> lib\

|

  • --> supportLib.jar

|

  • --> org\

|

  • --> mypackage\

|

  • --> HelloWorld.class
  • --> SupportClass.class
  • --> UtilClass.class



이 경우, 다음과 같이 명령줄 옵션을 지정해야 한다. 여러 경로는 운영체제에 맞는 구분자(윈도우: `;`, 리눅스: `:`)로 구분한다. 아래는 윈도우 환경에서의 예시이다.



java -classpath D:\myprogram;D:\myprogram\lib\supportLib.jar org.mypackage.HelloWorld



참고로, 클래스 파일이 포함된 디렉토리(예: `D:\myprogram`)에서 `java` 명령어를 실행하는 경우, 현재 작업 디렉터리를 클래스패스에 명시적으로 추가할 필요는 없다.

대안으로, 운영체제의 환경 변수 `CLASSPATH`를 설정하여 클래스패스를 지정할 수도 있다.

윈도우 환경에서의 예시는 다음과 같다.



D:\myprogram>set CLASSPATH=D:\myprogram;D:\myprogram\lib\supportLib.jar

D:\myprogram>java org.mypackage.HelloWorld


3. 3. 매니페스트 파일

JAR 파일 내부에 포함된 매니페스트 파일(일반적으로 `MANIFEST.MF`)을 사용하여 클래스패스를 지정할 수 있다. 이 방법은 JAR 파일을 실행할 때 필요한 라이브러리 경로를 자동으로 설정해주므로 편리하다.

매니페스트 파일 내에서 `Class-Path` 속성을 사용하여 클래스패스를 명시한다. 이 속성에는 하나 이상의 라이브러리 경로를 공백으로 구분하여 나열할 수 있다. 중요한 점은 여기에 지정하는 경로는 JAR 파일의 위치를 기준으로 한 상대 경로여야 한다는 것이다. 명령줄에서 사용하는 `-classpath` 옵션처럼 절대 경로를 사용하거나 JAR 파일 내부의 특정 클래스 경로를 직접 지정하는 것은 지원되지 않는다.

예를 들어, 프로그램이 `D:\myprogram` 디렉토리에 있는 `helloWorld.jar` 파일로 묶여 있고, 필요한 라이브러리 `supportLib.jar`가 하위 `lib` 폴더에 있다고 가정해보자. 파일 구조는 다음과 같다.

```

D:\myprogram\

|

  • --> helloWorld.jar

|

  • --> lib\

|

  • --> supportLib.jar

```

이때 `helloWorld.jar` 안의 매니페스트 파일 내용은 다음과 같이 작성될 수 있다.

```

Main-Class: org.mypackage.HelloWorld

Class-Path: lib/supportLib.jar lib/supportLib2.jar

```

  • `Main-Class`: `java -jar` 명령어로 JAR 파일을 실행할 때 자동으로 시작될 메인 클래스를 지정한다. 이 값은 명령줄에서 변경할 수 없다.
  • `Class-Path`: `helloWorld.jar` 파일을 기준으로 `lib` 폴더 아래의 `supportLib.jar`와 `supportLib2.jar`를 클래스패스에 추가하도록 지정한다. 여러 경로는 공백으로 구분한다.


유의할 점은 매니페스트 파일의 각 줄은 줄 바꿈 문자(newline)나 캐리지 리턴(carriage return) 문자로 끝나야 한다는 것이다.

이렇게 매니페스트 파일에 클래스패스가 정의되어 있으면, 다음과 같이 간단히 프로그램을 실행할 수 있다.

```

java -jar D:\myprogram\helloWorld.jar [애플리케이션 인자]

```

이 명령을 실행하면 JVM매니페스트 파일의 `Main-Class`에 지정된 클래스(`org.mypackage.HelloWorld`)를 실행하고, `Class-Path`에 명시된 라이브러리(`lib/supportLib.jar`, `lib/supportLib2.jar`)를 자동으로 클래스패스에 포함시킨다. 따라서 별도로 `-classpath` 옵션을 지정할 필요가 없다.

`-jar` 옵션에 대한 더 자세한 내용은 Java 공식 문서에서 확인할 수 있다.

3. 4. 와일드카드 사용 (Java 6 이상)

자바 6 이상 버전에서는 와일드카드(`*`) 표기법을 사용하여 특정 디렉토리 내의 모든 JAR 파일을 클래스패스에 한 번에 추가할 수 있다.

  • 윈도우 예시:

java -classpath ".;c:\mylib\*" MyApp

  • 리눅스/macOS 예시:

java -classpath '.:/mylib/*' MyApp

이 와일드카드 방식은 명령줄에서 -classpath 옵션을 사용할 때뿐만 아니라, 시스템 환경 변수로 클래스패스를 설정할 때도 동일하게 적용된다.

4. 클래스 로딩 방식

자바 프로그램을 실행할 때, 자바 가상 머신(JVM)은 동적 로딩과 유사한 방식으로 클래스를 찾아서 로드한다. 이는 클래스가 처음 사용될 때 해당 클래스의 바이트코드를 로드하는 지연 로딩(lazy loading|레이지 로딩eng) 방식이다. 이때 클래스패스는 JVM에게 클래스를 정의하는 파일이 파일 시스템의 어디에 있는지 알려주는 역할을 한다.

JVM은 다음 순서에 따라 클래스를 검색하고 로드한다.

# '''부트스트랩 클래스''': 자바 플랫폼의 기본 클래스들이다. 여기에는 자바 클래스 라이브러리의 공개 클래스와 라이브러리 작동에 필요한 비공개 클래스들이 포함된다.

# '''확장 클래스''': JRE나 JDK의 확장 디렉토리(jre/lib/ext/)에 위치한 패키지들이다.

# '''사용자 정의 패키지 및 라이브러리''': 개발자가 직접 만들거나 외부에서 가져온 패키지와 라이브러리들이다.

기본적으로 JDK 표준 API의 패키지와 확장 패키지는 별도의 설정 없이 접근할 수 있다. 하지만 사용자가 정의한 모든 패키지와 라이브러리는 클래스패스를 통해 그 경로를 명시적으로 지정해주어야 한다. 이는 보통 명령줄 옵션이나, 클래스가 포함된 JAR 파일 내부의 Manifest 파일을 통해 설정한다.

5. 운영체제별 클래스패스 구분자

클래스패스는 파일 시스템과 밀접하게 관련되어 있어, 명령줄 인수에서 사용하는 클래스패스 구분자는 운영 체제에 따라 다르다.[1]



하지만 이 규칙은 클래스패스를 매니페스트 파일에 정의할 때는 적용되지 않는다. 매니페스트 파일에서는 운영 체제 종류와 관계없이 각 파일 경로를 공백(" ")으로 구분해야 한다.

6. 클래스패스 문제 해결

애플리케이션 프로그래머는 자바 애플리케이션 실행 중 클래스패스 설정을 확인하고 디버깅하기 위해 다음 자바 코드를 사용할 수 있다.
`System.getProperty("java.class.path")`이 코드는 현재 JVM에 설정된 클래스패스 문자열을 반환한다. 클래스 로딩 관련 오류가 발생했을 때 이 값을 확인하여 클래스패스 설정이 올바른지 검토하는 것이 문제 해결의 한 방법이 될 수 있다.

참조

[1] 웹사이트 The Classpath http://www.antwerkz.[...] 2016-06-26
[2] 웹사이트 https://docs.oracle.[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com