2016-05-05 10 views
0

Я получаю исключение класса при попытке перенести объект Java в строку marhsal. Я включил JAXB-2.1 jar в папку lib. При развертывании в WAS я изменил стратегию загрузчика классов на родительский последний, чтобы сначала собрать первую банку в моей локальной библиотеке. Но это все равно бросает исключение класса из следующего сообщения. В чем причина этой ошибки?ClassCastException с JAXB - Websphere jar vs 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 берутся, хотя я упоминал загрузчик классов как последний.

+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 с вашим приложением. удалите их из своего приложения, и он будет работать. Эти банки уже в комплекте с WebSphere (на самом деле они являются частью JRE), и это вызывает исключение, поскольку загрузчик классов две версии одного и того же класса присутствуют

+0

Это, скорее всего, решит проблему, но на самом деле это не объясняет, почему API JAXB в приложении не удалось загрузите соответствующую реализацию JAXB из приложения. Возможно, у ОП был только API JAR в приложении ... –

+0

Классы JAXB являются частью JRE, поэтому неплохо переопределить классы JRE, подобные этому. Официальным способом переопределения классов JRE является размещение баннеров в папке \ lib \ endorsed. вы * можете * (для проверки) переопределить эти классы, установив свойство javax.xml.bind.JAXBContext, включите банки в ваше приложение и инвертируйте порядок загрузки класса для вашего приложения (сначала родительский). Но я не уверен, что это сработает. Почему это работает в Tomcat, а не в WAS? это связано с другим способом обработки загрузки классов в обоих продуктах. – titou10

+0

WebSphere не поддерживает переопределение API JAXB, входящего в состав JVM, и не поддерживает установку javax.xml.bind.JAXBContext. Это связано с тем, что сам продукт использует JAXB внутри себя, и переопределение значений по умолчанию может вызвать проблемы. Предположительно, Tomcat не использует JAXB. В конечном счете, переопределение JAXB является хрупким, и, вероятно, лучше всего его избежать. –

0

javax.xml.bind.ContextFinder.find(Class[] classes, Map properties) будет искать jaxb.property первым. Если не найден, попробуйте поискать/создать завод в следующей последовательности:

  1. Система собственности javax.xml.bind.context.factory
  2. Поиск с использованием OSGi ServiceLoader
  3. Поиск META-INF услуги

Я считаю, что ваша программа не предлагает jaxb.property в пакете com.my. Итак, класс фабрики загружается из WebSphere JDK/library, он вернет объект класса JAXBContext. Но этот класс отличается от того, который был в вашей WAR, поэтому javax.xml.bind.ContextFinder throw ClassCastException.