簡體   English   中英

javassist 從 jar 加載外部類時拋出 ClassNotFoundException

[英]javassist throws ClassNotFoundException when loading external classes from jar

我正在嘗試使用 javassist 加載外部 jar 文件並在運行時調用其 main 方法,但是當我嘗試使用以下代碼執行此操作時:

    File file = new File("C:\\Users\\MainPC\\Desktop\\test.jar");
    ClassPool cp = ClassPool.getDefault();
    cp.insertClassPath(file.getAbsolutePath());

    Class<?> MainClass = cp.get("TestPackage.MainClass").toClass();
    MainClass.getMethod("main", String[].class).invoke(null, new Object[] {args});

它拋出以下異常:

Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at ReflectionTests.main(ReflectionTests.java:99)

Caused by: java.lang.NoClassDefFoundError: TestPackage/OtherClass
    at TestPackage.MainClass.main(Unknown Source)
    ... 5 more

Caused by: java.lang.ClassNotFoundException: TestPackage.OtherClass
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    ... 6 more

當我僅使用內置的 java 反射 api 嘗試相同的事情時,它沒有問題:

    File file = new File("C:\\Users\\MainPC\\Desktop\\test.jar");
    URLClassLoader cl = new URLClassLoader(new URL[] {new URL("jar:file:"+file.getAbsoluteFile()+"!/")});
    
    Class<?> clazz = cl.loadClass("TestPackage.MainClass");
    clazz.getMethod("main", String[].class).invoke(null, new Object[] {args});

(上面沒有拋出異常並按預期調用jar文件的main方法)

這讓我相信我在 javassist 中做錯了什么(特別是 jar 文件類的加載)。 有人可以向我解釋它是什么嗎? 我應該提到 jar 文件只包含 2 個類:MainClass.class 和 OtherClass.Class。 兩者都駐留在名為 TestPackage 的包中。 似乎該錯誤與 MainClass 類在 javassist 加載時無法找到 OtherClass 類有關。

問題是,當我調用ct.toClass() ,它只將類本身暴露給我的運行時類加載器(而不是整個類池的類路徑)。 當我稍后嘗試調用這個類的 main 方法時,我的運行時類加載器嘗試執行加載另一個類的部分,它顯然不知道,因此拋出ClassNotFoundException

解決方案是使用 javassist 提供的類加載器 (javassist.Loader),它將類池作為構造函數中的參數,然后能夠正確加載和解析類池類路徑中的類。

這是我試圖實現的工作代碼示例:

    File file = new File("C:\\Users\\MainPC\\Desktop\\test.jar");
    ClassPool cp = ClassPool.getDefault();
    cp.insertClassPath(file.getAbsolutePath());

    Loader loader = new Loader(cp);
    Class<?> MainClass = loader.loadClass("TestPackage.MainClass");
    MainClass.getMethod("main", String[].class).invoke(null, new Object[] {args}); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM