2

mbox 形式の電子メール メッセージを解析しようとしています。ただし、Tika はこれらのメッセージで TNEFParser を使用しようとし続け、エラーが発生します。

2012-08-21 17:44:42,139 FATAL org.apache.hadoop.mapred.Child: Error running child : java.lang.OutOfMemoryError: Java heap space
    at org.apache.poi.hmef.attribute.TNEFAttribute.<init>(TNEFAttribute.java:50)
    at org.apache.poi.hmef.attribute.TNEFAttribute.create(TNEFAttribute.java:76)
    at org.apache.poi.hmef.HMEFMessage.process(HMEFMessage.java:74)
    at org.apache.poi.hmef.HMEFMessage.process(HMEFMessage.java:98)
    at org.apache.poi.hmef.HMEFMessage.process(HMEFMessage.java:98)
    at org.apache.poi.hmef.HMEFMessage.<init>(HMEFMessage.java:63)
    at org.apache.tika.parser.microsoft.TNEFParser.parse(TNEFParser.java:80)
    at org.apache.tika.parser.CompositeParser.parse(CompositeParser.java:242)
    at org.apache.tika.parser.mail.MailContentHandler.body(MailContentHandler.java:102)
    at org.apache.james.mime4j.parser.MimeStreamParser.parse(MimeStreamParser.java:133)
    at org.apache.tika.parser.mail.RFC822Parser.parse(RFC822Parser.java:76)
    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 org.lab41.asf.etl.mapred.MailboxToTextMapper.parse(MailboxToTextMapper.java:124)
    at org.lab41.asf.etl.mapred.MailboxToTextMapper.map(MailboxToTextMapper.java:88)
    at org.lab41.asf.etl.mapred.MailboxToTextMapper.map(MailboxToTextMapper.java:45)
    at org.apache.avro.mapred.HadoopMapper.map(HadoopMapper.java:81)
    at org.apache.avro.mapred.HadoopMapper.map(HadoopMapper.java:34)
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:391)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:325)
    at org.apache.hadoop.mapred.Child$4.run(Child.java:266)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:396)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1278)
    at org.apache.hadoop.mapred.Child.main(Child.java:260)

Tika が TNEFParser を使用するのを防ぐことは可能ですか? どんな提案も役に立ちます。

4

3 に答える 3

5

これは、@Gagravarr によって提案された構成バージョンです。

まず、tika-config.xml ファイルを作成します。

<properties>
  <parsers>

    <!-- use the default parser in most cases, it is a composite of all 
         the parsers listed in META-INF/services/org.apache.tika.parser.Parser -->
    <parser class="org.apache.tika.parser.DefaultParser"/>

    <!-- Disable tnef extraction-->    
    <parser class="org.apache.tika.parser.EmptyParser">
      <mime>application/vnd.ms-tnef</mime>
      <mime>application/x-tnef</mime>
    </parser>

  </parsers>
</properties>

次に、この構成から TikaConfig を作成します (クラスパスのどこかにあると仮定します)。

ClassLoader loader = Thread.currentThread().getContextClassLoader();
TikaConfig config = new TikaConfig(loader.getResource("tika-config.xml"), loader);

新しいパーサーを作成するか、Tika ファサードを使用する場合は、構成を渡します。

AutoDetectParser parser = new AutoDetectParser(config);
ParseContext context = new ParseContext();
context.set(Parser.class, parser);
parser.parse(input, handler, metadata, context);

TNEF として識別されたドキュメントは、コンテンツを返さず、実際には何も解析しない EmptyParser を使用します。

これは事実上ブラックリストです。ホワイトリストが必要な場合は、XML から DefaultParser を削除し、各パーサーとそのメタデータを手動で構成する必要があります。

于 2013-01-30T05:06:59.230 に答える
3

長期的な修正については、これを Apache Tika のバグとして報告し、問題のあるファイルをバグ レポートに添付して、プロジェクトと協力してバグを修正する必要があります。

短期的には、Tika-Parsers jar ファイルを解凍し、ファイルを編集してMETA-INF/services/org.apache.tika.parser.Parser、リストから TNEF パーサーを削除します。これにより、AutoDetectParser による自動ロードと使用が停止します

Tika Parsers jar ファイルを変更しないと、少し面倒です。利用可能なオプションは 2 つあります。1 つは、デフォルトのインスタンスに依存するのではなく、自分で TikaConfig インスタンスを作成し、限られたパーサーのリストのみを提供することです。ホワイトリストまたはブラックリストに登録するかどうかに応じて、それが簡単な場合と難しい場合があります。または、最後に登録された MIME タイプのパーサーが勝つという事実を利用することもできます。そのため、services ファイルを含む独自の jar と、独自のダミー パーサーを作成します。そのパーサーに TNEF mimetype を処理することを宣言させますが、何も実行させません。jar をクラスパスに追加すると、代わりにダミーのパーサーが使用されます

于 2012-08-22T10:08:31.607 に答える
3

これは、 @Gagravarrによって提案されたプログラム バージョンです。登録された不要なパーサーをEmptyParser.

private Tika createTika(final Parser... unnecessaryParsers) 
        throws TikaException, IOException {
    final TikaConfig config = new TikaConfig();
    final AutoDetectParser autoDetectParser = new AutoDetectParser(config);

    final Set<MediaType> unnecessaryMimeTypes = 
        getUnnecessaryMediaTypes(unnecessaryParsers);
    disableParsing(autoDetectParser, unnecessaryMimeTypes);

    final Detector detector = config.getDetector();
    final Tika tika = new Tika(detector, autoDetectParser);
    return tika;
}

private Set<MediaType> getUnnecessaryMediaTypes(
        final Parser... unnecessaryParsers) {
    final Set<MediaType> unnecessaryTypes = new HashSet<MediaType>();
    for (final Parser unnecessaryParser: unnecessaryParsers) {
        final Set<MediaType> supportedTypes = 
            unnecessaryParser.getSupportedTypes(null);
        unnecessaryTypes.addAll(supportedTypes);
    }
    return unnecessaryTypes;
}

private void disableParsing(final CompositeParser mainParser, 
        final Set<MediaType> unnecessaryMediaTypes) {
    final EmptyParser emptyParser = new EmptyParser();

    final Map<MediaType, Parser> parsers = mainParser.getParsers();
    for (final MediaType unnecessaryType: unnecessaryMediaTypes) {
        parsers.put(unnecessaryType, emptyParser);
    }

    mainParser.setParsers(parsers);
}

使用法:

final Parser unnecessaryParser = new MP4Parser();
final Tika tika = createTika(unnecessaryParser);

TIKA-1040: Could not delete temporary fileを回避するためにも使用できます。

于 2013-01-19T17:23:09.590 に答える