web-dev-qa-db-ja.com

Java-8でxmlを非整列化する際にエラーが発生する

次のコードは、Java 7

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

String xmlString = '<xml ..... ';

StringReader reader = new StringReader(xmlString);

JAXBContext jc = JAXBContext.newInstance(MyClass.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
MyClass myClass = (MyClass) unmarshaller.unmarshal(reader);
....

ここでJava 8にアップグレードする必要があり、コードを実行するとこの例外が発生します。

Sep 03, 2014 1:42:47 PM com.Sun.xml.internal.bind.v2.util.XmlFactory createParserFactory
SCHWERWIEGEND: null
org.xml.sax.SAXNotRecognizedException: Feature: http://javax.xml.XMLConstants/feature/secure-processing
    at org.Apache.xerces.jaxp.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.Java:100)
    at com.Sun.xml.internal.bind.v2.util.XmlFactory.createParserFactory(XmlFactory.Java:114)
    at com.Sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.getXMLReader(UnmarshallerImpl.Java:139)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.Java:157)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.Java:214)

私は question が同様の問題をターゲットにしていることを知っていますが、Java 7に戻ることは私にとって解決策ではありません。

私は次のMaven依存関係を追加しようとしました

<dependency>
    <groupId>javax.xml</groupId>
    <artifactId>jaxp-api</artifactId>
    <version>1.4</version>
</dependency>

しかし、それは結果を変更しなかったので、私はそれを削除しました(情報については@BlaiseDoughanに感謝します、これはJava 6)に含まれています)

ヒントは大歓迎です、ありがとう。

28
mmx73

これは依存関係の問題でした。

ここに私が問題を解決した方法があります:

  1. 以下に添付する簡単なコードで新しいMavenプロジェクトを作成します。プログラムはエラーで正常にクラッシュし、構造を解析できなかったので問題ありません。
  2. 依存関係をプロジェクトpom.xmlにコピーすると、プログラムがクラッシュするはずです(上記のとおり)

  3. 「悪い」依存関係を見つけるために、好みの方法(良い推測、二分法、1行1列)の後に依存関係を削除します。誰かがより良い(より専門的な)方法を持っているかもしれませんが、これは私のために働きました。

今、あなたは何をすべきかを決めることができます。多分新しいバージョンが利用可能です。私たちの場合、それは私が除外できるコラージュのパッケージを含んでいる、コラージュの独自のパッケージでした。

public class Test {
    public Test() {
    }
    public static void main(String[] args) {
        try {
            StringReader reader = new StringReader("<xml></xml>");
            JAXBContext jc = JAXBContext.newInstance(TestXML.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            TestXML testXMLs = (TestXML) unmarshaller.unmarshal(reader);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

およびtestXMLクラス

@XmlRootElement(name="rss")
@XmlAccessorType(XmlAccessType.FIELD)
public class TestXML {   
    public TestXML() {
    }

    @XmlElementWrapper(name="channel")
    @XmlElement(name="item")
    private int i ;

    public int getI() {
        return i;
    }    
    public void setI(int i) {
        this.i = i;
    }
}

ところで:私の場合はそうでした

<dependency>
    <groupId>jcs</groupId>
    <artifactId>jcs</artifactId>
    <version>1.3</version>
</dependency>

お役に立てば幸いです。

8
mmx73

同様の問題がありました-私たちの主任開発者は私たちに役立つソリューションを見つけました。

この依存関係をいくつかのpom.xmlファイルに追加しました

気にする人にとっては、デフォルトで古いバージョンのxercesを取り込むため、失敗していたSonarの単体テストは明らかに失敗していました。プルするバージョンは、Java 8.のJAX-Bと互換性がありません。このライブラリは、本番コードでは使用されず、Cobaturaのみです。したがって、修正は、より新しいxercesのバージョン(2.11.0)これは、pomファイルに依存関係を追加することで実行されます。

<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.11.0</version>
    <scope>test</scope>
</dependency>
46
Robert H.

ここでは、Xerces implが主犯です。それを除く。 Jdkには、jaxbパーサーが組み込まれています。これは必要ありません。

そのため、Mavenの場合にその依存関係が親プロジェクトからのものである場合、直接削除できない場合に除外タブを使用します。

<exclusion>
                 <groupId>xerces</groupId>  
            <artifactId>xercesImpl</artifactId> 
                </exclusion>

この問題を検出するのが非常に難しい理由は、通常、jaxb非整列化コードを記述するときです。

tryブロックでアンマーシャリングを実行し、jaxb例外をキャッチしてから、エラーで何でもします。

しかし、このjar(xercesimpl)の原因となっているパーサーは、途中でランタイム例外をスローし、エラーがログに記録されず、注意深いデバッグ後にのみ検出されます。以下のコードスニペットを見てください

try {
JAXBContext context = JAXBContext.newInstance(YourClass.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            YourClass object = (YourClass)unmarshaller.unmarshal(new StringReader("SomeXmlInString"));


}

catch (JAXBException e){
e.printStackTrace();

}

ここで、xercesImplにより、アンマーシャラーは(通常のjaxbパーサーの代わりに)他のサックスパーサーを使用して、jaxbexceptionまたはそのサブクラスの1つを予期しているcatchブロックでキャッチされない異なる例外をスローします。

22
shashwatZing

これに対する別の可能な解決策は、システム変数を追加することです:

私は私のために働いたmaven Tomcatプラグインでこれらを使用しました:

<javax.xml.parsers.DocumentBuilderFactory>com.Sun.org.Apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl</javax.xml.parsers.DocumentBuilderFactory>
<org.xml.sax.parser>com.Sun.org.Apache.xerces.internal.parsers.SAXParser</org.xml.sax.parser>
<javax.xml.parsers.SAXParserFactory>com.Sun.org.Apache.xerces.internal.jaxp.SAXParserFactoryImpl</javax.xml.parsers.SAXParserFactory>

ただし、次のように設定することもできます。

Java -Dorg.xml.sax.parser="com.Sun.org.Apache.xerces.internal.parsers.SAXParser" \
-Djavax.xml.parsers.DocumentBuilderFactory="com.Sun.org.Apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" \
-Djavax.xml.parsers.SAXParserFactory="com.Sun.org.Apache.xerces.internal.jaxp.SAXParserFactoryImpl"

またはSystem.setPropertyを使用することもできます。

System.setProperty("org.xml.sax.driver", "com.Sun.org.Apache.xerces.internal.parsers.SAXParser");
System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.Sun.org.Apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
System.setProperty("javax.xml.parsers.SAXParserFactory","com.Sun.org.Apache.xerces.internal.jaxp.SAXParserFactoryImpl");
15
Mitch1077487

バーナードとブレイズの回答は非常に役に立ちました。私の場合、JDK 7を使用しているため、解決策は、依存関係の1つに含まれていたxercesのサブ依存関係を除外することでした。

<dependency>
  <groupId>org.Apache.axis</groupId>
  <artifactId>axis</artifactId>
  <version>1.4.1-SNAPSHOT</version>
  <exclusions>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xercesImpl</artifactId>
    </exclusion>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xmlParserAPIs</artifactId>
    </exclusion>
  </exclusions>
</dependency>
5
pimlottc

JAXBの実装は、バージョン6以降のJava SEに含まれています。Maven依存関係(おそらくバージョンの競合を引き起こしている)を削除すると、すべてが機能するはずです。

5
bdoughan

私のプロジェクトでこの問題を解決したのは、2番目のMitchのソリューションですが、

Java -Djavax.xml.parsers.SAXParserFactory="com.Sun.org.Apache.xerces.internal.jaxp.SAXParserFactoryImpl"
2
foxpaps

SAXparserを使用するのは悪夢です。これはJavaで最も広く使用されているXMLパーサーであり、すべてが直接または間接的に使用されています。 JDK 8にはJAXBがすでに利用可能です。したがって、JDK 8を使用している場合は、Maven依存関係を削除することが唯一の可能な方法です。私もこの問題を抱えていたので、Mavenの依存関係を削除しようとしましたが、起こりませんでした。それから、JavaとVOILLAが成功したら、古いバージョンに戻らない理由を考えました。現在、jdk 7を使用していますが、テストはスムーズに実行されます。これが唯一の解決策だと思います。

1
Naveen Kumar

XMLドキュメントを作成し、非整列化します。それは私のために働いた。 JAXBContext jc = JAXBContext.newInstance(Message.class);

        InputStream stream = new ByteArrayInputStream( string.getBytes( StandardCharsets.UTF_8 ) );
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse( stream );

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Message msg = ( Message ) unmarshaller.unmarshal( doc );
1
madhugeeth

私は同様の問題に直面していましたが、この問題はxerces jarとxercesImpl jarのバージョンに大きな違いがある場合に発生します。これを解決するために、xerces-2.9.0とxercesImpl-2.9.1を使用しましたが、問題はなくなりました。

0

また、この問題を解決し、jdkバージョンとjreバージョンを同じにする必要があることに気付きました。そうしないと、バージョンの不一致が問題の原因となります。

この問題に出会った人はjdk1.6とjre 1.8を使用しますが、jdk1.6に変更すると問題はなくなりました。

0
James Liu