2009-11-18 2 views
3

저는 사람들이 플러그인 프레임 워크를 사용하여 특정 인터페이스의 구현을 제공 할 수있는 라이브러리를 작성하고 있습니다 (익숙하다면 JPF입니다). 플러그인은 클래스 경로에 저장되지 않습니다. 프레임 워크는 각 플러그인에 대한 ClassLoader를 제공하므로 인터페이스 "MyInterface"의 "MyImpl"구현이 요청되면 올바른 플러그인을 찾은 다음 해당 플러그인의 ClassLoader를 사용하여 인스턴스를 만들 수있는 클래스를로드 할 수 있습니다 내가 생성자에 대해 뭔가 알면. 여태까지는 그런대로 잘됐다.다른 Java 클래스 로더로로드 된 구현을 사용하는 방법은 무엇입니까?

그러나 지금은 특정 구현에서만 사용할 수있는 메서드를 호출해야하는 경우가 있습니다. 그것은 대부분 그대로

// This call will get an instance of MyImpl (already written and tested) 
MyInterface foo = Plugins.getInstance(MyInterface.class, "MyImpl"); 
// Compiler error because there is no MyInterface.methodOnlyInMyImpl method. 
foo.methodOnlyInMyImpl() 

방법 1 두의 청소기입니다 :

// Makes sure that MyImpl has been loaded, using the custom classloader 
Plugins.getClass(MyInterface.class, "MyImpl"); 
// This line will not compile because MyImpl is not available at build time 
MyImpl foo = new MyImpl(); 
// If I could get this far, this line would work: 
foo.methodOnlyInMyImpl(); 

방법 2 : 1

방법 : 그래서, 나는이를 수행하려고 할 수있는 두 가지 방법이 있습니다 클래스가 "정상"이고 플러그인을 통해 액세스 할 수없는 경우 코드 작성 방법과 비슷합니다. 그러나 어느 것도 컴파일되지 않습니다.

옵션 내가 지금까지 함께 왔어요 :
A. 사용 방법이 있지만, 사용 반사를 methodOnlyInMyImpl 메서드 호출을 수행하는 (! 제발, 아니오)
B. 장소 빌드 경로에 플러그인 클래스와 그런 다음 컴파일 할 방법 1을 사용하십시오.
C. 플러그인 설치시 클래스 파일을 클래스 경로에있는 다른 디렉토리에 복사하면 시스템 클래스 로더가 파일을로드 할 수 있습니다 (다른 문제가 발생 함)

내 질문은 다음과 같습니다.

  1. 다른 아이디어가 더 없습니까?
  2. B를 수행하면 런타임에 문제가 발생합니까? 결국 MyImpl을 사용하는 클래스는 아마도 시스템 클래스 로더를 사용하여로드되었을 것입니다. 따라서 MyImpl foo을 확인하자마자 System 클래스 로더를 사용하여 MyImpl을로드하려고 시도하지 않습니다 (이는 Plugins.newInstance 호출이 MyImpl 인스턴스를 제공하더라도 실패합니다).

답변

3

먼저 실제 구현을 구현해야 할 때 플러그인 메커니즘에서 얻을 수있는 이점은 무엇입니까? 플러그인은 인터페이스를 구현해야하며 인터페이스를 통해 구현을 사용할 수 있습니다.

JPF와 다르지 않지만 Java 클래스는 다른 클래스 로더에 의해로드 될 때 절대로 호환되지 않습니다.

  1. 인터페이스는 플러그인 클래스 로더는 부모와 같은 클래스 로더를 가지고, 그래서 그 인터페이스는 당신과 동일합니다, 당신의 클래스 로더에 :하지만 두 가지 방법이 있습니다. 인터페이스에서 메서드가 선언 될 때 코드 2가이 코드와 함께 작동해야합니다.

  2. 직렬화를 사용할 수 있습니다. 이것은 독립적 인 클래스 로더간에 데이터 객체를보다 유용하게 전송하는 제한된 방법입니다. 두 개의 webapp 사이의 요청 매개 변수를 사용하여 교차 컨텍스트를 전달하는 데이 기능을 사용해야했습니다.

+0

장점을 설명하기위한 예 : 인터페이스 X와 Y가 있습니다. Y를 반환하는 X.getY() 메소드가 있습니다. X 구현 Xa와 Xb 및 Y 구현 Yc와 Yd를 제공하는 네 개의 플러그인이 있습니다. 자, Xa와 Xb 모두 내부적으로 구현 Yc를 사용해야하므로 여기서는 특정 구현이 필요합니다. 응용 프로그램은 Xs 및 Ys와 상호 작용할 수 있지만 플러그인에는 특정 구현이 필요합니다. JPF는 플러그인 종속성을 처리하는 데 도움이됩니다. –

+0

+1 - OP는 인터페이스를 사용하여 암시 된 계약을 무시하려고 시도하고 있습니다. 플러그인이 구현 클래스를 고집하는 유일한 클래스 인 경우 구현 클래스에 대한 컴파일 타임 액세스를 제공하고 캐스트를 사용하고 가능한 ClassCastException을 처리해야합니다. – kdgregory

+0

불행히도 모든 인터페이스를 예상 할 수는 없습니다. 직렬화 (Arne), 런타임시 캐스팅 (kdgregory) 및 TransLoader (Carl) 모두 현재 클래스 로더에서 어떻게 든 사용할 수 있어야합니다. 내 경우에는 그렇지 않습니다. 런타임에 리플렉션 또는 요구 사항을 사용하는 것으로 왔습니다. classpath는 플러그인 디렉토리를 포함합니다. 나는 후자를 선택했다. "Java 클래스는 다른 클래스 로더에 의해로드 될 때 절대로 호환되지 않습니다."라는 핵심 문구로 인해이 대답을 수락합니다. 고마워, 내가 그 담당자를 가졌다면 +1 할거야. –

2

이전 질문에서 언급 한 TransLoader라는 라이브러리가 있습니다. 출처 URL은 http://code.google.com/p/transloader/입니다.

+1

이것은 도움이되었고 내 req가 다른 경우 도움이 될 것입니다. 감사. 내가 그 담당자를 가졌다면 +1 할거야. –

+0

+1 다시 atcha, 그리고 행복하게 나는 대표합니다. 죄송합니다. 귀하의 요구 사항을보다 자세히 파악하고 충족시킬 수 없었습니다. –

관련 문제