programing

Java, Classpath, Classloading => 동일한 jar/프로젝트의 여러 버전

sourcetip 2023. 1. 30. 22:59
반응형

Java, Classpath, Classloading => 동일한 jar/프로젝트의 여러 버전

나는 이것이 숙련된 코드 작성자들에게 바보 같은 질문일 수도 있다는 것을 안다.그러나 프로젝트에서 사용하는 다른 프레임워크/자르 중 일부가 필요한 라이브러리(http 클라이언트)가 있습니다.그러나 모두 다음과 같은 다른 메이저 버전이 필요합니다.

httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar

클래스 로더가 그들을 어떻게든 분리할 수 있을 만큼 지능적인가요?아마 아닐까요?클래스가 3개의 모든 항아리에서 동일한 경우 Classloader는 이를 어떻게 처리합니까?어떤 것이 로딩되어 있고, 그 이유는 무엇입니까?

Classloader는 정확히 하나의 병만 픽업합니까, 아니면 임의로 클래스를 혼합합니까?예를 들어 Version-1.jar에서 클래스가 로드된 경우 동일한 클래스 로더에서 로드된 다른 모든 클래스는 동일한 jar에 들어갑니다.

당신은 이 문제를 어떻게 처리합니까?

어떤 방법으로든 병을 "required.jar"에 "인테그레이션"하여 가 "1개의 유닛/패키지"로 인식되도록 하기 위한 요령이 있습니까?Classloader아니면 어떤 식으로든 연결되었을까요?

클래스 로더 관련 문제는 매우 복잡한 문제입니다.어떤 경우에도 몇 가지 사실에 유의해야 합니다.

  • 일반적으로 응용 프로그램의 클래스로더는 여러 개입니다.부트스트랩클래스 로더는 적절한 에 위임합니다.새 클래스를 인스턴스화하면 보다 구체적인 클래스 로더가 호출됩니다.로드하려는 클래스에 대한 참조가 발견되지 않으면 부트스트랩클래스 로더에 도달할 때까지 부모에게 위임됩니다.로드하려는 클래스에 대한 참조가 발견되지 않으면 ClassNotFoundException이 표시됩니다.

  • 같은 바이너리 이름의 클래스가 2개 있고, 같은 클래스 로더로 검색할 수 있으며, 그 중 어느 것을 로드하고 있는지 알고 싶다면 특정 클래스 로더가 클래스 이름을 해결하려고 하는 방법만 검사할 수 있습니다.

  • 자바 언어 사양에 따르면 클래스 바이너리 이름에 고유성 제약은 없지만 내가 볼 때 클래스 로더마다 고유해야 합니다.

같은 바이너리 이름으로 2개의 클래스를 로드하는 방법을 찾을 수 있습니다.이 방법에서는 기본 동작을 우선하는2개의 다른 클래스 로더에 의해 로드(및 그 모든 의존관계)가 필요합니다.대략적인 예:

    ClassLoader loaderA = new MyClassLoader(libPathOne);
    ClassLoader loaderB = new MyClassLoader(libPathTwo);
    Object1 obj1 = loaderA.loadClass("first.class.binary.name", true)
    Object2 obj2 = loaderB.loadClass("second.class.binary.name", true);

클래스 로더의 커스터마이즈는 항상 까다로운 작업이라고 생각했습니다.가능하면 여러 개의 호환되지 않는 종속성을 피하는 것이 좋습니다.

각 클래스 로드는 정확히 하나의 클래스를 선택합니다.보통 처음 발견되죠

OSGi는 동일한 jar의 여러 버전의 문제를 해결하는 것을 목표로 합니다.Equinox Apache Felix는 OSGi의 일반적인 오픈 소스 구현입니다.

Classloader는 처음에 클래스 경로에 있었던 jar에서 클래스를 로드합니다.일반적으로 호환되지 않는 버전의 라이브러리는 패키지에 차이가 있지만, 실제로는 호환되지 않으므로 jarjar로 대체할 수 없습니다.

클래스 로더는 필요에 따라 클래스를 로드합니다.즉, 응용 프로그램 및 관련 라이브러리에서 먼저 필요한 클래스가 다른 클래스보다 먼저 로드됩니다. 종속 클래스 로드 요청은 일반적으로 종속 클래스의 로드 및 링크 프로세스 중에 실행됩니다.

경우는 흔히 볼 수치다.LinkageError는 클래스 로더에 대해 중복된 클래스 정의가 발생했음을 기술하고 있습니다(로더의 클래스 패스에 같은 이름의 클래스가 2개 이상 존재하는 경우). 일반적으로 어떤 클래스를 먼저 로드해야 하는지 판단하지 않습니다.클래스 로더가 클래스 경로에서 발생하는 첫 번째 클래스를 로드하고 중복 클래스를 무시하는 경우가 있지만, 이는 로더의 구현에 따라 달라집니다.

이러한 종류의 오류를 해결하기 위해 권장되는 방법은 종속성이 경합하는 라이브러리 세트별로 별도의 클래스로더를 사용하는 것입니다.이렇게 하면 클래스로더가 라이브러리에서 클래스를 로드하려고 하면 종속 클래스는 다른 라이브러리와 종속성에 액세스할 수 없는 동일한 클래스로더에 의해 로드됩니다.

.URLClassLoaderjars에서 합니다.

URLClassLoader loader1 = new URLClassLoader(new URL[] {new File("httpclient-v1.jar").toURL()}, Thread.currentThread().getContextClassLoader());
URLClassLoader loader2 = new URLClassLoader(new URL[] {new File("httpclient-v2.jar").toURL()}, Thread.currentThread().getContextClassLoader());

Class<?> c1 = loader1.loadClass("com.abc.Hello");

Class<?> c2 = loader2.loadClass("com.abc.Hello");

BaseInterface i1 = (BaseInterface) c1.newInstance();

BaseInterface i2 = (BaseInterface) c2.newInstance();

언급URL : https://stackoverflow.com/questions/6105124/java-classpath-classloading-multiple-versions-of-the-same-jar-project

반응형