私はApache Tika 1.0を使用しています。ForkParser を使用して、pdf ファイルを解析するたびに、次の NoClassDefFoundException が発生します。
java.lang.NoClassDefFoundError: org/apache/tika/fork/MemoryURLStreamHandler$Record
at org.apache.tika.fork.MemoryURLStreamHandler.createURL(MemoryURLStreamHandler.java:46)
at org.apache.tika.fork.ClassLoaderProxy.findResource(ClassLoaderProxy.java:73)
at java.lang.ClassLoader.getResource(ClassLoader.java:977)
at org.apache.log4j.helpers.Loader.getResource(Loader.java:96)
at org.apache.log4j.LogManager.<clinit>(LogManager.java:105)
at org.apache.log4j.Logger.getLogger(Logger.java:104)
at org.apache.commons.logging.impl.Log4JLogger.getLogger(Log4JLogger.java:289)
at org.apache.commons.logging.impl.Log4JLogger.<init>(Log4JLogger.java:109)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(LogFactoryImpl.java:1116)
at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:914)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:604)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:336)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:310)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)
at org.apache.pdfbox.pdfparser.BaseParser.<clinit>(BaseParser.java:58)
at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1087)
at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1053)
at org.apache.tika.parser.pdf.PDFParser.parse(PDFParser.java:80)
at org.apache.tika.parser.CompositeParser.parse(CompositeParser.java:242)
at org.apache.tika.parser.CompositeParser.parse(CompositeParser.java:242)
at org.apache.tika.parser.AutoDetectParser.parse(AutoDetectParser.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tika.fork.ForkServer.call(ForkServer.java:136)
at org.apache.tika.fork.ForkServer.processRequests(ForkServer.java:116)
at org.apache.tika.fork.ForkServer.main(ForkServer.java:64)
jar を調べると、MemoryURLStreamHandler$Record が tika-core jar ファイルに存在することがわかります。ForkParser の代わりに AutoDetectParser を使用すると、問題なくファイルからメタデータを抽出できますが、Tika のメモリ使用量を制限できる必要があるため、ForkParser を使用する必要があります。Tika の ForkParser で動作するように PDF 解析を行うにはどうすればよいですか?
解析を行うところまでのコードのスニペットを次に示します。
public static FileAnalysis analyze(File f) throws java.io.FileNotFoundException{
FileInputStream fis = null;
ToXMLContentHandler contentHandler = new ToXMLContentHandler();
Metadata metadata = new Metadata();
ParseContext context = new ParseContext();
ForkParser parser = new ForkParser();
parser.setJavaCommand(props.getProperty("forkJavaCommand", "java") + " " +
props.getProperty("forkJavaMemory", "-Xmx64m"));
parser.setPoolSize(1);
fis = new FileInputStream(f);
try {
parser.parse(fis, contentHandler, metadata, context);
} catch (Throwable e) {
logger.error("Exception while analyzing file\n" +
"CAUTION: metadata may still have useful content in it!\n" +
"Exception:\n" + e, e);
}
編集#1
「-f」オプションを使用して Tika 1.0 と Tika 0.10 CLI アプリの両方をテストしたところ、Mac OS-X 用の SoyLatte Java 6 ポートを使用しているときに IOException (Broken Pipe) を受け取りました。ポートは開発マシンでのみ実行されているため、次のように「-f」スイッチを使用して Linux テスト マシンで CLI アプリ (1.0 と 0.10 の両方) を実行しました。
java -jar tika-app-1.0.jar -f /path/to/my/file.pdf
例外は発生しなくなりましたが、出力も得られませんでした。これは奇妙だと思いましたが、まだ機能しているのではないかと思いました。
Mac OS-X ターミナルですべての環境変数の設定を解除し、OS-X の組み込み Java 6 で上記と同じように Tika CLI を実行しようとしました。Linux テスト マシンと同じ結果が得られました。いくつかの改行が出力されますが、他には何もありません。私はpdfファイルの代わりにjpgファイルを試してみました.tikaアプリは宣伝されているメタデータを含むxhtmlドキュメントを印刷しました! 次にdocxファイルを試してみましたが、pdfのように何も印刷されません。
編集#2
小さなテスト Java プログラムを作成し、それをアプリケーションのコンテキストの外に配置して、新しい環境で実行できるようにしました。
import java.io.File;
import java.io.FileInputStream;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.fork.ForkParser;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.sax.ToXMLContentHandler;
import org.apache.tika.Tika;
public class ForkParserTest {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("must be passed the file to be parsed as the first argument");
return;
}
try {
File f = new File(args[0]);
FileInputStream fis = null;
ToXMLContentHandler contentHandler = new ToXMLContentHandler();
Metadata metadata = new Metadata();
ParseContext context = new ParseContext();
ForkParser parser = new ForkParser();
fis = new FileInputStream(f);
parser.parse(fis, contentHandler, metadata, context);
System.out.println(contentHandler.toString());
} catch (Exception e) {
System.out.println("Exception caught in main");
e.printStackTrace();
}
return;
}
}
こんな感じでまとめました
javac -cp /path/to/tika-app-1.0.jar ForkParserTest.java
そしてそのまま走った
java -cp /path/to/tika-app-1.0.jar:${PWD} ForkParserTest /path/to/file.pdf
jpegでもテストしました。Tika CLI アプリとまったく同じように動作し、jpg の XHTML ドキュメントを印刷しますが、pdf または docx ファイルは何も印刷しません。
この問題を解決する方法を知っている人がいたら教えてください!また、このテストを pdf ファイルまたは docx ファイルで実行し、実際に印刷する結果が得られた場合は、その方法も教えてください。
ありがとう!
また、stackoverflow に投稿するのはかなり新しいものです。これが完全に tl;dr である場合は、フィードバックをいただければ幸いです。これをより簡潔にする方法を提案してください。