2009-11-17 3 views
14

우리는 다른 내부 앱용 클라이언트 항아리를 제공하여 앱의 REST API에 연결합니다. API는 몇 가지 표준 자카르타 라이브러리에 따라 다릅니다. JAR 파일을 클라이언트 jar 파일에 포함시키는 것이 가장 좋은 방법입니까? 아니면 의존성을 문서화하고 클래스 패스에 해당 항아리가 있는지 확인하는 것은 클라이언트에게 달려 있습니까?클라이언트 jar에 종속 라이브러리를 제공해야합니까?

답변

12

아니요 타사 jar를 자신의 jar 파일로 묶는 것이 좋지만 배포판에 필요한 모든 jar 파일의 복사본을 lib 디렉토리에 포함시키는 것이 좋을 것입니다. 이제까지.

주된 이유는 클라이언트가 어떤 형태의 의존성 관리 시스템 (maven/ivy 등)을 사용하고 있고 프로젝트에 실제로 속하지 않는 패키지와 클래스를 제공하면 이러한 스키마가 무효화된다는 것입니다.

하나의 대안이 있는데, 이는 maven shade plugin과 같은 것을 사용하여 종속성을 자신의 패키지 네임 스페이스에 재배치하는 것입니다. 이것은 당연히 라이브러리의 코드 크기를 증가시킬 수 있다는 단점이 있지만, 클라이언트 측에서 사용하는 다른 라이브러리에 영향을 미치지 않고 종속성 버전을 거의 보장 할 수 있습니다.

편집 : 재배치 밖으로 번들로

가능한 솔루션/: 마커스 레온 주석에 응답

  • 문서, 당신이 당신의 종속성 및 이전 버전의 알려진 충돌을 문서화하십시오 - 아무도 실제로 그것을 읽는다
  • 의존 관리되는 시스템을 통해 당신에게 배포 할 라이브러리 ... 메이븐 (maven)이나 아이비 (ivy) 저장소와 같은 것들은 의존성이 무엇인지에 대한 매우 구체적인 범위 (위를 포함하여)를 문서화하게한다. 클라이언트가 OSGi를 실제로 사용하는 경우에만 유용함 - 클라이언트가 OSGi를 실제로 사용하는 경우에만 유용함 -
  • 종속성이 maven을 사용하여 빌드되었거나 매니페스트 파일에 버전 정보가있는 경우에만 유용합니다 당신은 이러한 클래스 패스를 검사하고 버전을 검사하는 일종의 검사 루틴을 작성할 수 있습니다 - 조금 극단적입니다.

결국에는 실제로 자바가 늦은 바운드이므로 원하는 종속성을 보장하기가 매우 어렵습니다. 언어를 사용하면 클래스 패스에서 다른 버전을 포함하여 누군가가 (심지어 번들로 묶어도) 의존성을 무시할 수 있습니다.

참고 : 저는 최근에 을 매우 우리의 애플 리케이션 중 하나가 log4j의 새로운 버전을 찾지 못한 이유를 찾으려고 노력한 나쁜 날을 보냈습니다. 원인 : 도움이 되려고하는 누군가가 완전히 무관 한 임의의 항아리에 그것을 묶어 두었다.

+0

번들을 사용하지 않고 클라이언트가 다른 버전의 dependent.jar을 사용하는 경우 client.jar이 올바른 버전의 dependent.jar을 참조하도록하려면 어떻게해야합니까? –

+1

수정 사항보기 ...짧은 대답은 당신이 어떤 방법으로도 ... 심지어 묶음이라도 할 수 없다는 것입니다. –

+0

매니페스트에 클래스 경로가 설정된 jar 파일에 종속성이 번들되어 있어도 컴파일러는 명시 적으로 언급 된 jar 파일을로드하지 않습니다 클래스 - 경로 매니페스트 항목? –

2

독립 실행 형 응용 프로그램으로 응용 프로그램을 배포하는 경우 해당 병을 포함해야합니다. 누군가를 빌드 할 소스를 배포하고 있고 maven pom 파일을 제공한다면 반드시 그렇게 할 필요는 없습니다.

5

의존하는 병을 포함해야합니다. 클라이언트가 표준 jar를 제공하도록 허용하는 경우 올바른 버전을 제공하기 위해 의존합니다. 앱이 작동하는 것으로 알고있는 버전을 포함하면 두 가지면에서 훨씬 더 고통 스럽습니다. 하나의 항아리에 번들의

+0

jar 파일 버전 2를 포함하고 클라이언트가 classpath에 버전 # 1을 이미 가지고 있다면 라이브러리가 버전 # 2 (및 v # 1이 아닌)를 사용하도록 어떻게 적용합니까? –

+2

응용 프로그램 jar의 매니페스트 파일에서 응용 프로그램의 클래스 경로를 지정할 수 있습니다. (http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html) CLASSPATH 정의 (환경 변수에 정의 된대로)는 jar의 매니페스트에 정의 된 "class-path"로 대체됩니다 . –

+0

나는 (http://one-jar.sourceforge.net/) "Java 클래스 로더는 Jar 파일에서 Jar 파일로부터 클래스를로드하는 방법을 모른다. 클래스 경로의 항목은 파일 Jar 파일 밖에서, 단일 Jar 파일로 애플리케이션을 전달한다는 목표를 뛰어 넘었다. " –

4

찬반이 분명히 있습니다 : 클라이언트

번들의 단점에 대한

  • 단순성은 다음과 같습니다의 버전을 업데이트 할

    • 수 없음 종속 라이브러리
    • 필요한 라이브러리를 숨기면 클라이언트에서 잠재적 인 충돌이 발생할 수 있습니다. h 여분의 라이브러리들
    • 빌드 프로세스에서 복잡함 (그러나 Ant/Maven에서이 작업을 매우 쉽게 수행 할 수있는 방법)
    • 매니페스트가있는 일부 라이브러리는 unjared 및 rejared 할 수 없습니다. 실제로 매니페스트 정보를 병합해야합니다. 이것에 대한 Ant와 Maven 지원이 있습니다.

    또 다른 옵션은 클래스 경로 매니페스트 특성이있는 단일 기본 병 (코드)을 사용하여 다른 병을 흡입하는 것입니다. 개인적으로 나는이 반 숨겨진 의존성을 놓치기가 정말 쉽기 때문에 이것을 좋아하지 않는다.

    결국 한두 개의 항아리 만 쓰고 있다면 나눠 둡니다. 10 개 또는 15 개의 통화를하는 경우 번들링을 고려할 수 있습니다.

0

아주 특정한 라이브러리 버전 의존성에 대해 긴장감을 나타내고있다. (그리고 Hibernate가 다른 모듈들과 얼마나 밀접하게 결합되어 있다고 가정하면 Hibernate의 특정 버전 만이 하나의 최대 절전 코어 이것은 차례로 특정 hibernate-validator와 함께 사용되어야합니다).

패키지가 더 큰 플랫폼의 일부로 작동해야한다는 것을 알고 있다면 (예 : 자체 jar를로드 할 수있는 프레임 워크의 플러그인으로), 더 강력한 다중 버전 클래스로드가 필요합니다. OSGI (일명 JSR-291) : OSGI 기반 프레임 워크와 OSGI Technology

, 봄, 이클립스, 조나스, 또는 글래스 피시 등, 당신은 당신의 특정 버전 종속성을 제기하는 XML에 지정할 수 있습니다, 당신은 번들에 의존하는 경우 libfoo-1.1.4, 또 다른 플러그인은 libfoo-2.0a에 달려 있지만 OSGI 종속성 관리자는 각각의 버전이 올바른 버전으로로드되도록합니다.

관련 문제