java - 服务加载器没有找到服务提供者类,即使类与 META-INF/services 在同一个 JAR 文件中

标签 java c++ java-native-interface

我成功运行了一个 C++ 应用程序,该应用程序将 JAR 文件作为类路径参数加载到 JVM 中。然后,应用程序成功地使用 JNI 调用来执行此 JAR 文件中的 .class 文件中定义的各种函数。

.jar 文件的目录结构中包含一组第 3 方 .class 文件 - 从 jai_imageio.jar 合并的文件(这些 .class 文件及其完整的目录结构使用 Intellij 合并到这个单个 .jar 文件中主意)。合并的 .jar 文件中还包括原始 jai_imageio.jar 的 manifest.mf 中的行 - 特别是 implementation-title 和相关行。此外,meta-inf/services 文件夹也存在,也是从 jai_imageio.jar 复制而来的。 services 目录中列出的各种服务看起来都是正确的。

特别是,.jar 文件中 meta-inf/services 文件夹中的 javax.imageio.spi.ImageOutputStreamSpi 包含单行 com.sun .media.imageioimpl.stream.ChannelImageOutputStreamSpi,并且在 .jar 文件中有一个对应于该行的类:com/sun/media/imageioimpl/stream/ChannelImageOutputStreamSpi。类

但是,当 Java 代码执行以下行时:

ImageIO.write(image, "tiff", file); // Assume 'image' is a BufferedImage and 'file' is a File

...它抛出一个异常:

java.util.ServiceConfigurationError: javax.imageio.spi.ImageOutputStreamSpi:
Provider com.sun.media.imageioimpl.stream.ChannelImageOutputStreamSpi not found

...即使该类存在于同一个 .jar 文件中,如上所述。

有人可以解释为什么会发生此错误,以及我应该如何解决它。

最佳答案

来自这份文件 http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/invocation.html

“当线程附加到 VM 时,上下文类加载器是引导加载器。”

任何通过 AttachCurrentThread() 连接到 JVM 的 native 线程只能获得引导类加载器,甚至不能获得系统类加载器。除非您明确修复新线程的上下文类加载器,否则 ServiceLoader 引用的类将不可用。

这可以像这样完成:

java.lang.Thread.currentThread().setContextClassLoader(
    java.lang.ClassLoader.getSystemClassLoader()
);

关于java - 服务加载器没有找到服务提供者类,即使类与 META-INF/services 在同一个 JAR 文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10514495/

相关文章:

java - 无法使用 Selenium webdriver 切换到 iframe

java - 带有 xml 或 json 作为参数的 restful webservice

c++ - 如何通过cstdlib系统传递带空格的参数

c++ - 保留临时 std::string 并返回 c_str() 以防止内存泄漏

Javah 工具错误 : Could not find class file for hellojni

java - Android System.loadLibrary 崩溃

java - Spring MVC Controller 在Servlet 2.5中异步执行任务

java - 从 OpenCV 的 LBP 实现中提取特征向量

c++ - 在 Linux 上使用 g++ 输出错误,在 Windows 上更正

java - 如何在使用JNI的java项目中处理DLL事件?