2008-09-26 1 views
27

나는 방금 라이브러리의 다른 버전을 사용했지만, my-app-server-has-already-loaded-이 - 이전 버전의 -이 라이브러리 - * 문제 (한숨).클래스 로더 문제 - 어떤 라이브러리 버전 (jar 파일)이로드되는지 확인하는 방법

응용 프로그램이 모든 적절한 jar 파일 또는로드 된 클래스 버전에 액세스 할 수 있는지 여부를 확인 (또는 모니터링)하는 훌륭한 방법을 아는 사람이 있습니까?

미리 감사드립니다.

[P.S. ! 아주 좋은 이유는] 내보기에서 OSGi module architecture를 사용하려면

업데이트 : This 문서뿐만 아니라 도움이! 그것은 JBoss의 클래스 로더가 로그 파일에 그것을 써서로드 한 클래스에 대한 통찰력을주었습니다.

답변

18

JBoss를 사용하는 경우 특정 클래스를로드 한 모든 클래스 로더를 요청할 수있는 MBean (클래스 로더 저장소 iirc)이 있습니다.

다른 모든 것이 실패하면 항상로드되는 모든 클래스 파일에 대해 jar의 위치를 ​​인쇄하는 'java -verbose : class'가 있습니다.

+0

내가 톰을 사용할 수있는 것과 같은 소리가납니다! 나는 내일 그것에 파고들 것이다. 미리 감사드립니다 .... Johan –

2

나는 그것을 확인하는 좋은 방법이 없다고 생각합니다. 그리고 나는 당신이 그것을하고 싶어하는지 확신하지 못합니다. 애플리케이션 서버의 클래스 로딩 아키텍처에 익숙해지고 그것이 어떻게 작동하는지 이해해야합니다.

작동 원리에 대한 간략한 설명 : EJB 또는 웹 응용 프로그램은 먼저 자체 모듈 (ejb-jar 또는 war)에 선언 된 라이브러리에서 클래스 또는 자원을 찾습니다. 클래스가 없으면 클래스 로더는 선언 된 종속성 (보통 ejb) 또는 ear 패키지에 선언 된 라이브러리 및 리소스를로드하는 응용 프로그램 클래스 로더 인 해당 상위 클래스 로더에 요청을 전달합니다 . 클래스 또는 자원이 여전히 발견되지 않으면 요청은 자체 클래스 경로에서 볼 응용 프로그램 서버로 전달됩니다.

Java EE 모듈 (web-app, ejb)은 항상 가장 가까운 범위에있는 jar에서 클래스를로드한다는 것을 기억해야합니다. 예를 들어 log4j v1을 war 파일에 log4j v2를 ear 레벨로 패키지하고 log4j v3를 app-server 클래스 경로에 넣으면 모듈은 자체 모듈에서 jar를 사용합니다. 그걸 가져 가면 귀에 걸리게됩니다. 그것을 가져 오면 앱 - 서버의 클래스 패스에있는 것을 사용할 것입니다. 모듈간에 복잡한 종속성이있을 때 상황이 더욱 까다로워집니다.

귀중한 수준으로 애플리케이션 글로벌 라이브러리를 배치하는 것이 가장 좋습니다.

+0

적어도 JBoss의 경우 간단하지 않습니다. 경우에 따라 JBoss는 클래스가 WAR 파일 내에 * 존재하더라도 WAR 파일 (예 : server/default/lib)의 * 외부 * 클래스를로드합니다. 범위가 지정된 로딩이 활성화되었는지 (JBoss 버전간에 기본값이 다름)와 부모 클래스 리포지토리에 대한 위임이 활성화되었는지 여부와 같은 다양한 요소에 따라 다릅니다. –

0

내가하는 방식보다 더 나은 방법이 있어야하지만, 나는 이것을 매우 수동적 인 방식으로하는 경향이있다.

  1. 모든 Jar 파일 이름에 버전 번호가 있어야합니다 (이름이 변경되지 않은 경우).
  2. 각 응용 프로그램에는 고유 한 클래스 경로가 있습니다.
  3. 업데이트 된 Jar (새 버전)를 사용해야하는 이유가 있어야합니다. 사용할 수 있기 때문에 변경하지 마십시오. 필요한 기능을 제공하므로 변경하십시오.
  4. 각 릴리스에는 필요한 모든 JAR이 포함되어야합니다.
  5. 필요로하는 Jars 목록을 알고있는 Version 클래스를 유지합니다 (이 파일은 소스 파일에 코딩되어 있습니다). 런타임에 classpath에있는 Jar 목록과 대조하여 확인할 수 있습니다.

내가 말했듯이 그것은 수동이지만 작동합니다.

3

현재 버전의 Java에서 라이브러리 버전 관리는 JAR이 유용한 목록과 함께 올바르게 패키징되는 것에 의존하는 다소 난감한 용어입니다. 그럼에도 불구하고 실행중인 응용 프로그램이이 정보를 유용한 방식으로 함께 수집하는 작업이 많습니다.JVm 런타임은 당신에게 아무런 도움을주지 않습니다.

나는 최선의 방법은 빌드 타임에 Ivy 나 Maven과 같은 의존성 관리 도구를 사용하여 모든 것을 올바른 버전으로 가져 오는 것입니다.

흥미롭게도 Java 7에는 이러한 종류의 모듈을위한 적절한 모듈 버전 관리 프레임 워크가 포함될 가능성이 높습니다. 이 순간에 바로 도움이되지 않습니다.

5

jar 매니페스트에 적절한 버전 정보가있는 경우 버전을 검색하고 테스트하는 방법이 있습니다. 매니 페스트를 수동으로 읽을 필요가 없습니다.

java.lang.Package.getImplementationVersion() 및 getSpecificationVersion() 및 isCompatibleWith()는 사용자가 원하는 것을 수행하는 것처럼 들립니다.

this.getClass(). getPackage()를 사용하여 다른 방법으로 패키지를 가져올 수 있습니다.

java.lang.Package 용 javadoc는 이러한 속성에 대한 특정 매니페스트 속성 이름을 제공하지 않습니다. 빠른 google 검색을 사용하면 다음과 같이 표시됩니다. http://java.sun.com/docs/books/tutorial/deployment/jar/packageman.html