2017-05-16 1 views
0

이 코드는 스택 오버플로에 표시됩니다. 그것은 좋은 하나지만 넷빈에서만 작동합니다. .jar 파일을 생성 한 후에는 더 이상 작동하지 않으며 오류 메시지를 표시하지 않습니다.포장 후 반사가 작동하지 않습니다.

/** 
* Scans all classes accessible from the context class loader which belong 
* to the given package and subpackages. 
* 
* @param packageName The base package 
* @return The classes 
* @throws ClassNotFoundException 
* @throws IOException 
*/ 
public Class[] getClasses(String packageName) 
     throws ClassNotFoundException, IOException { 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    assert classLoader != null; 
    String path = packageName.replace('.', '/'); 
    Enumeration<URL> resources = classLoader.getResources(path); 
    List<File> dirs = new ArrayList<File>(); 
    while (resources.hasMoreElements()) { 
     URL resource = resources.nextElement(); 
     dirs.add(new File(resource.getFile())); 
    } 
    ArrayList<Class> classes = new ArrayList<Class>(); 
    for (File directory : dirs) { 
     classes.addAll(findClasses(directory, packageName)); 
    } 
    return classes.toArray(new Class[classes.size()]); 
} 

/** 
* Recursive method used to find all classes in a given directory and 
* subdirs. 
* 
* @param directory The base directory 
* @param packageName The package name for classes found inside the base 
* directory 
* @return The classes 
* @throws ClassNotFoundException 
*/ 
private List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException { 
    List<Class> classes = new ArrayList<Class>(); 
    if (!directory.exists()) { 
     return classes; 
    } 
    File[] files = directory.listFiles(); 
    for (File file : files) { 
     if (file.isDirectory()) { 
      assert !file.getName().contains("."); 
      classes.addAll(findClasses(file, packageName + "." + file.getName())); 
     } else if (file.getName().endsWith(".class")) { 
      classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6))); 
     } 
    } 
    return classes; 
} 

이 코드는 다른 JMenu 라이브러리로 사용하기 위해 캡슐화되었습니다. 하지만 넷빈에서만 작동합니다. 나는 왜 그런지 이해하지 못한다.

갱신

내가 더 잘 설명하려고합니다.

저는 리플렉션을 통해 다른 프로젝트의 클래스를 읽는 JMenu와 함께 작업 할 프로젝트가 있습니다. 이 프로젝트는 다른 프로젝트의 도서관으로 사용됩니다. netbeans에서 실행되면 잘되지만 .jar 파일을 생성하면 더 이상 작동하지 않으며 오류 메시지가 표시되지 않습니다.

+1

을 볼 사용할 수 있습니까? 그것은 추락합니까? 예기치 않게 작동합니까? – Michael

+0

오류가 발생하지 않습니다. 코드는 아무 것도하지 않습니다. – Krismorte

답변

1

모든 리소스가 jar 파일로 압축되면 더 이상 파일이 없습니다.

대신 this.class.getResource() 또는 this.class.getResourceAsStream()

사용 또는 일부 라이브러리는 당신이 "더 이상 작동하지 않는다"무엇을 의미합니까 Can you find all classes in a package using reflection?

+0

멋지고 빠릅니다. – GhostCat

+0

Reflections를 사용하도록 코드를 변경했습니다. – Krismorte