users@jaxb.java.net

Re: help with unmarshaling

From: Levi Purvis <javanet_at_purvis.ws>
Date: Wed, 31 Jan 2007 10:40:27 -0500

> I believe (correct me if I am wrong) that JBOSS appserver has a
> different classloader for WAR's and for EJB's.

Yes and no. You can configure it either way. I believe the default
in current JBoss releases is to lump nearly every class into one
central classloader, with only WAR's having their own classloader. So
classes across EAR's could end up in the same classloader. You can
turn this off and put all of your deployments in their own classloader
if you want.

> I assumed having the EJB jar file in the manifest.mf file or the
> WARS would solve this problem because the classpaths would
> contain the jar file listing.

JBoss' support of using the MANIFEST.MF Class-Path is horrible. I
could never get it to work correctly.

Try this:

EAR
   +META-INF/jboss-app.xml - turn on private/scoped classloading [1]
   +META-INF/application.xml - list common.jar as a java module
   +common.jar - holds the XJC generated classes
              - list common.jar in META-INF/application.xml like so:
                      <module><java>common.jar</java></module>
   +ejb.jar - do *NOT* reference common.jar in the manifest.mf file
              - do *NOT* put a copy of the XJC gen'ed classes
   +webservice.war - holds the servlet
              - do *NOT* put common.jar in WEB-INF/lib
              - do *NOT* reference common.jar in its manifest.mf file
              - do *NOT* put a copy of the XJC gen'ed classes

[1] See http://www.jboss.org/wiki/Wiki.jsp?page=ClassLoadingConfiguration

Also, I'm not sure where you're deploying your jaxb.jar and
dependencies, but JBoss may have it's own copy in
<jboss>/server/<instance>/deploy/jbossws.sar/

You can use the java module trick in application.xml to reference any
shared library in your EAR (this may only work correctly in JBoss).
You can even override libraries from server/lib or other deployments
like this, if you turn it on (see [1] again).

I'm successfully using a similar deployment.


On 1/26/07, john.mcclain_at_homeq.com <john.mcclain_at_homeq.com> wrote:
> OK - so I have tried 3 methods to solve the problem (see history), but
> first, a drawing of my EAR file:
> EAR file-+
> |
> +EJB.jar - conatins the XJC generated classes
> +Test WAR file1-+
> |
> + servlet - contains the
> JAXBContext.newInstance call
> + EJB.jar - - conatins the XJC generated
> classes
> +TestWAR file2-+
> |
> +servlet - contains the
> JAXBContext.newInstance call
>
>
> 1) passing this.getClass().getClassLoader() as the second parm to
> JAXBContext.newInstance()
> 2) passing com.homeq.bpo.domain.FirstAmericanSchema.response
> .ObjectFactory.class to JAXBContext.newInstance()
> 3) passing an array of the XJC generated classes, i.e., {
> com.homeq.bpo.domain.FirstAmericanSchema.response.<class1-n>.class, } to
> JAXBContext.newInstance()
>
> The results are still the same as below, namely -
> the WAR file containing the jar file containing the XJC generated classes
> works (even though the jar file is also in the EAR file this war file is
> in)
> The WAR file NOT containing the jar file containing the XJC generated
> classes does NOT work (this WAR file is also in the EAR file cantaining
> that jar file, AND the manifest.mf file is sufficient to reference the XJC
> generated classes)
>
> After reading the FAQ about how the newInstance(...) tries to load classes
> using the sameclassloader used to load the JAXBContext itself, it seems
> this may be the problem; My JAXBContext.newInstance calls are in my
> servlets, which are in the war files. I.E., My XJC generated classes are
> in my EJB jar. Thoughmy 2 WAR files (1 works 1 does not) and my EJB jar
> file (containing generated classes) are all in my EAR file, I believe
> (correct me if I am wrong) that JBOSS appserver has a different
> classloader for WAR's and for EJB's. I assumed having the EJB jar file in
> the manifest.mf file or the WARS would solve this problem because the
> classpaths would contain the jar file listing. Am I going down a rabbit
> hole, or is it true that the XJC generated fiels MUST be in the same
> classloader and the loader that loaded the JAXBContext class itself
>
> I f I am correct, then how do I get my servlets to see the XJC generated
> files housed in the EJB jar, housed in the EAR?
> If I can't then what is a better architecture - should I have the XJC
> generated files reside in the WAR file AND the EJB jar file - wouldn't
> this cause conflict since they are being loaded in both the webapp
> classloader and the EJB classloader?
>
>
>
> To
> users_at_jaxb.dev.java.net
> cc
> jmcclain1_at_starstream.net
> Subject
> Re: help with unmarshaling
>
>
>
>
>
>
> john.mcclain_at_homeq.com wrote:
> > Howdy
> > I have an EAR project deployed in jboss. The ear file contains an EJB
> jar
> > file, which houses the XJC generated classes in addition to the EJB. The
>
> > ear file also includes 2 war files
> > Each war file contains 1 servlet.
> >
> > The issue is that the servlet from war 1 fails and the servlet from war2
>
> > succeeds, YET THEY ARE COPIES OF EACH OTHER
> >
> > Here are the datials from a failure/success perspective
> >
> > servlet from War that SUCCEEDS
> > 1)WEB-INF/lib containsa set of jars (call it setx), AND the EJB jar
> > containing the XJC generated classes
> > 2)the mainfest.mf (classpath) has all the above jars including the EJB
> > listed (generated from Maven2) - this means the EJB jar file is in the
> EAR
> > and this wars WEB-INF/lib
> > 3) When the servlet runs, i print out the to_string method of the
> > jaxbContext, and it shows ALL the specific XJC generated classes except
> > for the ObjectFactory
> >
> > Servlet from WAR that FAILS
> > 1)WEB-INF/lib contains ONLY set of jars, setx (see above)
> > 2)the mainfest.mf (classpath) has all the above jars including the EJB
> > listed (generated from Maven2)
> > 3)When the servlet runs, i print out the to_string method of the
> > jaxbContext, and it shows ONLY the ObjectFactory generated by XJC
>
> It sounds like a classloader issue. [1] and [2] are relevant docs on
> this topic. I suspect you've already looked at [1], but [2] might be
> just what you need --- I need to make [1] include [2].
>
> [1]
> https://jaxb.dev.java.net/guide/Unmarshalling_is_not_working__Help_.html
> [2] https://jaxb.dev.java.net/faq/#classloader
>
> Also, Is FIRST_AMERICAN_RESPONSE constant a string? Try passing in
> ObjectFactory.class list, as that's the easier way of identifying
> classloader problems.
>
> >
> > The servlet code FOR BOTH SERVLETS is:
> > JAXBContext jaxbContext_tst =
> > JAXBContext.newInstance(FIRST_AMERICAN_RESPONSE);
> > System.out.println(jaxbContext_tst.toString());
> > Unmarshaller unmarshaller_tst =
> > jaxbContext_tst.createUnmarshaller();
> > unmarshaller_tst.setEventHandler(new
> > javax.xml.bind.helpers.DefaultValidationEventHandler());
> > RESPONSEGROUP tst = (RESPONSEGROUP)
> > unmarshaller_tst.unmarshal(new File(
> > "C:\\homeq-maven\\projects\\homeq-bpo\\notes\\resptest.xml" ));
> >
> > In the success servlet, tst contains all the data, in the failing
> servlet,
> > an unmarshal exception is thrown
> >
> > The unmarshalexception I get when call unmarshal(...) is:
> > 17:08:18,827 INFO [STDOUT] DefaultValidationEventHandler:
> [FATAL_ERROR]:
> > unexpected element (uri:"", local:"RESPONSE_GROUP"). Expected elements
> are
> > (none)
> > Location: line 1 of
> > file:/C:/homeq-maven/projects/homeq-bpo/notes/resptest.xml
> > 17:08:22,093 ERROR [STDERR] javax.xml.bind.UnmarshalException:
> unexpected
> > element (uri:"", local:"RESPONSE_GROUP"). Expected elements are (none)
> > 17:08:22,093 ERROR [STDERR] at
> >
> com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(
> > UnmarshallingContext.java:556)
> > 17:08:22,093 ERROR [STDERR] at
> > com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(
> > Loader.java:199)
> > 17:08:22,093 ERROR [STDERR] at
> > com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(
> > Loader.java:194)
> > 17:08:22,093 ERROR [STDERR] at
> >
> com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(
> > Loader.java:71)
> > 17:08:22,093 ERROR [STDERR] at
> >
> com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(
> > UnmarshallingContext.java:957)
> > 17:08:22,108 ERROR [STDERR] at
> >
> com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(
> > UnmarshallingContext.java:399)
> >
> >
> > Given that the EAR file contains the EJB jar file containing the XJC
> > generated classes, AND the manifest.mf file lists the EJB jar (I believe
>
> > this puts it in the classpath), then why is the failing servlet
> failing???
> >