簡體   English   中英

通過反射運行main()時使用ClassNotFound,但是與java -jar一起使用時效果很好

[英]ClassNotFound when running main() through reflection but works fine with java -jar

我有一個jar文件,可以使用java -jar my-jar-file.jar

但是現在我必須使用反射從另一個Java程序中加載主類,並且當我這樣做時,我會收到ClassNotFoundException: javax.mail.MessagingException

我用於執行此操作的代碼:

URLClassLoader loader = URLClassLoader.newInstance(new URL[]{new File("my-jar-file.jar").toURI().toURL()});
Class<?> serverClass = loader.loadClass("com.foo.bar.application.MyMain");

Method main = serverClass.getMethod("main", String[].class);
String[] params = new String[]{"-flag", "value"};
main.invoke(null, (Object) params);

stacktrace是這樣的(刪除的詳細信息):

Exception in thread "main" java.lang.reflect.InvocationTargetException
Caused by: java.lang.NoClassDefFoundError: javax/mail/MessagingException
Caused by: java.lang.ClassNotFoundException: javax.mail.MessagingException

我還嘗試將System.getProperty("java.class.path")中的條目添加到傳遞給類加載器的URL數組中,但是也沒有運氣。

這個錯誤對我來說似乎很合理,因為jar文件不包含javax.mail.MessagingException (實際上不包含javax.mail軟件包),但是當我只執行java -jar my-jar-file.jar時,它如何工作?

如何解決此問題? 謝謝

編輯:

添加了MANIFEST.MF內容:

Manifest-Version: 1.0
Main-Class: com.foo.bar.application.MyMain
Implementation-Version: 1.5.4

編輯2:

值得一提的是jar文件在META-INF目錄中包含一個javamail.providers文件。 假設這種方式可以使該jar正常工作,但是我該如何以編程方式執行相同操作?

javamail.providers內容:

# AWS Mail Provider
protocol=aws; type=transport; class=com.amazonaws.services.simpleemail.AWSJavaMailTransport; vendor=Amazon Web Services LLC;

好的,我通過添加Thread.currentThread().setContextClassLoader(loader);來解決此問題Thread.currentThread().setContextClassLoader(loader);

URLClassLoader loader = URLClassLoader.newInstance(new URL[]{new File("my-jar-file.jar").toURI().toURL()});
Thread.currentThread().setContextClassLoader(loader);
Class<?> serverClass = loader.loadClass("com.foo.bar.application.MyMain");

Method main = serverClass.getMethod("main", String[].class);
String[] params = new String[]{"-flag", "value"};
main.invoke(null, (Object) params);

現在一切都按預期工作,並且我不再收到ClassNotFoundException了,但是我仍然不太明白為什么會這樣。 在我看來,它試圖通過其他ClassLoader加載其他類/資源,從而未能做到這一點,並且通過調用setContextClassLoader我明確地說要使用提供的ClassLoader

暫無
暫無

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

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