2010-01-21 2 views
1

Java 프로그램이 jar 파일에서 클래스를 가져 오는 시나리오를 고려하십시오. 동일한 클래스가 두 개 이상의 jar 파일에있는 경우 문제가있을 수 있습니다. 이러한 시나리오에서JAR 파일로부터 안전 클래스 가져 오기

  1. 프로그램에서 가져온 클래스는 무엇인가? 더 오래된 타임 스탬프가있는 클래스 입니까 ??

  2. 이러한 합병증을 피하기 위해 우리가 따라야 할 관행은 무엇입니까?

편집 :이 예입니다. 2 개의 jar 파일 my1.jar 및 my2.jar가 있습니다. 두 파일 모두 com.mycompany.CrazyWriter를 포함합니다.

+1

동일한 클래스가 두 개 이상의 클래스에 있습니다. 명확하게 할 수 있습니까? – Aadith

+1

"동일한 학급이 두 개 이상의 학급에 거주하는 경우"? "같은 반이 두 개 더있는 병에 살면 *"을 의미 했습니까? – phisch

+0

편집을 기반으로 첫 번째 문장을 명확히하기 위해 질문이 업데이트되었습니다. –

답변

0

첫째, 올바른 버전이로드되어 있는지 확인하고, 당신을위한 complexitites 많이 관리 할 수 ​​있습니다, 당신이 동일한 클래스가 두 개 더 항아리에 파일 ...

있는 것을 의미한다고 가정

지금, 당신의 질문에 대답 : 가져온 클래스

  1. 는 클래스 로더와 JVM에 따라 달라집니다. 클래스가 어떤 클래스인지는 보증 할 수 없지만, 일반 클래스 로더에서는 classpath의 첫 번째 jar 파일의 클래스가됩니다.
  2. 동일한 클래스를 여러 jar 파일에 넣지 않거나 시스템 클래스를 재정의하려는 경우 -bootclasspath을 사용하십시오.

편집 :이 대답에 대한 의견 중 하나를 해결합니다. 원래는 sealing the jar은 이론적으로 다른 jar 파일에서 같은 패키지의 두 클래스를로드해서는 안되기 때문에 차이가 있다고 생각했습니다. 그러나 몇 가지 실험을 마친 후에는 적어도 기본 보안 공급자와 관련하여이 가정이 유효하지 않음을 알았습니다.

+0

1. ** 기본 ** 클래스 로더는 무엇입니까? (질문이 무엇입니까?) 2. 여러 개의 JAR (예 : 클래스를 패치)에 동일한 클래스의 서로 다른 버전을 두는 유효한 유스 케이스가 있습니다. –

+0

@Pascal 이것이 올바른 유스 케이스라고 생각할 수도 있지만, 일반적으로 어쨌든 재시동해야하기 때문에 원래의 jar를 대체하는 것이 훨씬 낫습니다. 대답은 위와 같이 클래스 로더가 먼저 찾은 클래스를 사용합니다. 일반적으로 classpath에있는 첫 번째 jar 파일에 있습니다. –

+0

@Paul BEA **는 새로운 weblogic.jar을 제공하지 않으므로 원래의 jar 파일을 바꾸는 것이 더 좋지 않습니다. 문제는 다시 시작하지 않을 수도 있습니다. 그리고 내가 함께 작업 한 모든 JVM은 ** 항상 ** 발견 된 첫 번째 클래스를 선택합니다. –

2

기본적으로 클래스는 순서대로 검색되는 클래스 경로를 사용하여 ClassLoader에 의해로드됩니다.

동일한 클래스의 구현이 두 개있는 경우 클래스 로더가 먼저 찾은 것이로드됩니다.

클래스가 실제로 동일한 클래스 (동일한 이름이지만 다른 메소드)가 아닌 경우 사용하려고하면 예외가 발생합니다.

여러 클래스 로더를 사용하여 단일 VM에서 동일한 이름의 클래스 두 개를로드 할 수 있습니다. OSGI 프레임 워크 등

0

ClassLoader는 클래스를로드합니다. 그것은 ClassPath를 스캔하고 먼저 발견 한 클래스를로드합니다. ClassPath에서 동일한 Jar를 두 번 사용하거나 동일한 클래스의 다른 두 버전 (com.packagename.Classname)을 포함하는 Jar가 두 개있는 경우 먼저 발견 된 Jar 파일이로드됩니다.

클래스 패스에 동일한 병이 두 번 나타나지 않도록하십시오.당신이 무슨 뜻인지

0
  1. 확실하지 중첩 된/내부 클래스를 의미하는 경우 서로 다른 네임 스페이스에 있기 때문에, 아무 문제가 없을 것

    "같은 클래스가 두 개 더 클래스에 있습니다."
    이미 2 개 이상의 JAR을 의미하는 경우 이미 응답 한대로 클래스 경로의 순서가 사용됩니다.

  2. 피하려면?
    중복 된 클래스를 피하려면 패키지가 하나의 JAR에만 있어야합니다. 두 클래스가 동일한 간단한 이름 (예 : java.util.Datejava.sql.Date)을 가지고 있지만 다른 패키지에있는 경우 실제로는 다른 클래스입니다. 클래스 중 적어도 하나에서 정규화 된 이름을 사용하여 구분해야합니다. 당신은 문제가 클래스의 버전이 사용되는 찾는 경우

0

, 다음 jwhich 사용 될 수 있습니다 http://www.fullspan.com/proj/jwhich/index.html

+0

Eclipse에 JAR 파일/위치 목록이있는 "Multiple class definitions found"경고가 표시되기를 바랍니다. 특정 클래스를 가져올 위치를 알려주는 Eclipse 용 플러그인이 있습니까? 나는 많은 병에 의존하는 큰 프로젝트를 관리하고 때로는 갈등이있다. jar 파일은 불변이므로 빌드 경로가 바뀌면 제대로 작동합니다. 대부분의 경우, 올바른 파일이 사용되는지 여부를 알기가 어렵습니다 (클래스 파일을 빌드 할 때 특정 클래스에 대한 참조로 빌드되며 중복 파일을 가리킬 수는 없습니다). – ADTC

+0

@ATDC 내가 아는 것은 아니다. (나는 현재 이클립스 사용자가 아니다.) 그러나 나는 당신 자신의 글을 쓰기에는 너무 어려울 것이라고 생각하지 않는다. –

0

이 있어야 같은 클래스가 두 개 더 항아리에있는 경우 문제.

정확히 무엇을 의미합니까? 왜 이되어야합니까?

이러한 시나리오에서 프로그램에서 가져온 클래스는 무엇입니까? (보다 오래된 타임 스탬프가있는 클래스 ??)

클래스가 두 개의 JAR에있는 경우, 클래스는 발견 된 클래스 경로의 첫 번째 JAR에서로드됩니다. Setting the class path을 인용하십시오 (따옴표 붙은 부분도 아카이브 파일에 적용됩니다) :

여러 클래스 경로 항목을 지정하는 순서는 중요합니다. Java 인터프리터는 클래스 경로 변수에이 나타나는 순서대로 디렉토리의 클래스를 찾습니다. 위의 예에서 Java 인터프리터는 먼저 C:\java\MyClasses 디렉토리에서 필요한 클래스를 찾습니다. 해당 디렉토리에 적절한 이름의 클래스가 없으면 통역사는 C:\java\OtherClasses 디렉토리를 찾습니다.

즉, 특정 순서가 필요한 경우 클래스 경로에서 JAR 파일을 명시 적으로 열거하면됩니다. 이는 응용 프로그램 서버 공급 업체에서 일반적으로 사용하는 것입니다. 특정 클래스의 제품을 패치하려면 주 JAR (예 : weblogic.jar) 앞에 클래스 경로에 패치 된 클래스가 포함 된 JAR (예 : CR1234.jar)을 넣습니다.

이러한 합병증을 피하기 위해 우리가 따라야 할 관행은 무엇입니까?

음, 명백한 대답은하지 마십시오 (또는 위에 주어진 샘플과 같은 목적에만 해당).