Почему ForkParser Тики выдает ошибку NoClassDefFoundError, когда парсер автоопределения работает нормально? - PullRequest
5 голосов
/ 08 декабря 2011

Я использую 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 $ существует в файле jar-файла tika-core.Когда я использую AutoDetectParser вместо ForkParser, я могу без проблем извлекать метаданные из файлов, но должен иметь возможность ограничивать использование памяти Tika, поэтому мне необходимо использовать ForkParser.Как я могу получить разбор pdf для работы с Tika's 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);
    }

Edit # 1

Iпротестировал CLI-приложение Tika 1.0 и Tika 0.10 с опцией «-f» и получал IOException (Broken Pipe) при использовании порта Java 6 SoyLatte для Mac OS-X.Порт запускается только на моей машине для разработки, поэтому я запустил приложение CLI (как 1.0, так и 0.10) на машине тестирования linux с ключом -f следующим образом:

java -jar tika-app-1.0.jar -f /path/to/my/file.pdf

Я больше не получал исключение, но я также не получал никакого вывода.Я нашел это странным, но подумал, что он все еще может работать, просто не производя никакого вывода (навсегда оптимист, я думаю).

Я сбросил все свои переменные окружения в моем терминале Mac OS-X и попытался запуститьTika CLI, как и выше, с OS-X, встроенным в java 6. Я получил тот же результат, что и на тестовой машине linux, напечатаны несколько новых строк, но больше ничего.Я попробовал файл jpg вместо файла pdf, и приложение tika распечатало документ xhtml с метаданными, как было объявлено!Затем я попробовал файл docx, но, как и pdfs, ничего не печатает.

Edit # 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, где печатает документ XHTML для jpg, но ничего не печатает для файлов pdf или docx.

Если кто-нибудь знает, как решить эту проблему, пожалуйста, дайте мне знать!Кроме того, если вы запускаете этот тест на файлах pdf или docx и фактически получаете результаты для печати, пожалуйста, также дайте мне знать, как вы это сделали.

Спасибо!

Я также довольно новичокдля публикации в stackoverflow, если это полностью tl; dr, обратная связь приветствуется, дайте мне советы, как сделать это более кратким.

...