경주장
7주차 과제: 패키지 #7 클래스패스 (~02.30) 본문
✔️ 학습할 것 (필수)
+ 패키지란?
package 키워드import 키워드클래스패스CLASSPATH 환경변수-classpath 옵션접근지시자
클래스패스란?
Def) Classpath
ClassPath is a parameter in JVM or the Java compiler that specifies the location of user-defined classes and packages. The parameter may be set either on the command-line,or through an enviroment variable
전통적인 Dynamic Loading의 특성과 유사하게, 자바 프로그램을 실행할때 JVM은 classes를 Lazy하게 find/load합니다. 즉, 클래스의 바이트코드를 클래스가 처음 사용될 때 load합니다. 이때 classpath 는 java에게 classes (바이트코드 바일)을 찾아야할 file system 상의 경로를 알려줍니다.
JVM은 아래와 같은 순서로 .class 파일을 찾고 로드합니다.
- bootstrap 클래스 - java.lang과 같은 모든 자바 코어 라이브러리의 클래스
- extention 클래스
- jar 파일에 정의 된 클래스
packages that are in the extension directory of the JRE or JDK, jre/lib/ext/ -- user-defined packages and libraries
@See Also) - 클래스 로더
저희는 평소에 IDE의 도움으로 클래스패스와 패키지의 경로에 대한 고민을 하지 않고 편하게 개발에 집중할 수 있습니다. 하지만 항상 이러한 도움을 받을 수 있는 것이 아니니 직접 자바 파일을 컴파일 하고 실행/배포 하는 법을 알아둔다면 장기적으로 큰 도움이 될 것입니다.
클래스 패스를 명시적으로 적용하는 예제를 살펴 보겠습니다.
세 개의 클래스를 가진 하나의 HelloWorld.java 파일을 컴파일 하면 세 개의 클래스 파일 (바이트 코드)이 생성됩니다.
.class 파일을 JVM에 올리고 실행하기 위해서는 java 명령어를 활용해야 합니다.
이때 Helloworld 클래스를 패키지를 고려하여 classpath를 지정해야합니다.
package week7_package.study.classpath;
JVM입장에서는 Classpath를 기준으로 위 패키지를 지닌 class 파일이
classpath:/week7_package/study/classpath 의 경로에 있기를 기대합니다.
따라서 classpath는 절대경로로 C:\Users\1\Desktop\java\live-study-assignment\live-study\src\main\java 로 정해져야합니다.
-classpath 옵션을 통해 클래스 패스를 지정하고 java 명령어로 자바 프로그램을 실행 할 수 있습니다.
이때 classes파일의 경로를 외부로 빼 봅시다!
바이트 코드를 외부로 빼고 같은 명령어를 실행하면
메인 클래스를 찾을 수 없고 그 이름은 week7_package.study.classpath.HelloWorld임을 알려줍니다. - ClassNotFoundException
src\main\java아래 패키지 경로인 week7_package\study\classpath\아래 .class 파일들이 없기 때문에
src\main\java는 더이상 클래스 패스로서 기능 하지 못합니다.
대신에 새롭게 이사한 클래스패스인 mytarget을 경로로 클래스 패스의 옵션에 넣어주면 정상적으로 클래스를 찾습니다.
이쯤에서 정리하는 classpath의 역할은 아래와 같습니다.
- JAR 파일 및
- 패키지 계층 구조의 최상위 경로의 집합입니다.
위의 예제을 통해 classpath가 패키지 계층 구조의 최상단임을 확인하였습니다.
이번에는 "집합"이라는 단어에 집중해 보겠습니다.
mytarget아래 3개의 클래스파일 중 SupportClass.class 파일을 잠깐 삭제하면 아래와 같은 에러가 발생합니다.
이제 SupportClass.class를 다른 classpath에 저장하고 두개의 클래스패스를 조합하여 자바 명령어로 실행해보겠습니다.
semi colon으로 여러개의 클래스패스를 옵션으로 전달 할 수 있습니다.
.jar 파일 에의해 로딩되는 extention 클래스들을 classpath에 전달하는 명령어를 살펴보겠습니다. 이번에는 인텔리제이 IDE의 도움을 받겠습니다.
간단하게 인텔리제이의 Run을 통해 HelloWolrd.main을 실행 하면 아래와 같은 명령어를 활용함을 알 수 있습니다.
//명령어 입니다.
"C:\Program Files\Java\jdk-11.0.12\bin\java.exe"
"-javaagent:
C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\lib\idea_rt.jar=4189:
C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\bin"
-Dfile.encoding=UTF-8
-classpath
C:\Users\1\Desktop\java-study\live-study-assignment\live-study\target\classes;
C:\Users\1\.m2\repository\org\kohsuke\github-api\1.301\github-api-1.301.jar;
C:\Users\1\.m2\repository\org\apache\commons\commons-lang3\3.9\commons-lang3-3.9.jar;
C:\Users\1\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.13.0\jackson-databind-2.13.0.jar;
C:\Users\1\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.13.0\jackson-annotations-2.13.0.jar;
C:\Users\1\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.13.0\jackson-core-2.13.0.jar;
C:\Users\1\.m2\repository\commons-io\commons-io\2.8.0\commons-io-2.8.0.jar
week7_package.study.classpath.HelloWorld
//실행결과 입니다.
HelloWorld.main
-classpath외 에도 -javaagent, -Dfile.encoding의 옵션을 자동으로 포함합니다.
classpath 부분을 살펴 보면 처음에는 user-defined package and libraries에 해당되는 클래스 파일을 모아놓는 경로인 target\classes가 있고 이후에는 여러 jar 파일들이 자동으로 추가되어 있음을 확인 할 수 있습니다.
이는 지난 과제를 수행하면서 pom.xml에 추가한 github-api에 대한 의존성 때문에 추가된 것입니다.
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>github-api</artifactId>
<version>1.301</version>
</dependency>
깃헙 API는 내부적으로 위의 jar 파일에 해당하는 dependency를 모두 가지고 있으며 Maven 빌드를 통해 jar파일의 형태로 pc에 다운로드 되어 Run할때는 자동으로 classpath로 추가됩니다.
다시한번 클래스 패스의 역할을 살펴보면 아래와 같습니다.
클래스 패스는
- JAR 파일 및
- 패키지 계층 구조의 최상위 경로의 집합입니다.
classpath는 옵션으로 전달하는 방법 외에도 환경 변수로 설정할 수 있습니다.
이부분에 대한 실습은 생략하겠습니다.
제 PC에는 현재 위와 같이 설정되어 있습니다. 혹시 저부분이 bootstrap class에 대한 classpath를 담당하는 것인지 확인해보기 위해 저 환경변수를 삭제하고 main함수의 인자인 String에 대한 ClassNotFoundException이 발생하기를 기대하며 HelloWorld.main을 실행해보았지만 정상적으로 출력되었습니다. 아마 jvm내부적으로 이미 bootstrap class에대한 classpath를 가지고 있는 것으로 추측됩니다. 혹시 잘 아시는 분은 댓글 부탁드립니다.
접근 제어자에 대한 학습은 5주차 클래스에서 학습한 내용으로 대체하겠습니다.
@See Also)
@출처)
'JAVA > whiteship_live-study' 카테고리의 다른 글
8주차 과제: 인터페이스 #8 상속, Default Method (~03.04) (0) | 2022.02.28 |
---|---|
8주차 과제: 인터페이스 #8 (~03.04) (0) | 2022.02.25 |
7주차 과제: 패키지 #7 package,import 키워드 (~02.30) (0) | 2022.02.24 |
7주차 과제: 패키지 #7 패키지란 (~02.30) (0) | 2022.02.23 |
6주차 과제: 상속 #6 (~02.29) - Object 클래스 (0) | 2022.02.23 |