7

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

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

特别是,javax.imageio.spi.ImageOutputStreamSpimeta-inf/services.jar 文件中的文件夹中包含单行 .jar 文件中com.sun.media.imageioimpl.stream.ChannelImageOutputStreamSpi,在该行所指示的目录中,有一个与此相对应的类:com/sun/media/imageioimpl/stream/ChannelImageOutputStreamSpi.class.

但是,当 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 文件中,如上所述。

有人可以解释为什么会发生这个错误,我应该怎么做才能解决它。

4

1 回答 1

2

从这个文档 http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/invocation.html

“当一个线程连接到虚拟机时,上下文类加载器就是引导加载器。”

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

这可以像这样完成:

java.lang.Thread.currentThread().setContextClassLoader(
    java.lang.ClassLoader.getSystemClassLoader()
);
于 2014-09-18T21:07:04.940 回答