validator vs configuration

バリデーションをするのに、XMLを読み込もうとしたらこんな例外になってしまった。
src*1

    InputStream in = loader.getResourceAsStream("hoge_validate.xml");
    resourcess = new ValidatorResources(in);


例外の内容(適当に折り返し)

[ERROR] Digester - Digester.getParser:  <org.xml.sax.SAXNotRecognizedException: 
    Feature: http://apache.org/xml/features/validation/dynamic>org.xml.sax.SAXNotRecognizedException:
    Feature: http://apache.org/xml/features/validation/dynamic
        at org.apache.xerces.jaxp.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:100)
        at org.apache.commons.digester.parser.XercesParser.configureXerces(XercesParser.java:185)
(中略)
java.lang.NullPointerException
        at org.apache.commons.digester.Digester.getXMLReader(Digester.java:891)
        at org.apache.commons.digester.Digester.parse(Digester.java:1591)
        at org.apache.commons.validator.ValidatorResources.<init>(ValidatorResources.java:156)
        at org.apache.commons.validator.ValidatorResources.<init>(ValidatorResources.java:133)


なんのこっちゃという内容なのだが、ここをヒントに(見た名前だと思えばid:koichikさんである)。
http://ml.seasar.org/archives/seasar-user/2005-September/000722.html


Xercesのソースが怪しいということで、辿っていくと・・・
org.apache.commons.digester.ParserFeatureSetterFactory

    try{
        // Use reflection to avoid a build dependency with Xerces.
        Class versionClass = 
                        Class.forName("org.apache.xerces.impl.Version");
        isXercesUsed = true;
    } catch (Exception ex){
        isXercesUsed = false;
    }
public static SAXParser newSAXParser(Properties properties)
        throws ParserConfigurationException, 
               SAXException,
               SAXNotRecognizedException, 
               SAXNotSupportedException {

    if (isXercesUsed){
        return XercesParser.newSAXParser(properties);
    } else {
        return GenericParser.newSAXParser(properties);
    }
}


つまり、"org.apache.xerces.impl.Version"がクラスパスにあるとxercesをパーサーにしてしまい、結果必要もないfeatureうんたらがでてくると。


プロジェクトのなかでこやつを利用しているのは、テストで利用しているcommons-configurationのみ。
まぁ切り取ってしまっても問題ないでしょう。

    <dependency>
      <groupId>commons-configuration</groupId>
      <artifactId>commons-configuration</artifactId>
      <version>1.3</version>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <artifactId>xerces</artifactId>
          <groupId>xerces</groupId>
        </exclusion>
      </exclusions>
    </dependency>


これでOK。


xercesをパーサーにするともう一つ問題があって、どうもcommons-configuration自身もWindows-31Jを扱えない「場合がある」ようなのだ。
でも環境によっては読めてしまうので、ちょっと謎なのだけど。
この辺りはクラスがロードされる順番にもよるので、予防しておいた方がよさそうではある。
cf.http://www.ingrid.org/java/i18n/encoding/shift_jis.html