1

背景:我有一个数据供应商,它提供带有虚假字符编码的 XML 文档。它不是一个有效的编码名称(但它本质上是 ISO 8859-1。)我无法让这个供应商更改格式。

尝试使用 DOM 解析器解析这些 XML 文档会导致UnsupportedEncodingException抛出异常。这可能是正常行为,我可以通过编写Charset包装 ISO-8859-1 字符编码的 a 并编写 aCharsetProvider来支持它来解决它。当我将此提供程序添加到 时META-INF/services/java.nio.charset.spi.CharsetProvider,一切正常,并且我的 Charset 用于读取 XML,无需额外编码。

这是我无法解决的问题:如何让 Hadoop 识别这个 Charset 和 CharsetProvider。我正在运行 Hadoop 作业以从 HDFS 读取序列文件,其中每条记录都是上述 XML 文档之一。我无法让 DOM 解析器识别和使用我的 Charset。该系统运行 Java 1.6、Hadoop 0.20.2,XML 解析器是 Java 1.6 中内置的内部 Xerces 解析器。

一些额外的细节:

我可以通过执行以下操作(使用“上下文类加载器”)强制 CharsetProvider 在我的代码中手动加载,但我仍然无法实例化 Charset,并且 XML 解析失败:

ClassLoader cl = Thread.currentThread().getContextClassLoader();
ServiceLoader<CharsetProvider> serviceLoader = ServiceLoader.load(CharsetProvider.class, cl);
for (CharsetProvider i : serviceLoader) {
    LOG.info("CharsetProvider[1]: " + i);
}

查看可用字符集列表,当我作为独立 Java 应用程序运行时,我看到我的编码存在,但在 Hadoop 中运行时不存在。

Set<String> charsetNames = Charset.availableCharsets().keySet();
for (String name : charsetNames) {
    LOG.info("Charset: " + name);
}

以下在 Hadoop 下失败,但在其他情况下有效:

Charset cs = Charset.forName(MY_CHARSET_NAME);

我怀疑我需要一些神奇的配置来告诉 Hadoop 加载我的 CharsetProvider,但我不知道怎么做。

4

0 回答 0