Skip to main content

Control Over JAXBContext in JAX-WS RI/Metro

Posted by jitu on August 29, 2008 at 4:20 PM PDT




Finally, this RFE Issue 282 : Control Over JAXBContext Creation is resolved. This means an application can configure its own JAXBRIContext for an endpoint or a proxy and JAX-WS RI runtime uses that context for (un)marshalling, WSDL generation etc. It is implemented as a custom WebServiceFeature. See Rama's blog on using custom feature. Looks like, I cannot live without this extension. All the features like SchemaValidation, StreamingAttachment etc. are exposed using this extension.

Thanks to Kohsuke who created @UsesJAXBContext feature(after many reminders!! yeah, yeah he is busy with many other things like hudson, Brazil trip!!). Basically, this feature provides a JAXBRIContext that needs to be used in the runtime. Here is an endpoint sample that uses this feature:

@WebService
@UsesJAXBContext(ServerJAXBContextFactory.class)
public class EchoImpl {
    ...
}

public class ServerJAXBContextFactory implements JAXBContextFactory {
    public JAXBRIContext createJAXBContext(...) throws JAXBException {
    ...
    }
}

I added two test cases:
custom_client_jaxbcontext,
custom_server_jaxbcontext. Both these test cases create their own JAXBRIContext to do type substitution(but doesn't use @XmlSeeAlso). I think that it is also possible to influence (Un)Marshallers that are used by JAX-WS RI runtime using this feature.

Try the 2.1.x nightly and let us know your feedback. The feature will be part of JAX-WS RI 2.1.5/Metro 1.4.

Comments

<p>Hi Jitu,</p> <p>I was looking at @UsesJAXBContext ...

Hi Jitu,
I was looking at @UsesJAXBContext feature to fix my @XmlIdRef issue using a custom IDResolver. You mentioned it is possible to influence the Unmarshaller usng @UsesJAXBContext. Can you provide example of accessing/setting properties on the unmarshaller that will be used JAX-WS. It will help us in setting the IDResolver on the Unmarshaller. Currently, I see that we can only create JaxbRIContext using the @UsesJAXBContext annotation.
Thanks in advance.
Regards,
Anis

Caching JAXBContext

We use more than 50 web services in our application. We are running into issues with memory. Our memory consumption is over 1300 MB and it is causing problems in 32 bit environments. We use WSImport for client generation. Schemas that we use are very large and they are HL7 v3 schemas. We are making Service objects as static. I did some profiling and looks like the WSServiceDelegate is retaining lots of memory, more than 20 MB. Also the total memory retained by JAXBContexts is 250 MB and there are more than 114 JAXBContexts created. I feel that we may improve some memory by caching JAXBConext. In order to do that, do I need to create a custom JAXBContext factory and configure using @UsesJAXBContext feature? Are there any suggestions to decrease the memory foot print?

<p>Have you found any solution for that? But I am mostrly ...

Have you found any solution for that? But I am mostrly interested in client part (client stubs), then in serever part. For example, I see that each WebService port (=com.sun.xml.ws.client.sei.SEIStub class) has com.sun.xml.bind.v2.runtime.JAXBContextImpl and com.sun.xml.ws.model.wsdl.WSDLModelImpl classes, which I believe could be shared among all proxies. Each proxy stub requires 5Mb of memory in my case (that depends on how big is JAXB context). I see that @UsesJAXBContext() can potentially help somehow...

  • Has anybody got a good example? E.g. there are two places in which I call Service.getPort(MyInterface[1,2].class) to create a client proxy. Where to put @UsesJAXBContext ?
  • Is there anything to save on WSDLModel?

A bit related relative issue: JAX_WS 878

Server WS Deployment

Hi, I've been trying endlessly to get this annotation to work on the server side in order to avoid having to have massive @XmlSeeAlso on my parent POJO objects but it seems as though this annotation only gets read/acknowledged when WSGEN is run against it).

Basically, I have the following:

POJOs:
public class Abstract{
}
public class Subclass1 extends Abstract{
}
public class Subclass2 extends Abstract{
}
Webservice:
@WebService
@UsesJAXBContext(WebService.ServerJAXBContextFactory.class)
public class WebService{

@WebMethod
public Abstract findById(@WebMethod(name="id") Integer id){

}
public static class ServerJAXBContextFactory implements JAXBContextFactory {

public JAXBRIContext createJAXBContext(SEIModel sei, List classesToBind, List typeReferences) throws JAXBException {
System.out.println("Using server's custom JAXBContext");
List classList = new ArrayList();
classList.addAll(classesToBind);
classList.add(Abstract.class);
classList.add(Subclass1.class);
classList.add(Subclass2.class);


List refList = new ArrayList();
refList.addAll(typeReferences);
refList.add(new TypeReference(new QName("",""),Abstract.class));
refList.add(new TypeReference(new QName("", ""), Subclass1.class));
refList.add(new TypeReference(new QName("", ""), Subclass2.class));

return JAXBRIContext.newInstance(classList.toArray(new Class[classList.size()]), refList, null, sei.getTargetNamespace(), false, null);
}
}
}

When I make SOAP requests to findById and pass in an Id for an object of type Subclass1 or Subclass2, I get back only an Abstract object (it seems as though the Subclass1 and Subclass2 are not being added to the JAXBContext being used).
Any thoughts?
-MK

MK , I tried the above example . Were you able to run the ...

MK ,

I tried the above example . Were you able to run the example.
For me too the subclasses did not show in WSDL.
Regards,
Ranajit

Help adding properties to JAXB marshaller used by JAXWS

I have to interface with a 3rd party web service that was created and released a few years ago. It is effectively black box to me and I have no way to effect change in its poor handling of xml.

I found a thread on the java forums that seemed similar and I've attempted to use the functionality identified therein. The problem ultimately is that I don't seem able to push my implementation of the com.sun.xml.bind.namespacePrefixMapper (which i need to change the way namespaces are written....unless you have a better way) property onto the Marshaller that is used by JAXWS even when I use the @UsesJAXBContext feature identified in this "control of jaxb" blog. I'm using JAXB 2.1.11 and JAX-WS 2.1.7.

I've attached a debugger and can see the wrapper around JAXBContextImpl that I've created (so i can apply the namespace prefix mapper property onto any marshaller returned) down in the SEIModel. The problem seems to be that when JAXWS goes to marshall my jaxb object it is going to a bridgeimpl object that is created by the JAXBContextImpl that my wrapper created. This causes my wrapper to be bypassed and therefor no namespace prefix mapper.

Similar thread is here:
http://forums.java.net/jive/message.jspa?messageID=347997

Thanks,
Noah
noah.guilbault {@t} gmail dot org

Great! I was waiting eagerly for this feature. Thanks a lot

Hi , I was looking on having our own prefix for namespaces in WSDL generated request and response objects. Can we achieve this using this feature. If so ca you provide me with some study material or samples on this. Thanks.