2016-05-05 28 views
0

marhsal Javaオブジェクトを文字列にしようとすると、クラスキャスト例外が発生します。 libフォルダにJAXB-2.1 jarを含めました。 WASにデプロイする際には、クラスローダー戦略を親に最後に変更して、ローカルライブラリのjarファイルを最初に取得するようにしました。しかし、これはまだ以下のメッセージでクラスキャストの例外を投げています。このエラーの原因は何ですか?JAXBを使用したClassCastException - Websphere jarとapplicationl jar

javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/opt/was7/base/crm/java/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to wsjar:file:/prod/wesadm/wes/was7/base/profiles/sadasd/installedApps/asdadad/myapp.ear/myapp_war.war/WEB-INF/lib/jaxb-api-2.1.jar!/javax/xml/bind/JAXBContext.class. Please make sure that you are specifying the proper ClassLoader. 
     at javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:96) 
     at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:214) 
     at javax.xml.bind.ContextFinder.find(ContextFinder.java:372) 
     at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574) 
     at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522) 
     at com.my.MyClass.convertObjectToXML() 

これはconvertObjectToXML()方法です。

private <T> String convertObjectToXMLString(T obj) throws JAXBException { 
     JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass()); 
     Marshaller marshaller = jaxbContext.createMarshaller(); 

     StringWriter sw = new StringWriter(); 
     marshaller.marshal(obj, sw); 

     return sw.toString(); 

    } 

このロジックは、Tomcatにデプロイすると正常に動作します。私は、クラスローダーを親として最後に言及したにもかかわらず、WAS jarファイルが選択されている理由を理解することができません。

+0

あなたのサーバーでポリシーをチェックしましたか?ポリシーが単一の場合、ポリシーが複数の場合は各アプリケーションが独自のモードを持つ、サーバーレベルのモードがすべてのアプリケーションで強制されますhttps://www.ibm .com/support/knowledgecenter/was_beta/com.ibm.websphere.base.doc/ae/crun_classload.html%23crun_classload__crun_classload_modes – achabahe

答えて

1

あなたのアプリでJAXB api jarsをバンドルしたようです。あなたのアプリからそれらを削除し、それが動作します。これらのjarファイルが既にのWebSphereにバンドルされている(実際には、彼らはJREの一部である)と同じクラスの2つのバージョンが

+0

これはおそらく問題を解決しますが、アプリケーションのJAXB APIが失敗した理由を実際に説明していません対応するJAXB実装をアプリケーションからロードします。おそらくOPはアプリケーション内にAPI JARしか持っていなかったでしょう... –

+0

JAXBクラスはJREの一部ですので、このようなJREクラスをオーバーライドすることは悪い考えです。 JREクラスをオーバーライドする公式の方法は、jarファイルを \ lib \ endorsedフォルダに置くことです。 "javax.xml.bind.JAXBContext"プロパティを設定し、アプリケーションにjarをインクルードし、アプリのクラス読み込み順序を逆にする(親を先に)ことで、これらのクラスをオーバーライドする(確認する)ことができます。しかし、私はこれがうまくいくかどうかはわかりません.WASではなくTomcatで動作するのはなぜですか?両方の製品でクラスのロードを処理する方法が異なるためです。 – titou10

+0

WebSphereは、JVMに含まれているJAXB APIのオーバーライドをサポートしておらず、javax.xml.bind.JAXBContextの設定もサポートしていません。これは、製品自体がJAXBを内部的に使用し、デフォルトをオーバーライドすると問題が発生する可能性があるためです。おそらく、TomcatはJAXB自体を使用しないでしょう。最終的には、JAXBのオーバーライドは壊れやすく、おそらくそれを避けるのが最善です。 –

0

javax.xml.bind.ContextFinder.find(Class[] classes, Map properties)存在しているので、それがクラスローダ例外が発生しますがjaxb.property最初に探します。 見つからない場合は、それが配列を以下に工場を作成/検索しよう:

  1. システムプロパティのOSGi ServiceLoaderを使用してjavax.xml.bind.context.factory
  2. 検索
  3. 検索META-INFサービス

あなたのプログラムは、com.myのjaxb.propertyを提供していないと思います。 したがって、ファクトリクラスはWebsphere JDK /ライブラリからロードされているので、オブジェクトはJAXBContextクラスを返します。 しかし、そのクラスはあなたのWARのクラスとは異なりますので、javax.xml.bind.ContextFinderClassCastExceptionです。

関連する問題