我成功运行了一个 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/