2011-01-05 4 views
3

저는 현재 여러 사용자 정의 형식으로 출력하고자하는 데이터 세트가있는 Java 프로젝트에서 작업하고 있습니다. 각 형식에 대한 클래스가 있는데, 원시 데이터를 취하여 적절하게 변환합니다. 그러나 처음에는이 형식 중 2 ~ 3 개만 구현하지만 나중에 응용 프로그램을 대규모로 다시 빌드 할 필요없이 더 많은 형식을 추가 할 수 있기를 바랍니다.동적 Java 프로그램 용 DLL은 무엇입니까?

내 생각은 각 형식 클래스에 대한 DLL을 만들고 내 응용 프로그램이이 각각으로 변환 할 데이터를 전달하도록하는 것이 었습니다. 이렇게하면 나중에 DLL을 만들고 기본 응용 프로그램에 액세스 할 수 있습니다. (나는 C++/C#에서 논리적 솔루션과 같은 느낌이 들기는하지만 Java에 적용되지 않을 수도 있지만 Java에 적용되지 않을 수도 있습니다.)

제 문제는 제가 절대적으로 가지고있는 것입니다. C++/C#에서는 몇 줄의 코드로이 코드를 작성할 수 있지만 Java로 어떻게 작동하는지 잘 모르겠습니다. 끔찍한 모호한 질문을 할 위험이 있습니다. 어떻게해야합니까?

정답은 쿠키와 차가 제공됩니다. :) 사전에

감사합니다, M

편집 : 죄송합니다, 단지 추가 :이 프로젝트를 위해 자바에 있어야 DLL을 만드는 방법도 확실하지 오전은, 처음에 읽을 수 . 감사. :)

답변

5

DLL 자체를 사용하는 대신, 일종의 플러그인 아키텍처가 필요합니다.

필요하지 않은 한 DLL 사용을 권장하지 않는 한 가지 이유는 Java 코드를 원시 코드와 연결하는 데 순수한 Java 솔루션보다 많은 노력이 필요한 Java Native Interface (JNI)을 사용해야한다는 것입니다.

상대적으로 간단한 방법은 Java의 reflection 기능을 사용하는 것입니다.주어진 정보에서

, 나는 아마 다음의 라인을 따라 갈 것 :

  1. 는 출력 형식에 대한 인터페이스를 정의합니다.
  2. 인터페이스를 구현하는 Java 클래스를 만듭니다.
  3. classpath에서 수업을 받으십시오.
  4. 리플렉션을 사용하여 동적으로 클래스를로드하십시오. 합니다 (Class.newInstance 방법을 사용하면 ClassLoader에 의해로드 class 파일에서 객체를 생성 할 수 있습니다.) 다음 단계로

, 전체를 필요로하지 않을 단순한 플러그인을 구현할 수있을 것이다 재건 할 때 새로운 형식에 대한 지원 필요합니다.


1 단계 : 정의

이의 우리가 같은 인터페이스 결국 가정 해 봅시다 인터페이스 다음

public interface Outputter { 
    public void write(Data d); 
} 

2 단계 : 확인 구현 클래스

그런 다음 구현 클래스를 만듭니다.

public class TextOutputter { 
    public void write(Data d) { 
    // ... output data to text 
    } 
} 

그런 다음, 위의 컴파일, 우리는 TextOutputter.class라는 class 파일을하게 될 겁니다.

3 단계 : 주요 응용 프로그램을 실행하면 클래스 경로

에서 클래스가 사용할 수 있도록, 우리는 classpathTextOutputter.class을해야합니다. 일반적으로 JVM에게 classpath로 고려해야 할 곳 목록을 알려주고, 위의 class 파일을 포함해야합니다.

일단 완료되면 리플렉션을 사용하여 위의 클래스를로드 할 수 있어야합니다.

4 단계 :

// Note: We load the class by specifying the fully-qualified class name! 
Class<?> clazz = Class.forName("TextOutputter"); 

// Then, we instantiate the class. 
// Note that the following method will call the no-argument constructor. 
Outputter outputter = clazz.newInstance();  

// Now, we can give data to the TextOutputter object that we loaded dynamically. 
outputter.write(...); 

Class.forName 방법 : 우리가 실제로 위의 클래스를로드 할 때 동적으로 이제 반사

를 사용하여 클래스를로드, 우리는 다음과 같이 뭔가를 할 것 는 ClassLoader에서 TextOutputter 클래스를 찾기 위해 사용됩니다. 클래스를 Class 표현으로 얻으면 클래스의 객체를 인스턴스화 할 수 있습니다.

개체의 인스턴스화는 Class.newInstance 메서드를 사용하여 수행 할 수 있습니다. 인수가없는 생성자 이외의 것이 사용되어야한다면 클래스의 Constructor을 가져 와서 거기에서 객체를 인스턴스화해야합니다.반사 후 Outputter 변수에 배치되므로 write 방법은 TextOutputter 호출 할 수 통해

오브젝트가 인스턴스화.

더 많은 형식을 추가하면 위의 과정이 수반되지만 정규화 된 클래스 이름을 변경하면 (예 : String의 경우 FQCN은 java.lang.String) 다른 클래스를로드하는 데 필요한 것입니다. 간단히 말해서


, 즉 동적으로 class 파일을로드하고 응용 프로그램에서 사용하는 데 걸리는거야.

(그냥 보조 노트로, 실제로 위의 코드를 컴파일하지 않았다, 그래서 여기 저기 약간의 오차가있을 수 있습니다,하지만 난이 걸릴 것입니다 과정을 설명 할 수 있기를 바랍니다.)

+0

예, JNI 및 동적 네이티브 라이브러리 (고성능 또는 특정 외부 라이브러리에서 래퍼로 POJO를 사용하는 경우)가 필요한 클래스를 사용하려는 경우가 아니라면이 방법이 효과적입니다. DLL에 바인딩 된 클래스를 표준 클래스 로더로 다시로드 할 수 없으므로이 경우 하위 클래스에 바인딩해야합니다. – dweeves

+0

자바의 최신 버전에서는 서비스 제공 업체 메커니즘 (java.util.ServiceProvider)을 사용하여 플러그인 항아리에서 플러그인 구현로드를 표준화 할 수 있습니다. – jtahlborn

+0

@dweeves : 클래스 로더를 서브 클래스 할 필요가 없습니다. 별도의 클래스 로더를 사용하여 dll을 언로드하려는 경우 삭제해야합니다. – jtahlborn

1

자바에서 사용할 네이티브 코드 (DLL로 컴파일)를 작성하려면 Java Native Interface (JNI)을보고 싶습니다. (라이브러리 이름을 알고 라이브러리 경로가 설정되어있는 경우) System.loadLibrary(String libName)을 사용할 수 있습니다

업데이트 또는 System.load(String filename) (라이브러리 파일 이름) 자바 라이브러리 (DLL)를로드합니다.

1

System.loadLibrary()를 사용하여 언제든지 새 DLL을로드 할 수 있습니다. 그러나 바인딩 할 자바 클래스를로드해야 할 수도 있습니다. 당신은이 같은 도움이 OSGi 컨테이너를 사용하여 찾을 수 있습니다

모두 부하 (공유 라이브러리 포함) 모듈의 하역

내가 iPOJO와 karaf 사용 제안을 지원하지만 많은 사람들이있다.

2

나는 그런 것들을 만들었습니다. 나는 오픈 된 자바 기반의 플러그인 아키텍쳐 인 POJO 기반을 만들었는데, 업데이트 된 플러그인 클래스를 즉시 재로드했다. JNI는 네이티브 코드를 처리하기위한 인터페이스입니다. 유일한 기술적 인 부분은 런타임에 동적으로 DLL을 다시로드 할 수있는 클래스 로더를 다시 작성하는 것입니다. 그러나 "오프라인"업데이트 만하는 경우에는 그런 것이 필요하지 않습니다.

1

난 당신을 생각 JNI 경로를 무시할 수 있습니다. 나는 당신이 더 나은 단어의 부족에 대한 용어 dll을 사용하고 있다는 인상을 가지고, 당신은 정말 dll이 필요하지 않습니다.

자바에서도 똑같은 작업을 수행 할 수 있지만 dll 대신 jar 파일에 필터를 넣을 수 있습니다.

  1. 폴더 반복,
  2. 이 응용 프로그램의 한 시점에서
  3. ('필터'같은) 특정 폴더에, 항아리에 각 구현을 넣어 구현하는 파일 형식 필터 인터페이스를 정의 자신의 일을하기 위해 인터페이스의 모든 구현을 찾기 위해 항아리에 대한
  4. 사용 반사 클래스 로더를 생성하고, 각
  5. 전화에 대한 방법을 클래스를 만들

그건 기본적입니다. http://download.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html

당신이 적절한 모듈 식 접근 방법을 원하는 경우 이 (가 데스크톱 응용 프로그램은 특히 경우) 넷빈즈 플랫폼을 고려 또는은 OSGi :

1

자바 SE 6은 ServiceLoader 클래스를 소개합니다.

관련 문제