我正在使用 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 文件中。当我使用 AutoDetectParser 而不是 ForkParser 时,我能够毫无问题地从文件中提取元数据,但需要能够限制 Tika 内存使用,因此需要使用 ForkParser。如何让 pdf 解析与 Tika 的 ForkParser 一起工作?
这是一段代码,直到我进行解析:
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 测试机器上相同的结果,打印了一些换行符,但是没有其他的。我尝试使用 jpg 文件而不是 pdf 文件,并且 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,感谢您的反馈,请给我一些建议,以使其更简洁。