2011-01-05 7 views
0

우리 시스템에는 런타임시 알 수없는 클래스를 인스턴스화 할 수있는 플러그인 메커니즘이 있습니다.클래스 검색, 리플렉션, jars 및 jnlp

클래스 패스에 디렉토리 또는 jar가 있으면 시스템은 포함 된 클래스를 탐색 할 수 있으며 클래스가 특정 인터페이스를 구현하면 인스턴스화하여 플러그인으로 사용할 수 있습니다.

모든 것이 항아리로 포장되어 잘 작동합니다. 그러나 웹 스타트 응용 프로그램으로 번들을 만들려고 할 때이 메커니즘이 중단 된 것 같습니다.

더 구체적으로는 더 이상 작동하지 않는 클래스의 발견처럼 보인다 :

public static Collection<String> getAllClassFiles() 
{ 
    Collection<String> all_files = new ArrayList<String>(); 

    String pathSep = System.getProperty("path.separator"); 
    String classpath = System.getProperty("java.class.path"); 

    for (String path : classpath.split(pathSep)) 
    { 
     File filepath = new File(path); 

     if (filepath.isDirectory()) 
     { 
      all_files.addAll(dirContent(filepath)); 
     } 
     else if (path.endsWith(".jar")) 
     { 

      JarFile jar; 
      try { 
       jar = new JarFile(filepath); 
      } 
      catch (IOException e) { 
       Log.warning("WARNING: " + filepath + " could not be opened!"); 
       continue; 
      } 

      for (Enumeration<JarEntry> entries = jar.entries(); entries 
        .hasMoreElements();) 
      { 
       JarEntry entry = entries.nextElement(); 
       if (entry.getName().endsWith(".class")) 
        all_files.add(entry.getName()); 
      } 
     } 
     else if (path.endsWith(".class")) { 
      all_files.add(path); 
     } 
     else { 
      Log.warning("Warning: corrupt classpath entry: " + path); 
     } 

    } 
    return all_files; 
} 

을 그래서 ...이에도 불구하고 더 이상하지 Webstart를 직접 항아리를 사용하여 시스템을 호출 할 때 작동합니다 ...하지만 모든 항아리에는 서명되어 포함되어 있습니다.

webstart에서 계속 작동시키는 방법을 알려주세요.

+1

당신을 어떤 오류를주고있다 ...이 열망로드 각각의 주위에 모든 클래스보다 빠르게 어쨌든, 당신의 classpath 항아리에 따라? –

+0

오류 없음 ... 빈 목록을 반환하는 것 – dagnelies

+0

... 분명히 classpath가 java webstart를 사용하여 사라지기 때문입니다. 단지 다음과 같습니다 : java.class.path = /usr/lib/jvm/java-6-sun-1.6.0.06/jre/lib/deploy.jar 그리고 시스템/배치 등록 정보를 덤프하면 아무 것도 볼 수 없습니다. "내"클래스 경로의 흔적도 원래 항아리의 정보도 ... 그래서 가능한 클래스 목록을 어떻게 수집 할 수 있습니까? – dagnelies

답변

0

은 컨텍스트 클래스 로더를 가져 와서 URL [] s를 얻고 콘텐츠를 스트리밍하려고하면 운이 좋다.

나는 이것도 좋은 생각이라고 생각하지 않습니다. Java는 이러한 방식으로 내용을 반영하지 않습니다. 하지만, 예를 들어 Thread.getContextClassLoader().getResources("META-INF/plugins.txt")과 같이 인스턴스화 된 클래스를 정의 할 수있는 메타 데이터 파일을 읽을 가능성은 다소 희박합니다.

또는 간소화 된 ServiceLoader를 사용하십시오.

+0

ServiceLoader에서 지적한 방식이 마음에 들지만 두 가지 단점이 있습니다. 첫째, 특정 파일에 모든 플러그인 구현 목록을 유지해야합니다. 그런 다음 특수 메커니즘을 삽입하여 jar뿐만 아니라 개발시에도 작동하도록해야합니다. 나는 둘 다 우회 될 수 있다는 것에 동의하지만 ... 최종 해결책은 ... 좋지는 않다. – dagnelies

+0

맞습니다. 클래스와 "메타"파일에 대한 인터페이스 또는 주석의 두 가지 정보 소스를 유지해야합니다. 그러나 클래스 패스의 모든 파일을 열거하면 실제로 비용이 많이들 수 있습니다. 일식과 같이 개발 시간에이 작업을 수행하는 데 어려움이 없습니다. 간단히 "META-INF/services"폴더를 src 폴더에 추가하면 선언 된 모든 서비스는 런타임과 마찬가지로 클래스 경로에 있습니다. 항아리로 수출되면 더 이상 신경 쓰지 않아도됩니다. – mtraut

+0

이것은 만족스러운 접근 방법으로 보일지 모르지만 처음에는 인식 할 때 더 많은 문제가 있습니다. 첫째, 목록을 가져올 때 각 서비스의 인스턴스를 만듭니다. ServiceLoader를 사용하여 클래스 목록을 가져올 방법이 없으므로 인스턴스를 직접 가져올 수 있습니다. 이는 시간이 오래 걸리며 오류가 발생하기 쉽습니다. 둘째로, 다른 인스턴스를 다시로드하지 않고도 여러 서비스 인스턴스를 가져올 수 없습니다. – dagnelies