development

폴더 또는 JAR에서 런타임에 클래스를로드하는 방법은 무엇입니까?

big-blog 2020. 12. 4. 19:44
반응형

폴더 또는 JAR에서 런타임에 클래스를로드하는 방법은 무엇입니까?


Java 응용 프로그램의 구조를 스캔하고 의미있는 정보를 제공하는 Java 도구를 만들려고합니다. 이렇게하려면 프로젝트 위치 (JAR / WAR 또는 폴더)에서 모든 .class 파일을 스캔하고 리플렉션을 사용하여 메서드에 대해 읽을 수 있어야합니다. 이것은 거의 불가능한 것으로 입증되었습니다.

디렉토리 / 아카이브에서 특정 클래스를로드 할 수있는 URLClassloader를 기반으로하는 많은 솔루션을 찾을 수 있지만 클래스 이름이나 패키지 구조에 대한 정보없이 클래스를로드 할 수있는 솔루션은 없습니다.

편집 : 나는 이것을 잘못 표현했다고 생각합니다. 내 문제는 모든 클래스 파일을 가져올 수 없다는 것이 아니라 재귀 등으로 할 수 있고 올바르게 찾을 수 있다는 것입니다. 내 문제는 각 클래스 파일에 대해 Class 객체를 얻는 것입니다.


다음 코드는 JAR 파일에서 모든 클래스를로드합니다. 수업에 대해 알 필요가 없습니다. 클래스 이름은 JarEntry에서 추출됩니다.

JarFile jarFile = new JarFile(pathToJar);
Enumeration<JarEntry> e = jarFile.entries();

URL[] urls = { new URL("jar:file:" + pathToJar+"!/") };
URLClassLoader cl = URLClassLoader.newInstance(urls);

while (e.hasMoreElements()) {
    JarEntry je = e.nextElement();
    if(je.isDirectory() || !je.getName().endsWith(".class")){
        continue;
    }
    // -6 because of .class
    String className = je.getName().substring(0,je.getName().length()-6);
    className = className.replace('/', '.');
    Class c = cl.loadClass(className);

}

편집하다:

위의 의견에서 제안했듯이 javassist도 가능성이 있습니다. 위의 코드를 구성하는 while 루프 전에 ClassPool을 초기화하고 클래스 로더를 사용하여 클래스를로드하는 대신 CtClass 개체를 만들 수 있습니다.

ClassPool cp = ClassPool.getDefault();
...
CtClass ctClass = cp.get(className);

ctClass에서 모든 메소드, 필드, 중첩 클래스 등을 얻을 수 있습니다. javassist API를 살펴보십시오 : https://jboss-javassist.github.io/javassist/html/index.html


jar 파일 내의 모든 클래스를 나열합니다.

public static List getClasseNames(String jarName) {
    ArrayList classes = new ArrayList();

    if (debug)
        System.out.println("Jar " + jarName );
    try {
        JarInputStream jarFile = new JarInputStream(new FileInputStream(
                jarName));
        JarEntry jarEntry;

        while (true) {
            jarEntry = jarFile.getNextJarEntry();
            if (jarEntry == null) {
                break;
            }
            if (jarEntry.getName().endsWith(".class")) {
                if (debug)
                    System.out.println("Found "
                            + jarEntry.getName().replaceAll("/", "\\."));
                classes.add(jarEntry.getName().replaceAll("/", "\\."));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return classes;
}

이렇게하려면 프로젝트 위치 (JAR / WAR 또는 폴더 만)에서 모든 .class 파일을 스캔 할 수 있어야합니다.

Scanning all of the files in a folder is simple. One option is to call File.listFiles() on the File that denotes the folder, then iterate the resulting array. To traverse trees of nested folders, use recursion.

Scanning the files of a JAR file can be done using the JarFile API ... and you don't need to recurse to traverse nested "folders".

Neither of these is particularly complicated. Just read the javadoc and start coding.

참고URL : https://stackoverflow.com/questions/11016092/how-to-load-classes-at-runtime-from-a-folder-or-jar

반응형