gpt4 book ai didi

java - 通过反射运行 main() 时 ClassNotFound 但与 java -jar 一起工作正常

转载 作者:太空宇宙 更新时间:2023-11-04 13:44:43 27 4
gpt4 key购买 nike

我有一个 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);

堆栈跟踪如下(删除了详细信息):

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); 解决了这个问题:

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

关于java - 通过反射运行 main() 时 ClassNotFound 但与 java -jar 一起工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30983372/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com