9

I have updated our projects (Java EE based running on Websphere 8.5) to use a new release of a company internal framework (and Ejb 3.x deployment descriptors rather than the 2.x ones). Since then my integration Tests fail with the following exception:

 [java.lang.ClassNotFoundException: com.ibm.xml.xlxp2.jaxb.JAXBContextFactory]

I can build the application with the previous framework release and everything works fine. While debugging i noticed that within the ContextFinder (javax.xml.bind) there are two different behaviours:

  1. Previous Version (Everything works just fine): None of the different places brings up a factory class so the default factory class gets loaded which is com.sun.xml.internal.bind.v2.ContextFactory (defined as String constant within the class).

  2. Upgraded Version (ClassNotFound): There is a resource "META-INF/services/javax.xml.bind.JAXBContext" beeing loaded successfully and the first line read makes the ContextFinder attempt to load "com.ibm.xml.xlxp2.jaxb.JAXBContextFactory" which causes the error.

I now have two questions:

  1. What sort is that resource? Because inside our EAR there is two WARs and none of those two contains a folder services in its META-INF directory.

  2. Where could that value be from otherwise? Because a filediff showed me no new or changed properties files.

No need to say i am going to read all about the JAXB configuration possibilities but if you have first insights on what could have gone wrong or help me out with that resource (is it a real file i have to look for?) id appreciate a lot. Many Thanks!

EDIT (according to comments Input/Questions):

Out of curiosity, does your framework include JAXB JARs? Did the old version of your framework include jaxb.properties?

Indeed (i am a bit surprised) the framework has a customized eclipselink-2.4.1-.jar inside the EAR that includes both a JAXB implementation and a jaxb.properties file that shows the following entry in both versions (the one that finds the factory as well as in the one that throws the exception):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

I think this is has nothing to do with the current issue since the jar stayed exactly the same in both EARs (the one that runs/ the one with the expection)

It's also not clear to me why the old version of the framework was ever selecting the com.sun implementation

There is a class javax.xml.bind.ContextFinder which is responsible for initializing the JAXBContextFactory. This class searches various placess for the existance of a jaxb.properties file or a "javax.xml.bind.JAXBContext" resource. If ALL of those places dont show up which Context Factory to use there is a deault factory loaded which is hardcoded in the class itself:

private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory";

Now back to my problem:

Building with the previous version of the framework (and EJB 2.x deployment descriptors) everything works fine). While debugging i can see that there is no configuration found and thatfore above mentioned default factory is loaded.

Building with the new version of the framework (and EJB 3.x deployment descriptors so i can deploy) ONLY A TESTCASE fails but the rest of the functionality works (like i can send requests to our webservice and they dont trigger any errors). While debugging i can see that there is a configuration found. This resource is named "META-INF/services/javax.xml.bind.JAXBContext". Here are the most important lines of how this resource leads to the attempt to load 'com.ibm.xml.xlxp2.jaxb.JAXBContextFactory' which then throws the ClassNotFoundException. This is simplified source of the mentioned javax.xml.bind.ContextFinder class:

URL resourceURL = ClassLoader.getSystemResource("META-INF/services/javax.xml.bind.JAXBContext");

BufferedReader r = new BufferedReader(new InputStreamReader(resourceURL.openStream(), "UTF-8"));

String factoryClassName = r.readLine().trim();  

The field factoryClassName now has the value 'com.ibm.xml.xlxp2.jaxb.JAXBContextFactory'

Because this has become a super lager question i will also add a bounty :) I will work the entire day on this and let you know if there is any news.

Update/ Solution

This question has been solved. The original problem has occured because misconfiguration of complexly build multi model maven projects which one dependency used a updated version of a customized eclipse link jar that contained a definition for a JAXBFactory not available in the component where the error occured. Setting the JAXB context factory in most cases is configured with a jaxb.propertie file or JAXBContext file that contains the same definition. Detailed loading process of the appropriate JAXBContextFactory happens in javax.xml.bind.ContextFinder.

The error has not yet been solved (during the fact over 4 major EE/SE Applications lead to the error) and there is no general answer but that defined JAXBContextFactorys must exist in your classpath (wow what a wonder...) so you either have a that ClassNotFound Error because youre missing resources (well thats the acctual cause) or because you have a wrong JAXBContextFactory defined in any of the above mentioned propertie files which contain a definition according to the below answer.

Very many thanks for your great comments and support, i realy appreciate!

JBA
  • 2,769
  • 5
  • 24
  • 40
  • Very many thanks for the editing! – JBA Nov 01 '13 at 17:07
  • Out of curiosity, does your framework include JAXB JARs? Did the old version of your framework include jaxb.properties? It's not clear to me how you ended up in a situation where your application class loader can see the META-INF/services file but not the implementation class. It's also not clear to me why the old version of the framework was ever selecting the com.sun implementation. – Brett Kail Nov 02 '13 at 15:18
  • Many thanks for your input, i editet the questions to hopefully provide more information – JBA Nov 04 '13 at 09:51
  • Again very many thanks for the editing! I promise before i post the next question i will make sure to understand everything on how to format approperly! – JBA Nov 04 '13 at 11:14
  • https://stackoverflow.com/questions/48832270/jaxbcontextfactory-hell-java-lang-classnotfoundexception-com-ibm-xml-xlxp2-ja – Gouri Yashodhan Mar 23 '18 at 15:03
  • https://stackoverflow.com/questions/58009038/eclipse-4-12-java-lang-classnotfoundexception-com-sun-xml-internal-bind-v2-co/66757918#66757918 – Manan Shah Mar 23 '21 at 05:50

2 Answers2

12

You can include a jaxb.properties file in the same package as your domain model to specify the JAXB (JSR-222) implementation you wish to use. For example it would look like the following to specify EclipseLink MOXy as your JAXB provider.

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

For More Information

Stijn Van Bael
  • 4,830
  • 2
  • 32
  • 38
bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • @user1902288 - Who is providing the ` "META-INF/services/javax.xml.bind.JAXBContext"` entry, you or WebSphere? – bdoughan Nov 01 '13 at 17:27
  • @BlaiseDoughan It's provided by WebSphere. – Brett Kail Nov 02 '13 at 15:17
  • 1
    I upvoted your answer because this seems to be the official way of how to set the desired ContextFactory. Even thus i have placed that file in both model packages (the ones used in the service as well as the ones in the integration tests) the error still appears and i am currently debugging why it does not find those jaxb.properties. As soon as it works i will accept your answer to get you the reputation reward. I think this is the best way to make sure the ContextFacory of the oracle jdk is taken. – JBA Nov 04 '13 at 10:20
  • 1
    I wasent yet able to solve our big mess in the maven dependencys including at least 4 EE components and two different versions of the company framework. However i am now sure that the missconfiguration of according jaxb.propertie or JAXBContext files causes this issue. Very many thanks for your support (i will reward the bounty within the next 2 days... have to wait at least 17 hours) – JBA Nov 04 '13 at 16:15
  • Nearly forgott to award your bonty, there you go, very many thanks again :) I now solved the problem by including a huge customized library that contains half of the websphere jdk as well as tons of eclipse link files just for the integration tests to run. The library defining the ContextFactory is meant to be used under websphere with eclipse link only ... "encapsulation ... yeah close enoth" – JBA Nov 08 '13 at 08:30
  • 6
    If you're using Maven, don't forget to put `jaxb.properties` in `java/main/resources`, otherwise Maven might not copy it to the output folder. – Stijn Van Bael Aug 21 '14 at 09:24
  • What is the fundamental thought not to be done with a simple constructor (jaxb-wise) ? ... – hephestos Jun 03 '18 at 13:47
  • Property `javax.xml.bind.JAXBContextFactory` should be used instead – Mahmoud Mar 24 '22 at 22:58
4

Another quick and dirty solution (a workaround, really) that worked for me is to explicitly include a JAXB implementation to the maven build. For example

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.7</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.7</version>
</dependency>

Note that this adds a somehow unnecessary dependency to your build, as JAXB obviously already is part of each JRE >= version 6.

Most likely this will only work when the WAS classloader is set to parent last.

Dani
  • 3,744
  • 4
  • 27
  • 35
schnatterer
  • 7,525
  • 7
  • 61
  • 80
  • I don't believe it will work by default - WAS will still use it's own implementation from the parent classloader. – kboom Sep 25 '14 at 05:54
  • 1
    It definitely worked for me at the time. Maybe setting the WAS classloader to parent last would be an option, or disabling/changing the default implementation as described here: http://stackoverflow.com/a/10002848/1845976 or it might work just like for JAXWS, as described here: http://stackoverflow.com/questions/24864549/error-deploying-jaxws-webservice-on-websphere-server/24866039#24866039 – schnatterer Sep 25 '14 at 20:15
  • You're right! This is a valid solution but please include this in your answer. – kboom Sep 26 '14 at 07:18
  • For me this worked... https://stackoverflow.com/questions/58009038/eclipse-4-12-java-lang-classnotfoundexception-com-sun-xml-internal-bind-v2-co/66757918#66757918 – Manan Shah Mar 23 '21 at 05:51