Java

클래스 패스

본 수업에서는 IDE(eclipse, intellij)를 사용하지 않고 운영체제의 기본 에디터를 사용 한다.

클래스 패스

빈 디렉터리에 아래와 같이 코드를 작성한다. 필자는 프로젝트 디렉토리에 /srcbin 이라는 디렉토리를 만들고 여기에서 실습을 진행할 것이다. 아래 예제의 파일명은 ClasspathDemo.java 이다. 

class Item{
}

class ClasspathDemo {
}

컴파일을 한다.

javac ClasspathDemo.java

그 결과 두 개의 클래스 파일이 생성된다.

  • ClasspathDemo.class
  • Item.class

즉 클래스 하나는 하나의 클래스 파일이 된다는 것을 알 수 있다.

클래스의 경로

ClasspathDemo2.java을 만들고 내용을 아래와 같이 한다.

class Item2{
    public void print(){
		System.out.println("Hello world");	
	}
}

class ClasspathDemo2 {
	public static void main(String[] args){
		Item2 i1 = new Item2();
		i1.print();
	}
}

컴파일을 한다.

javac ClasspathDemo2.java

그리고 현재 디렉터리 하위에 lib을 만들고 여기에 Item2.class 파일을 이동한다. 현재 디렉터리에는 Item2.class 파일이 없어야 한다. 그리고 ClasspathDemo2를 실행한다.

java ClasspathDemo2

아래와 같은 결과가 출력된다.

F:\dropbox\생활코딩\실습\java_tutorials\srcbin>java ClasspathDemo2
Exception in thread "main" java.lang.NoClassDefFoundError: Item2
        at ClasspathDemo2.main(ClasspathDemo2.java:9)
Caused by: java.lang.ClassNotFoundException: Item2
        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" ClasspathDemo2
리눅스, OSX와 같은 유닉스 계열의 시스템이라면 아래와 같이 콜론을 사용해야 한다.
java -classpath ".:lib" ClasspathDemo2

옵션 -classpath는 자바를 실행할 때 사용할 클래스들의 위치를 가상머신에게 알려주는 역할을 한다. -classpath의 값으로 사용된 ".;lib"를 살펴보자.

.

현재 디렉터리에서 클래스를 찾는다는 뜻이다.

;

경로와 경로를 구분해주는 구분자

lib

현재 디렉터리에 없다면 현재 디렉터리의 하위 디렉터리 중 lib에서 클래스를 찾는다는 의미다.

만약 .을 제외한다면 어떻게 될까? 아래와 같은 오류가 발생할 것이다.

F:\tmp\java>java -classpath "lib" ClasspathDemo
오류: 기본 클래스 Classpath을(를) 찾거나 로드할 수 없습니다.

디렉터리 lib 아래에 있는 Item.class 파일을 찾았는데 정작 현재 디렉터리에 있는 ClasspathDemo.class 파일은 찾을 수 없기 때문이다.

이와 같이  클래스 패스라는 것은 자바를 실행할 때 클래스의 위치를 지정하는 역할을 하는 것이다. 클래스 패스는 자바 애플리케이션이 사용하고 있는 클래스가 여러 경로에 분산되어 있을 때 유용하게 사용할 수 있는 방법이다.

지금까지는 자바를 실행할 때 클래스 패스를 지정하는 방법을 알아봤다. 실행 할 때마다 클래스 패스를 지정하는 것이 귀찮다면 클래스 패스를 시스템의 환경변수로 지정하면 된다.

환경변수

환경변수는 운영체제에 지정하는 변수로 자바 가상머신과 같은 애플리케이션들은 환경변수의 값을 참고해서 동작하게 된다. 자바는 클래스 패스로 환경변수 CLASSPATH를 사용하는데 이 값을 지정하면 실행할 때마다 -classpath 옵션을 사용하지 않아도 되기 때문에 편리하다. 하지만 운영체제를 변경하면 클래스 패스가 사라지기 때문에 이식성면에서 불리할 수 있다.

운영체제 별로 환경변수를 설정하는 방법은 자바를 설치하는 방법에서 다루기 때문에 이것을 참고하자.

동시대적 감수성

필자는 상수, 변수, 연산자, 조건문, 반복문을 가장 기본적인 프로그래밍의 수단이라고 생각한다. 다시 말해서 로직 자체라고 생각 할 수 있다. 반면에 메소드, 유효범위, 클래스, 클래스 패스와 같은 것들을 관통하는 공통분모는 로직의 체계적인 관리수단이라고 할 수 있다. 로직 자체는 간단하다. 하지만, 이 로직을 체계적으로 관리하기 위한 수단들은 많다. 복잡하다. 프로그래밍이 이러한 복잡성을 감수하고 있는 것은 로직의 체계적 관리가 그만큼 중요한 문제라는 반증일 수도 있다. 그 중요성을 이해한다면 이러한 수단들이 단지 공부거리가 아니라 개발을 쾌적하게 도와주는 매우 유용한 도구라는 것을 이해할 수 있을 것이다.

만약 여러분이 프로그래밍의 초창기부터 개발을 했다면 이러한 도구들의 등장이 마치 게임의 아이템을 획득한 것처럼 즐거운 일이었을 것이다. 그 느낌을 그대로 느끼는 것은 어렵겠지만, 이러한 기능이 등장하게 된 시대에 있다고 상상해본다면 공부가 좀 더 흥미롭게 느껴지지 않을까?

다음 챕터에서는 클래스 패스와 함께 거론될 수 밖에 없는 개념인 패키지라는 것을 알아본다.

댓글

댓글 본문
작성자
비밀번호
  1. 로직의 체계적인 관리 도구의 발전에 대해 동시대적 감수성이란 타이틀로 풀어내시는것에 감동받았습니다.
  2. 송선욱
    ClasspathDemo2.java 컴파일시 소스코드를 분명 똑같이 적었는데 왜 이런 에러가 뜨는걸까요?????

    Seonuk-ui-MacBook-Air:srcbin Song$ javac ClasspathDemo2.java
    ClasspathDemo2.java:3: error: illegal character: '\u201c'
    System.out.println(“Hello world”);
    ^
    ClasspathDemo2.java:3: error: ';' expected
    System.out.println(“Hello world”);
    ^
    ClasspathDemo2.java:3: error: illegal character: '\u201d'
    System.out.println(“Hello world”);
    ^
    ClasspathDemo2.java:3: error: not a statement
    System.out.println(“Hello world”);
  3. 지나가던 공고생
    정말 좋은 강의였습니다 화이팅하세요.
  4. Jay Jaewoong Kang
    감사합니다.
  5. JustStudy
    고맙습니다
  6. whatislife91@naver.com
    강의 클라스 지리구요...
  7. 김트라슈
    잘 봤습니다
  8. 감사합니당
  9. 찐똥구리구리
    수업 감사합니다.

    제가 java파일이름과 class파일 이름이 다른 걸 모르고 엄청 고생해서 혹시나해서 남겨둡니다.
    ---------------------------------------------------------------------------------------------------------------------------------------
    java파일의 class이름이 달라진걸 모르고, 계속해서 main class를 찾을 수 없다는 에러만 연발해서 환장하는 줄 알았습니다.

    이클립스였다면 미리 에러를 보였겠지만, textedit으로 하다보니 캐치하지 못한 대소문자의 다름(ClassPathDemo ≠ClasspathDemo)
    여하튼 javac를 통해 컴파일한 class파일이름이 다르다면, 그 다른 이름을 java명령으로 부르니 정상작동은 된다. 우선 컴파일 되면, java파일은 자바머쉰에겐 뒤전이 되나보다. 그래서, 컴파일한 이후에는 이름이 다르다고 java파일 수정해도 소용이 없었다.

    삽질기념으로 남겨둔다.
    -----------------------------------------------------------------------------------------------------------------------------------
    사진 참고하세요. http://d.pr/i/iWwv+
    화이팅합니다~~!!!!
  10. 레니타키
    감사합니다
  11. 오빠는다르다
    감사합니다!!!
  12. 재밌습니다
  13. 위에보면, 만들었다고 적어놓으셨네요 ㅋㅋ
    대화보기
    • 파닥
      만들면됩니다 ㅠㅠ
    • panda_90
      저도...ㅜㅜ
      대화보기
      • 변진규
        저는 왜 srcbin이라는 폴더 자체가 없을까요?
      • 박첩구드
        감사합니다~!!
      • Byunghawk Lee
        흠...여기서 복잡하다고 느낀 것에 대한 답을 찾은 것 같습니다.
        감사합니다.
      • 초보
        이클립스로 컴파일한 클래스 파일을 cmd로 실행했을때 문제가 없게하려면
        폴더 맞추는건 기본으로 해주시고
        ClasspathDemo2.java 파일열으시면

        class Item2{
        public void print(){
        System.out.println("Hello world");
        }
        }

        class ClasspathDemo2 {
        public static void main(String[] args) {
        Item2 i1 = new Item2();
        i1.print();
        }
        }
        소스가 이렇게만있어야됩니다...
        저는 처음에 package Classpath; 이게 있어서 이걸 지워버렸더니 이상없이 실행 되었습니다!!

        소스에서 오류가 있을경우에도 기본 클래스를 찾거나 로드할 수 없습니다라고 나오네요
      • 가리바우
        저도 이런 결과가 나오는데 어떻게 해야하나요??? cmd java 명령어실행시 디렉토리는 당연히 bin폴더로 했고 dir로 class 파일 이름도 확인했습니다.
        대화보기
        • 지나가는 이
          Akinaro님, 4개월 전에 세미콜론(;)에 대해서 얘기하셨는데
          커맨드 창에서 java 적고 엔터 치면

          C:\>java
          사용법: java [-options] class [args...]
          (클래스 실행)
          또는 java [-options] -jar jarfile [args...]
          (jar 파일 실행)
          여기서 options는 다음과 같습니다.
          .
          [중간 생략]
          .
          -classpath <디렉토리 및 zip/jar 파일의 클래스 검색 경로>
          클래스 파일을 검색할 ;(으)로 구분된 디렉토리,
          JAR 아카이브 및 ZIP 아카이브 목록입니다.
          .
          [이후 생략]
          .
          이렇게 -clsspath에 대한 설명이 나옵니다.
          세미콜론은 여기 적힌 것과 같이
          여러개의 경로를 적을 때 구분을 위해 적는 문자일 뿐이라서
          영상에서처럼 세미콜론을 같이 지우든, 남겨두든
          별 상관은 없는 듯 합니다.
          .
          실제로 제가 지금 시험해보니 쓸데없는 세미콜론을 20개쯤 덤으로 붙여도
          프로그램 실행에는 아무런 영향이 없습니다.
        • 강아지
          위에서 하시는 거랑 똑같이 했는데 기본 클래스 ClasspathDemo2를 찾거나 로드할 수 없다고 나옵니다.;;;
          도데체 무엇이 잘못됬는지.. 모르겠네요 .

          아래 글 보니까 으아아악 님하고 똑같은 현상 같은데..;; 뭐가 잘못된거죠 ?
        • Akinaro
          저도 그런적 있는데 재부팅 하니깐 되더군요..ㅋㅋ
          대화보기
          • Akinaro
            2번째 영상에서 점만 콕찝어서 지우신다고 말씀하시고 세미콜론도 같이 지우시네요
            점만 지우고 -classpath ";lib"해도 정상적으로 Helloworld가 출력 이되구요..
            이때는 왜 잘되는지 궁금합니다.
            그리고 2번째영상 마지막부분에 -classpath"." 해도 정상적으로된다고 하시는데
            "." , "" , ";" 요것도 다 잘되는데 차이점을 알고싶네요.
          • 강좌를첨부터들으세요
            이클립스에서 컴파일한 class 파일은 bin 폴더에 저장되기 때문입니다.
            대화보기
            • 으아아악
              이클립스로 컴파일한 클래스 파일은 cmd로 실행하면 계속 기본 클래스를 찾을 수 없다고 합니다. 어떤 문제가 있는걸까요?
            • 한사람
              기본 클래스 이름과 java파일 저장명은 동일해야 가능합니다~
            • jeaross
              기본 클래스 이름과 java 파일 이름은 항상 같게 해줘야 하나요? 같게하면 실행되고 다르게하면
              실행이 되질 않네요ㅠ
            • jaballet
              환경변수 경로 지정할 때마다 '왜 해야 하는거지?'라는 의문이 항상 들었는데 드디어 그 이유를 알게되었네요.
              재밌게 알려주셔서, 너무 너무 감사합니다.. ^^
            • 신천지
              와~ 오늘부터 자바가 더 재밌어졌어요......
              감사~ 감격! 또. 감사합니다. 꾸벅~_ _
            • Haewon Lee
              오호 정말 그렇네요.

              java -classpath ".;lib;rib" ClasspathDemo2

              하니까 두개의 디렉토리 에서 ClasspathDemo2.class를 먼저 검색하고 ClasspathDemo2.class 를 실행하기 위한 Item2.class 를 검색 하는군요.
              2개뿐만 아니라 더 늘려 갈 수도 있겠네요.
              대화보기
              • 도와주세요
                이고잉님 갑자기 이클립스가 안열립니다 도와주세요 ㅠ
                누르면 그 보라색 문구 있는거 뜨고 로딩되는것처럼 하더니 갑자기 사라지고
                프로세스창에도 보면 없어요 흑.. 그래서 지우고 압축풀고 다시깔면 되는데
                디렉토리를 원래쓰던 디렉토리로 설정하면 똑같은 현상이일어납니다 ㅠ..
              • YOUNG
                궁금해서 찾아봤는데 클래스패스를 두 개 이상 추가할 경우,

                그러니까 아래의 두 디렉토리에 있는 클래스들을 사용할 때는
                ..../first_depth
                ..../first_depth/second_depth

                java -classpath ".:first_depth:first_depth/second:depth" Filename

                이고잉님 정말 좋은 강의 감사합니다! :D
              • 강민구
                네. 윈도우는 ; 리눅스는 : 입니다.
                대화보기
                • egoing
                  아 그랬군요. 수정했습니다. ^^
                  대화보기
                  • charlie
                    안녕하세요. 실습을 해보니 Path 구분자가 ";" 아니고 ":"일때 동작합니다.
                    저는 맥에서 공부중인데 혹시 윈도우하고 구분자가 다른가요?
                  • 감사
                    혼동되는 개념인데, 정말 쉽게 설명해주셨어요
                  • kimjun
                    이해하기 쉽게 설명해주셔서 기본 다지는데 도움이 됐습니다.
                  버전 관리
                  egoing
                  현재 버전
                  선택 버전
                  graphittie 자세히 보기