빈 디렉터리에 아래와 같이 코드를 작성한다.
class Item{
}
class ClasspathDemo {
}
컴파일을 한다.
javac ClasspathDemo.java
그 결과 두 개의 클래스 파일이 생성된다.
즉 클래스 하나는 하나의 클래스 파일이 된다는 것을 알 수 있다.
클래스의 경로
아래와 같이 코드를 고쳐보자.
class Item{
public void print(){
System.out.println("Hello world");
}
}
class ClasspathDemo {
public static void main(String[] args){
Item item = new Item();
item.print();
}
}
그리고 현재 디렉터리 하위에 lib을 만들고 여기에 Item.class 파일을 이동한다. 그리고 ClasspathDemo를 실행한다.
D:\Java\exam>java ClasspathDemo
Exception in thread "main" java.lang.NoClassDefFoundError: Item
at ClasspathDemo2.main(ClasspathDemo.java:9)
Caused by: java.lang.ClassNotFoundException: Item
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
이것은 item.class 파일이 현재 디렉터리에 존재하지 않기 때문에 찾을 수 없다는 메시지다. 아래와 같이 실행해서 이 문제를 해결할 수 있다.
java -classpath ".;lib" ClasspathDemo
리눅스, OSX와 같은 유닉스 계열의 시스템이라면 구분자로 콜론을 사용해야 한다.
옵션 -classpath는 자바를 실행할 때 사용할 클래스들의 위치를 가상머신에게 알려주는 역할을 한다. .
. : 현재 디렉터리에서 클래스를 찾는다는 뜻이다.
; : 경로와 경로를 구분해주는 구분자
lib : 현재 디렉터리에 없다면 현재 디렉터리의 하위 디렉터리 중 lib에서 클래스를 찾는다는 의미다.
만약 .을 제외한다면 어떻게 될까? 아래와 같은 오류가 발생할 것이다.
오류: 기본 클래스 Classpath을(를) 찾거나 로드할 수 없습니다.
디렉터리 lib 아래에 있는 Item.class 파일을 찾았는데 정작 현재 디렉터리에 있는 ClasspathDemo.class 파일은 찾을 수 없기 때문이다.
이와 같이 클래스 패스라는 것은 자바를 실행할 때 클래스의 위치를 지정하는 역할을 하는 것이다. 클래스 패스는 자바 애플리케이션이 사용하고 있는 클래스가 여러 경로에 분산되어 있을 때 유용하게 사용할 수 있는 방법이다.
실행 할 때마다 클래스 패스를 지정하는 것이 귀찮다면 클래스 패스를 시스템의 환경변수로 지정하면 된다.
환경변수
환경변수는 운영체제에 지정하는 변수로 자바 가상머신과 같은 애플리케이션들은 환경변수의 값을 참고해서 동작하게 된다. 자바는 클래스 패스로 환경변수 CLASSPATH를 사용하는데 이 값을 지정하면 실행할 때마다 -classpath 옵션을 사용하지 않아도 되기 때문에 편리하다.
동시대적 감수성
필자는 상수, 변수, 연산자, 조건문, 반복문을 가장 기본적인 프로그래밍의 수단이라고 생각한다. 다시 말해서 로직 자체라고 생각 할 수 있다. 반면에 메소드, 유효범위, 클래스, 클래스 패스와 같은 것들을 관통하는 공통분모는 로직의 체계적인 관리수단이라고 할 수 있다. 로직 자체는 간단하다. 하지만, 이 로직을 체계적으로 관리하기 위한 수단들은 많고 복잡하다. 프로그래밍이 이러한 복잡성을 감수하고 있는 것은 로직의 체계적 관리가 그만큼 중요한 문제라는 반증일 수도 있다. 그 중요성을 이해한다면 이러한 수단들이 단지 공부거리가 아니라 개발을 쾌적하게 도와주는 매우 유용한 도구라는 것을 이해할 수 있을 것이다.