수색…


소개

클래스 경로는 Java 런타임이 클래스 및 자원을 찾는 위치를 나열합니다. 클래스 경로는 이전에 컴파일 된 외부 종속성을 찾기 위해 Java 컴파일러에서도 사용됩니다.

비고

자바 클래스 로딩

JVM (Java Virtual Machine)은 클래스가 필요할 때 클래스를로드합니다 (이를 지연로드 (lazy-loading)이라고 함). 사용되는 클래스의 위치는 다음 세 곳에서 지정됩니다.

  1. Java 클래스 라이브러리에있는 것과 같이 Java 플랫폼에 필요한 것들이 먼저로드되고 그 종속성이 있습니다.
  2. 확장 클래스가 다음에로드됩니다 (즉, jre/lib/ext/ 있는 클래스)
  3. 클래스 경로를 통해 사용자 정의 클래스가로드됩니다.

클래스는 java.lang.ClassLoader 부속 유형 인 클래스를 사용하여로드됩니다. 이것에 대해서는이 주제 : 클래스 로더 에서 자세히 설명합니다.

클래스 패스

classpath는 사용자 정의 클래스 및 패키지의 위치를 ​​지정하는 JVM 또는 컴파일러에서 사용되는 매개 변수입니다. 이것은 대부분의 예제와 같이 명령 행에서 설정하거나 환경 변수 ( CLASSPATH )를 통해 설정할 수 있습니다.

클래스 경로를 지정하는 여러 가지 방법

클래스 경로를 설정하는 세 가지 방법이 있습니다.

  1. CLASSPATH 환경 변수를 사용하여 설정할 수 있습니다.

     set CLASSPATH=...         # Windows and csh
     export CLASSPATH=...      # Unix ksh/bash
    
  2. 다음과 같이 명령 줄에서 설정할 수 있습니다.

     java -classpath ...
     javac -classpath ...
    

    -classpath (또는 -cp ) 옵션은 CLASSPATH 환경 변수보다 우선합니다.

  3. 실행 가능한 JAR 파일의 Class-PathMANIFEST.MFClass-Path 요소를 사용하여 지정됩니다.

     Class-Path: jar1-name jar2-name directory-name/jar3-name
    

    JAR 파일이 다음과 같이 실행될 때만 적용된다는 점에 유의하십시오.

     java -jar some.jar ...
    

    이 실행 모드에서는 JAR 파일에 Class-Path 요소가없는 경우에도 -classpath 옵션과 CLASSPATH 환경 변수가 무시됩니다.

classpath가 지정되어 있지 않은 경우, 디폴트의 classpath는, java -jar 사용하는 경우는 선택된 JAR 파일, 그렇지 않은 경우는 현재의 디렉토리가됩니다.

관련 항목 :

디렉토리의 모든 JAR를 클래스 경로에 추가

디렉토리의 모든 JAR를 classpath에 추가하려면 classpath 와일드 카드 구문을 사용하여 간결하게이 작업을 수행 할 수 있습니다. 예 :

 someFolder/*

이는 someFolder 디렉토리의 모든 JAR 및 ZIP 파일을 클래스 경로에 추가하도록 JVM에 지시합니다. 이 구문은 실행 가능한 JAR 파일의 매니페스트 파일에서 -cp 인수, CLASSPATH 환경 변수 또는 Class-Path 특성에서 사용할 수 있습니다 . 클래스 경로 설정 : 클래스 경로 와일드 카드 예제 및주의 사항을 참조하십시오.

노트:

  1. Classpath 와일드 카드는 Java 6에서 처음 도입되었습니다. 이전 버전의 Java에서는 "*"를 와일드 카드로 처리하지 않습니다.
  2. " " 앞에 또는 뒤에 다른 문자를 넣을 수 없습니다 . 예 : "someFolder / .jar"는 와일드 카드가 아닙니다.
  3. 와일드 카드는 접미어 ".jar"또는 ".JAR"이있는 파일과 만 일치합니다. ZIP 파일은 무시되며 다른 접미사가있는 JAR 파일도 무시됩니다.
  4. 와일드 카드는 서브 디렉토리가 아닌 디렉토리 자체의 JAR 파일과 만 일치합니다.
  5. 하나의 JAR 파일 그룹이 와일드 카드 항목과 일치하면 클래스 경로에서의 상대 순서가 지정되지 않습니다.

클래스 경로 구문

클래스 경로는 디렉토리 경로 이름, JAR 또는 ZIP 파일 경로 이름 또는 JAR / ZIP 와일드 카드 사양 인 일련의 항목입니다.

  • 명령 행에서 지정된 클래스 경로 (예 : -classpath ) 또는 환경 변수의 경우, 항목은 ; 로 분리되어야합니다 ; (세미콜론) 문자 또는 다른 플랫폼 (Linux, UNIX, MacOSX 등)의 : 콜론) 문자.

  • JAR 파일의 MANIFEST.MF 에있는 Class-Path 요소의 경우 단일 공백을 사용하여 항목을 구분하십시오.

때로는 클래스 경로 항목에 공간을 임베드해야합니다.

  • 명령 행에 클래스 경로가 지정되면, 단순히 적절한 쉘 인용 부호를 사용하는 문제 일뿐입니다. 예 :

    export CLASSPATH="/home/user/My JAR Files/foo.jar:second.jar"
    

    (세부 사항은 사용하는 명령 셸에 따라 다를 수 있습니다.)

  • 클래스 경로가 JAR 파일의 "MANIFEST.MF"파일에 지정되면 URL 인코딩을 사용해야합니다.

     Class-Path: /home/user/My%20JAR%20Files/foo.jar second.jar
    

동적 클래스 패스

때로는 폴더에서 모든 JAR을 추가하는 것만으로는 충분하지 않습니다. 예를 들어, 네이티브 코드가 있고 JAR의 하위 집합을 선택해야하는 경우입니다. 이 경우 두 개의 main() 메소드가 필요하다. 첫 번째 클래스는 클래스 로더를 만든 다음이 클래스 로더를 사용하여 두 번째 main() 을 호출합니다.

다음은 플랫폼에 맞는 올바른 SWT 기본 JAR을 선택하고 모든 애플리케이션의 JAR을 추가 한 다음 실제 main() 메소드를 호출하는 예제입니다. 크로스 플랫폼 Java SWT 애플리케이션 생성

클래스 경로에서 자원로드

JAR 내에 패키지 된 자원 (이미지, 텍스트 파일, 특성, KeyStore, ...)을로드하는 것이 유용 할 수 있습니다. 이를 위해 ClassClassLoader 사용할 수 있습니다.

다음과 같은 프로젝트 구조가 있다고 가정 해보십시오.

program.jar
|
\-com
  \-project
    |
    |-file.txt
    \-Test.class  

그리고 Test 클래스에서 file.txt 의 내용에 액세스하려고합니다. 클래스 로더에게 다음과 같이 요청할 수 있습니다.

InputStream is = Test.class.getClassLoader().getResourceAsStream("com/project/file.txt");

클래스 로더를 사용하여 리소스 (각 패키지)의 정규화 된 경로를 지정해야합니다.

또는 Test 클래스 객체에 직접 요청할 수 있습니다.

InputStream is = Test.class.getResourceAsStream("file.txt");

클래스 객체를 사용하면 경로는 클래스 자체와 관련이 있습니다. 우리의 Test.classcom.project 패키지에 있으며, file.txt 와 마찬가지로 모든 경로를 지정할 필요가 없습니다.

그러나 다음과 같이 클래스 객체의 절대 경로를 사용할 수 있습니다.

 is = Test.class.getResourceAsStream("/com/project/file.txt");

클래스 이름을 경로 이름으로 매핑

표준 Java 툴체인 (및 타사 도구와 상호 운용되도록 설계된)은 클래스의 이름을 파일의 경로 이름과이를 나타내는 다른 리소스에 매핑하는 특정 규칙을 가지고 있습니다.

매핑은 다음과 같습니다.

  • 기본 패키지에있는 클래스의 경우 경로 이름은 단순한 파일 이름입니다.
  • 명명 된 패키지의 클래스의 경우 패키지 이름 구성 요소는 디렉토리에 매핑됩니다.
  • 명명 된 중첩 클래스와 내부 클래스의 경우 파일 이름 구성 요소는 클래스 이름을 $ 문자로 결합하여 구성됩니다.
  • 익명 내부 클래스의 경우 이름 대신 숫자가 사용됩니다.

이것은 다음 표에 설명되어 있습니다.

클래스 이름 소스 경로 이름 클래스 파일 경로명
SomeClass SomeClass.java SomeClass.class
com.example.SomeClass com/example/SomeClass.java com/example/SomeClass.class
SomeClass.Inner ( SomeClass.java ) SomeClass$Inner.class
내부 클래스의 SomeClass ( SomeClass.java ) SomeClass$1.class , SomeClass$2.class

클래스 패스가 의미하는 것 : 검색 작동 원리

클래스 경로의 목적은 JVM에게 클래스 및 기타 자원을 찾을 위치를 알려주는 것입니다. 클래스 패스와 검색 프로세스의 의미는 서로 얽혀 있습니다.

클래스 경로는 자원을 찾을 위치 순서를 지정하는 검색 경로의 양식입니다. 표준 클래스 경로에서이 위치는 호스트 파일 시스템의 디렉토리, JAR 파일 또는 ZIP 파일입니다. 각각의 경우에 위치는 검색 될 네임 스페이스 의 루트입니다.

클래스 경로에서 클래스를 검색하는 표준 절차는 다음과 같습니다.

  1. 클래스 이름을 상대 클래스 파일 경로 이름 RP 매핑하십시오. 클래스 파일 이름에 대한 클래스 이름 매핑은 다른 곳에서 설명합니다.

  2. 클래스 패스의 각 항목 E 에 대해 :

    • 항목이 파일 시스템 디렉토리 인 경우 :
      • E 를 기준으로 RP 해결하여 절대 경로 이름 AP 합니다.
      • AP 가 기존 파일의 경로인지 테스트합니다.
      • 그렇다면 해당 파일에서 클래스를로드하십시오.
    • 항목이 JAR 또는 ZIP 파일 인 경우 :
      • JAR / ZIP 파일 색인에서 RP 를 찾습니다.
      • 해당 JAR / ZIP 파일 항목이 있으면 해당 항목에서 클래스를로드하십시오.

클래스 경로에서 자원을 검색하는 절차는 자원 경로가 절대 경로인지 상대 경로인지에 따라 다릅니다. 절대 리소스 경로의 경우 절차는 위와 같습니다. Class.getResource 또는 Class.getResourceAsStream 사용해 해결되는 상대 자원 패스에서는, 클래스 패키지의 패스가 검색 전에 추가됩니다.

표준 Java 클래스 로더에 의해 구현 된 프로 시저이므로 사용자 정의 클래스 로더가 검색을 다르게 수행 할 수 있습니다.

부트 스트랩 클래스 경로

일반적인 Java 클래스 로더는 확장 및 응용 프로그램 클래스 경로를 확인하기 전에 부트 스트랩 클래스 경로에서 먼저 클래스를 찾습니다. 기본적으로 부트 스트랩 클래스 경로는 "rt.jar"파일과 JRE 설치로 제공되는 다른 중요한 JAR 파일로 구성됩니다. 이것들은 다양한 "내부"구현 클래스와 함께 표준 Java SE 클래스 라이브러리의 모든 클래스를 제공합니다.

정상적인 상황에서는이 문제에 신경을 쓸 필요가 없습니다. 기본적으로 java , javac 등과 같은 명령은 적절한 버전의 런타임 라이브러리를 사용합니다.

매우 자주, 표준 라이브러리에서 클래스의 다른 버전을 사용하여 Java 런타임의 정상적인 동작을 무시해야합니다. 예를 들어 런타임 라이브러리에서 정상적인 방법으로 해결할 수없는 "쇼 스토퍼"버그가 발생할 수 있습니다. 이러한 경우, 변경된 클래스를 포함하는 JAR 파일을 작성한 다음 JVM을 시작하는 부트 스트랩 클래스 경로에 추가 할 수 있습니다.

java 명령은 부트 스트랩 클래스 경로를 수정하기위한 다음 -X 옵션을 제공합니다.

  • -Xbootclasspath:<path> 는 현재 부트 클래스 경로를 제공된 경로로 바꿉니다.
  • -Xbootclasspath/a:<path> 는 제공된 경로를 현재 부트 클래스 경로에 추가합니다.
  • -Xbootclasspath/p:<path> 는 제공된 경로를 현재 부트 클래스 경로 앞에 추가합니다.

bootclasspath 옵션을 사용하여 Java 클래스 (기타)를 대체하거나 무시할 때 기술적으로 Java를 수정한다는 점에 유의하십시오. 코드를 배포 할 경우 라이센스 관련 사항이있을 수 있습니다 . (Java Binary License의 이용 약관을 참조하고 변호사와 상담하십시오.)



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow