자바 팁 105 : JWhich로 클래스 경로 마스터하기

때때로 개발자는 Java 클래스 경로를 처리 할 때 좌절감을 경험합니다. 특히 애플리케이션의 클래스 경로가 디렉토리와 파일로 넘쳐나는 경우 클래스 로더가로드 할 클래스가 항상 명확하지는 않습니다. 이 기사에서는로드 된 클래스 파일의 절대 경로 이름을 표시 할 수있는 도구를 제공합니다.

Classpath 기본 사항

JVM (Java Virtual Machine)은 필요에 따라 애플리케이션에서 사용하는 클래스를로드하기 위해 클래스 로더를 사용합니다. CLASSPATH환경 변수 어디 타사 및 사용자 정의 클래스를 찾기 위해 클래스 로더를 알려줍니다. 환경 변수에 -classpath지정된 클래스 경로를 재정의하는 JVM 명령 줄 인수를 사용하여 응용 프로그램별로 클래스 경로를 지정할 수도 있습니다 CLASSPATH.

클래스 경로 항목은 패키지에없는 클래스의 클래스 파일을 포함하는 디렉토리, 패키지의 클래스에 대한 패키지 루트 디렉토리 또는 클래스를 포함하는 아카이브 파일 (예 : .zip 또는 .jar 파일) 일 수 있습니다. 클래스 경로 항목은 Unix 유형 시스템에서는 콜론으로 구분되고 MS Windows 시스템에서는 세미콜론으로 구분됩니다.

클래스 로더는 위임 계층 구조로 구성되며 각 클래스 로더에는 상위 클래스 로더가 있습니다. 클래스 로더가 클래스를 찾도록 요청 받으면 클래스 자체를 찾으려고 시도하기 전에 먼저 요청을 상위 클래스 로더에 위임합니다. 시스템에 설치된 JDK 또는 JRE에서 제공하는 기본 클래스 로더 인 시스템 클래스 로더는 CLASSPATH환경 변수 또는 -classpathJVM 명령 줄 인수를 사용하여 타사 및 사용자 정의 클래스를로드합니다 . 시스템 클래스 로더는 Java 확장 메커니즘을 사용하는 클래스를로드하도록 확장 클래스에 위임합니다. 확장 클래스 로더는 핵심 JDK 클래스를로드하기 위해 부트 스트랩 클래스 로더 (벅은 여기서 멈 춥니 다!)에 위임합니다.

JVM이 클래스를 동적으로로드하는 방법을 사용자 정의하기 위해 특수 클래스 로더를 개발할 수 있습니다. 예를 들어, 대부분의 서블릿 엔진은 사용자 정의 클래스 로더를 사용하여 사용자 정의 클래스 경로에 지정된 디렉토리에서 변경된 서블릿 클래스를 동적으로 다시로드합니다.

특히 중요하고 당황스럽게도 클래스 로더는 클래스 경로에 나타나는 순서대로 클래스를로드합니다. 첫 번째 클래스 경로 항목부터 클래스 로더는로드 할 클래스를 찾으려고 시도하는 각 지정된 디렉토리 또는 아카이브 파일을 방문합니다. 적절한 이름으로 찾은 첫 번째 클래스가로드되고 나머지 클래스 경로 항목은 무시됩니다.

간단 해 보이죠?

Classpath 속임수

그들이 그것을 인정하든 그렇지 않든, 초보자와 베테랑 Java 개발자 모두 어느 시점에서 (보통 최악의 순간에!) 번거로운 클래스 경로에 속았습니다. 응용 프로그램에 대해 종속 된 타사 및 사용자 정의 클래스의 수가 증가하고 클래스 경로가 모든 가능한 디렉토리 및 아카이브 파일에 대한 덤프 장소가됨에 따라 클래스 로더가 먼저로드 할 클래스가 항상 명확하지는 않습니다. 이것은 특히 클래스 경로에 중복 된 클래스 항목이 포함되어있는 불행한 경우에 해당됩니다. 클래스 로더는 클래스 경로에서 찾은 첫 번째 적절하게 명명 된 클래스를로드하고 우선 순위가 낮은 적절하게 명명 된 다른 모든 클래스를 효과적으로 "숨 깁니다".

이 클래스 패스 속임수에 희생 되기는 너무 쉽습니다. 핫 키보드로 긴 하루를 보낸 후, 클래스의 다른 버전이 클래스 경로에서 더 높은 우선 순위. 잡았다!

JWhich : 간단한 클래스 경로 도구

플랫 경로 선언에 내재 된 우선 순위 문제는 Java 클래스 경로에 고유하지 않습니다. 문제에 대한 해결책을 찾으려면 전설적인 소프트웨어 거인의 어깨에 서기 만하면됩니다. Unix 운영 체제의 which명령은 이름을 취하고 이름이 명령으로 발행 된 경우 실행될 파일의 ​​경로 이름을 표시합니다. 기본적으로 PATH환경 변수를 탐색 하여 명령의 첫 번째 발생을 찾습니다. 이는 Java 클래스 경로를 관리하기위한 강력한 도구처럼 들립니다. 그 개념에 영감을 받아 Java 클래스 이름을 취하고 클래스 경로에 규정 된대로 클래스 로더가로드 할 클래스 파일의 절대 경로 이름을 표시 할 수있는 Java 유틸리티를 작성하는 방법을 설정했습니다.

다음 예제 사용은 디렉토리에있는 클래스 로더에 의해로드 될 클래스 JWhich의 첫 번째 발생의 절대 경로 이름 을 표시합니다 com.clarkware.ejb.ShoppingCartBean.

 > java JWhich com.clarkware.ejb.ShoppingCartBean 클래스 'com.clarkware.ejb.ShoppingCartBean'이 '/home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class'에 있습니다. 

다음 예제 사용은 아카이브 파일에 패키지화되는 클래스 로더에 의해로드 될 클래스 JWhich의 첫 번째 발생의 절대 경로 이름 을 표시 javax.servlet.http.HttpServlet합니다.

 > java JWhich javax.servlet.http.HttpServlet 클래스 'javax.servlet.http.HttpServlet'이 'file : /home/mclark/lib/servlet.jar! /javax/servlet/http/HttpServlet.class'에 있습니다. 

JWhich의 작동 원리

클래스 경로에서 먼저로드 될 클래스를 명확하게 결정하려면 클래스 로더에 대해 이해해야합니다. 이것은 들리는 것만 큼 어렵지 않습니다. 그냥 물어보세요! 관련 소스 코드는 JWhich다음과 같습니다. 전체 소스 코드는 리소스를 참조하세요.

1 : public class JWhich {2 : 3 : / ** 4 : * 클래스 파일의 절대 경로 이름을 인쇄합니다. 5 : * 지정된 클래스 이름을 포함합니다. 6 : * 현재 클래스 경로에 의해 규정 됨. 7 : * 8 : * @param className 클래스 이름. 9 : * / 10 : public static void which (String className) {11 : 12 : if (! className.startsWith ( "/")) {13 : className = "/"+ className; 14 :} 15 : className = className.replace ( '.', '/'); 16 : className = className + ".class"; 17:18 : java.net.URL classUrl = 19 : new JWhich (). getClass (). getResource (className); 20 : 21 : if (classUrl! = null) {22 : System.out.println ( "\ nClass '"+ className + 23 : "'에서 \ n '"+ classUrl.getFile () + "'"); 24 :} else {25 : System.out.println ( "\ nClass '"+ className + 26 : "'을 (를) \ n '에서 찾을 수 없습니다."+ 27 : System.getProperty ("java.class.path ") +" ' "); 28 :} 29 :} 30 : 31 : public static void main (String args []) {32 : if (args.length > 0) {33 : JWhich.which (args [0]); 34 :} else {35 : System.err.println ( "사용법 : java JWhich"); 36 :} 37 :} 38 :}

먼저, 클래스 로더 승인을 얻기 위해 클래스 이름을 약간 마사지해야합니다 (12-16 행). 클래스 이름 앞에 "/"를 추가하면 호출하는 클래스의 패키지 이름을 암시 적으로 앞에 추가하지 않고 클래스 경로 내에서 그대로 클래스 이름과 일치하도록 클래스 로더에 지시합니다. "."의 각 항목을 변환합니다. "/"는 클래스 이름을 클래스 로더에 필요한 유효한 URL 리소스 이름으로 형식화합니다.

다음으로, 클래스 로더는 적절하게 형식화 된 클래스 이름과 일치하는 리소스를 조사합니다 (18-19 행). 모든 Class객체는 자신 ClassLoader을로드 한 객체에 대한 참조를 유지 하므로 JWhich클래스 자체 를로드 한 클래스 로더가 여기에서 조사됩니다. 이 Class.getResource()메서드는 실제로 클래스를로드 한 클래스 로더에 위임하여 클래스 파일 리소스를 읽기위한 URL을 반환하거나 null지정된 클래스 이름을 가진 클래스 파일 리소스를 현재 클래스 경로에서 찾을 수없는 경우입니다.

마지막으로, 지정된 클래스 이름이 포함 된 클래스 파일의 절대 경로 이름이 현재 클래스 경로에서 발견되면 표시됩니다 (21-24 행). 디버깅을 돕기 위해 현재 클래스 경로에서 클래스 파일을 찾을 수없는 경우 java.class.path시스템 속성 값을 가져와 현재 클래스 경로를 표시합니다 (24 ~ 28 행).

서블릿 엔진의 클래스 경로를 사용하거나 EJB 서버의 클래스 경로를 사용하는 EJB (Enterprise JavaBean)를 사용하여 Java 서블릿에서이 간단한 코드 덩어리를 호출하는 방법을 쉽게 상상할 수 있습니다. 경우 JWhich클래스가 서블릿 엔진에서 사용자 정의 클래스 로더에 의해로드 된, 예를 들어, 다음 서블릿 엔진의 클래스 로더는 클래스를 찾는 데 사용됩니다. 서블릿 엔진의 클래스 로더가 클래스를 찾을 수없는 경우 상위 클래스 로더에 위임합니다. 일반적으로 JWhich클래스 로더에 의해로드되면 해당 클래스 로더 또는 상위 클래스 로더에 의해로드 된 모든 클래스를 찾을 수 있습니다.

결론

필요가 모든 발명의 어머니라면, Java 클래스 경로를 관리하는 데 도움이되는 도구는 오래전입니다. Java 관련 뉴스 그룹과 메일 링 목록은 클래스 경로와 관련된 질문으로 가득 차 있습니다. 우리는 모두 더 높은 수준의 추상화에서 계속 작업 할 수 있도록 새로운 개발자의 진입 장벽을 낮춰야합니다. JWhich어떤 환경에서도 Java 클래스 경로를 마스터하는 데 도움이되는 간단하면서도 강력한 도구입니다.

Mike Clark은 Clarkware Consulting의 독립 컨설턴트로 J2EE 기술을 사용한 Java 기반 아키텍처, 설계 및 개발을 전문으로합니다. 그는 최근에 B2B (Business-to-Business) XML 교환 서버의 개발 및 배포를 완료했으며 현재 J2EE 성능 관리 제품을 구축하는 프로젝트의 컨설턴트입니다.

이 주제에 대해 더 알아보기

  • Obtain the full source code for this article

    //images.techhive.com/downloads/idge/imported/article/jvw/2000/12/jwhich.zip

  • A full-featured version of JWhich, including a classpath validator, is available at

    //www.clarkware.com/software/jwhich.zip

  • Official documentation for the Sun JDK and how it deals with the classpath for the various officially supported platforms is available at

    //java.sun.com/j2se/1.3/docs/tooldocs/findingclasses.html

  • For details on how to set the classpath on Unix and Windows platforms, see "Setting the classpath" at:
  • Unix

    //java.sun.com/j2se/1.3/docs/tooldocs/solaris/classpath.html

  • Windows

    //java.sun.com/j2se/1.3/docs/tooldocs/win32/classpath.html

  • View all previous Java Tips and submit your own

    //www.javaworld.com/javatips/jw-javatips.index.html

  • 더 많은 Java 트릭을 보려면 ITworld.com의 무료 Java Tutor 뉴스 레터를 구독하십시오.

    //www.itworld.com/cgi-bin/subcontent12.cgi

  • JavaWorld 작성자 Geoff Friesen이 진행하는 Java Beginner 토론에서 의견을 나눕니다.

    //www.itworld.com/jump/jw-javatip105/forums.itworld.com/[email protected]@.ee6b804/1195!skip=1125

이 스토리 "Java Tip 105 : JWhich로 클래스 경로 마스터하기"는 원래 JavaWorld에서 게시했습니다.