PDFドキュメントをjpeg画像に変換するWebサービス(ジャージーベース)を開発しようとしています。私が GhostScript を選んだ理由は、GhostScript の使用経験とその結果 (特に埋め込みフォントの場合) が良かったからです。そこで、Java で GhostScript を使用する方法を検索し、Ghost4j を見つけました。
そこで、すべての Ghost4j jar をアプリケーションの lib フォルダー (これも jna.jar) に入れました。最初のテストでは、タスクを複数回実行すると問題が発生しました。これは、jna が複数回起動されるとエラーがスローされるためです。そこで、jna.jar を tomcat lib フォルダーに入れました。これで少しはうまくいきましたが、一度に 1 つのタスクしか実行できませんでした。同時に別のものを開始しても、何も起こりませんでした。私は他のタスクを実行していないようでした。
そこでsetMaxProcessCount(2);
、アプリケーションが一度に複数のタスクを実行できるようにしました。これが私のコードです:
private static void generateImages(String inputFile, String outputPath) throws IOException, RendererException, org.ghost4j.document.DocumentException {
PDFDocument document = new PDFDocument();
document.load(new File(inputFile));
SimpleRenderer renderer = new SimpleRenderer();
renderer.setMaxProcessCount(2);
renderer.setResolution(150);
renderer.setAntialiasing(4);
System.setProperty("jna.library.path", "C:\\Program Files\\gs\\gs9.09\\bin\\");
List<Image> images = renderer.render(document);
for (int i = 0; i < images.size(); i++) {
ImageIO.write((RenderedImage) images.get(i), "jpeg", new File(outputPath + File.separatorChar + (i + 1) + ".jpeg"));
}
}
しかし、タスクを実行しようとすると、Ghost4j は次のエラーをスローします。
org.ghost4j.renderer.RendererException: java.lang.Exception: java.lang.NoClassDefFoundError: com/sun/jna/Structure
at org.ghost4j.renderer.AbstractRemoteRenderer.render(AbstractRemoteRenderer.java:133)
at PdfResource.ConversionTask.generateImages(ConversionTask.java:218)
at PdfResource.ConversionTask.exec(ConversionTask.java:58)
at PdfResource.Task.run(Task.java:86)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.Exception: java.lang.NoClassDefFoundError: com/sun/jna/Structure
at gnu.cajo.invoke.Remote.invoke(Remote.java:594)
at gnu.cajo.invoke.Remote.invoke(Remote.java:722)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:160)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at com.sun.proxy.$Proxy165.invoke(Unknown Source)
at gnu.cajo.invoke.Remote.invoke(Remote.java:565)
at org.ghost4j.renderer.AbstractRemoteRenderer.render(AbstractRemoteRenderer.java:126)
... 4 more
Caused by: java.lang.NoClassDefFoundError: com/sun/jna/Structure
at org.ghost4j.renderer.SimpleRenderer.run(SimpleRenderer.java:68)
at org.ghost4j.renderer.AbstractRemoteRenderer.remoteRender(AbstractRemoteRenderer.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at gnu.cajo.invoke.Remote.invoke(Remote.java:582)
at gnu.cajo.invoke.Remote.invoke(Remote.java:722)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
... 1 more
Caused by: java.lang.ClassNotFoundException: com.sun.jna.Structure
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 23 more
Ghost4j が起動している追加の JVM と何か関係があると思いますが、Tomcat が使用するのと同じクラスパスを使用していないようですが、私は実際には Java の専門家ではなく、この問題を解決する方法がわかりません。