2010-12-14 4 views
5

우리는 Apache HTTPClient 3을 사용하여 HTTP 요청을하는 여러 응용 프로그램을 가지고 있습니다. 최근에 우리는 다양한 이유로 HTTPClient 4를 사용하는 웹 서비스 클라이언트를 만들기 시작했습니다. Apache 입장에서는 "주요 릴리스는 역 호환되지 않습니다"입니다. 버전 4를 사용하기 위해 모든 프로젝트를 업데이트하고 싶지만 간단하지는 않습니다.Java에서 패키지의 여러 버전에 액세스

내 주된 질문은 다소 일반적인 것이지만, 나의 특별한 질문이 있습니다. HTTPClient 버전 3과 4를 같은 응용 프로그램에서 어떻게 사용할 수 있습니까? 우리의 경우 응용 프로그램은 웹, 데스크탑 또는 명령 줄 응용 프로그램이 될 수 있습니다.

반 폐쇄 된 것으로 보이는 SO question for java-dynamically-load-multiple-versions-of-same-class을 읽었지만 동적 부분에 대해서는별로 신경 쓰지 않습니다. 사실 나는 JAR이 app (예 : WEB-INF/lib for web apps)와 함께 선적되기를 원합니다. OSGi이이 질문과 유사한 질문을 많이하는 것을 보았습니다. 그러나 지나치게 복잡하거나 어쩌면 지나치게 복잡한 것 같습니다. 간단한 예가 그렇지 않다는 것을 증명할 수있다). 결국

나는 팀에게 그들이에서 삭제할 수 있습니다 항아리의 집합을 손으로 할 수 있도록하려면 그것은 단지 HTTP 클라이언트 3.

+1

이것은 아키텍처 관리가 좋은 아이디어 였을 것입니다. 버전 3을 고수하거나 모든 것을 버전 4로 옮길 것입니다. 이제 패치 워크 솔루션 구현 비용을 지불해야합니다. 시간이 지남에 따라 악화된다. – Anon

+1

@Anon : 죄책감은 없지만 상황을 알지 못하고 그런 담요 진술을하는 데 조언을하지 않습니다. 나는 그러한 의견을 피하기 위해 "여러 가지 이유로"말했다. –

+0

OSGi는 적어도 작동합니다 (잔인한 것인지 아닌지 결정해야합니다.) 라이브러리의 각 버전마다 하나씩 두 개의 웹 서버를 갖는 것 이외에 다른 작업을 수행하는 간단한 방법을 알지 못합니다. –

답변

5

다른 사람들이 말했듯이, 여러 클래스 로더를 생성하고 두 버전을 분리하여로드 할 수 있습니다. 이 부분은 충분히 쉽습니다.

문제는 본질적으로 "클래스 공간"을 나누기 때문에 응용 프로그램의 다른 부분에서 v4를 참조하면서 응용 프로그램의 일부에서 v3을 참조하는 것은 여전히 ​​어려울 것입니다. 당신은 애플리케이션 을 매우 조심스럽게으로 분할해야 할 것입니다. 그래서 그것을 분할하고 두 개의 애플리케이션을 제공하는 것이 어떻습니까?

서비스로 기능을 분류 할 수있는 경우 OSGi가 해결책이 될 수 있습니다.그러나 레거시 애플리케이션을 OSGi로 변환하는 것은 가볍게 수행 할 사항이 아니며, 분명히 당신이 걸어온 함정에서 싼 탈출구가되지는 않을 것입니다. OSGi와 잘 알려진 OSGi 전도자에 대한 책의 저자로서 이것을 말합니다. 응용 프로그램을 OSGi 으로 변환하는 장기 목표는이 큰 이점을 가져다 주지만 상당한 초기 비용이 소요됩니다.

1

를 사용하여 여러 개의 클래스 로더, 각 하나를 사용하여 자신의 프로젝트의 독립적 인 작동 포용하려는 HTTP 클라이언트.

가장 간단한 방법은 URLClassLoader를 확장하고 각 버전의 클래스 경로를 별도로 하드 코드 해킹하는 것입니다. 그런 다음 나머지 코드가 사용할 HTTP 클라이언트의 버전을 알고 (올바른 클래스 로더에 액세스하여) 액세스 할 수 있도록합니다.

+0

JAR이 WAR와 함께 출하되어야하는 webapp에서는 어떻게 작동합니까? –

+0

참조 된 각 라이브러리의 모든 버전을 제공하지만 web-inf/lib가 아닌 다른 곳에 두십시오. 사용자 정의 클래스 로더는 "다른 위치"에서 찾습니다. 이렇게하면 전쟁 컨테이너가 직접 참조 할 수 없습니다. –

1

v3 및 v4에는 별도의 클래스 로더를 사용해야합니다. v3 및 v4 병을 응용 프로그램 클래스 경로를 넘는 별도의 폴더에 넣으십시오. URLClassLoadedr을 사용하여 각 버전을로드하십시오. 클래스 로더 각각에 전달하는 URL에는 특정 버전의 HTTP 클라이언트에 대한 URL이 포함되어야합니다.

하지만 조언을 해 주시겠습니까? 먼저 시작하기 전에이 모든 것이 정말로 필요한지 확인하십시오. 버전이 호환되지 않을 수도 있습니다. 그러나 그들이 할 수있는 큰 기회가 있습니다.

+1

당신은 "거대한 기회가 없다 *"라고 생각합니다. HTTP 클라이언트 v3와 V4가 잘 작동하지 않는다는 것을 알고 있습니다. –

2

는 쉽지만 간단한 솔루션은 HttpClient3 및 HttpClient4에 대한 소스를 얻을 수 있으며,

org.apache.commons.httpclient3 HttpClient3에 대한org.apache.commons처럼 뭔가에 패키지 이름을 리팩토링 것입니다 HttpClient4가 충돌을 피하기 위해 .httpclient4. 그런 다음 컴파일, 패키지 완료.

이제 두 구현을 쉽게 전환 할 수 있으며 클래스 로더에서 충돌하지 않습니다.

+1

이 방법은 한 항아리에서만 작동하지만 문제가 해결되는 것보다 더 많은 문제가 발생합니다. 예를 들어, apache.commons.logging이 필요할 수 있으며, 두 버전 모두 서로 다른 버전의 공통 로그에 종속적입니다 (서로 다른 시간에 출시되기 때문에). 이제 위와 같은 방법으로 commons 로깅을 재 패키징 할 수 있지만 재 패키지 된 http 클라이언트의 모든 소스 코드를 수동으로 편집하여 올바르게 참조해야합니다. 곧 이러한 솔루션은 큰 혼란이된다. –

+1

그들은 다른 버전의 commons-logging에 정말로 의존합니까? 최신 버전은 둘 다 잘 작동합니다. – Thilo

+2

commons-lang 사람들이이 경로를 사용하고 있습니다. Commons Lang 3은 패키지 이름 org.apache.commons.lang3을 사용할 것입니다. 호환되지 않는 API 변경이있을 경우 새 패키지 이름이 가장 나쁜 아이디어는 아닙니다. – Thilo

관련 문제