Announcement Announcement Module
Collapse
No announcement yet.
null jaxbContext in Jaxb2Marshaller Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • null jaxbContext in Jaxb2Marshaller

    I am having problems using the jaxb2Marshaller in my client. It works just fine on the server.

    I am very new to the Jaxb marshalling and could use some pointers on how to get it working on the client side.

    On the server I create java files from the xsd and put them in a jar file. This jar is included in the class path of the client. Eventually we'll generate the java files on the client from the xsd as well. For now I just want to get something working.

    The client can send and receive data to the web service if I send xml strings, but throws a null pointer exception when I try to use a the jaxb2Marshaller.

    The client code is divided into the client and a test class. For now I am creating the objects needed in the test rather than in a spring config file.


    Here is the client code:

    import gov.nwcg.isuite.webservice.api.schema.Notify;
    import gov.nwcg.isuite.webservice.api.schema.ReceiptData;

    import java.io.Reader;
    import java.io.StringReader;

    import javax.xml.transform.Result;
    import javax.xml.transform.Source;
    import javax.xml.transform.stream.StreamSource;


    import org.springframework.oxm.Marshaller;
    import org.springframework.oxm.Unmarshaller;
    import org.springframework.ws.client.core.support.WebServ iceGatewaySupport;
    import org.springframework.xml.transform.StringResult;

    public class DataNotifyClient extends WebServiceGatewaySupport {

    public DataNotifyClient(Marshaller marshaller) {
    setMarshaller(marshaller);
    setUnmarshaller((Unmarshaller)marshaller);
    setDefaultUri("http://localhost:8080/isuite-enterprise/ws/dataNotify");
    }

    public ReceiptData send(Notify notify) {
    return (ReceiptData)getWebServiceTemplate().marshalSendAn dReceive(notify);
    }
    }

    The test class is:

    public class TestDataNotify {

    @Test
    public void testNotifyMarshall() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath("gov.nwcg.isuite.webserv ice.api.schema");


    DataNotifyClient client = new DataNotifyClient(marshaller);
    String name = "ois";
    String requestId = "abc456";

    Notify notify = new Notify();
    notify.setSourceName(name);
    notify.setSourceType(SourceType.OIS);
    notify.setRequestId(requestId);

    ReceiptData result = client.send(notify);
    assertNotNull(result);
    assertEquals(requestId, result.getReceiptId());
    assertEquals(ReceiptStatus.RECEIVED, result.getStatus());
    assertEquals(SourceType.OIS.toString(), result.getExplaination());
    assertEquals(new BigInteger("0"), result.getExpectedProcessTime());
    }


    When the test runs I get the following:

    java.lang.NullPointerException
    at org.springframework.oxm.jaxb.AbstractJaxbMarshalle r.createMarshaller(AbstractJaxbMarshaller.java:149 )
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.marsh al(Jaxb2Marshaller.java:352)
    at org.springframework.ws.support.MarshallingUtils.ma rshal(MarshallingUtils.java:81)
    at org.springframework.ws.client.core.WebServiceTempl ate$1.doWithMessage(WebServiceTemplate.java:268)
    at org.springframework.ws.client.core.WebServiceTempl ate.sendAndReceive(WebServiceTemplate.java:404)
    at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 265)
    at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 253)
    at org.springframework.ws.client.core.WebServiceTempl ate.marshalSendAndReceive(WebServiceTemplate.java: 245)
    at gov.nwcg.isuite.webservice.DataNotifyClient.send(D ataNotifyClient.java:35)
    at gov.nwcg.isuite.webservice.TestDataNotify.testNoti fyMarshall(TestDataNotify.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.internal.runners.TestMethod.invoke(TestM ethod.java:59)
    at org.junit.internal.runners.MethodRoadie.runTestMet hod(MethodRoadie.java:98)
    at org.junit.internal.runners.MethodRoadie$2.run(Meth odRoadie.java:79)
    at org.junit.internal.runners.MethodRoadie.runBefores ThenTestThenAfters(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.runTest(Me thodRoadie.java:77)
    at org.junit.internal.runners.MethodRoadie.run(Method Roadie.java:42)
    at org.junit.internal.runners.JUnit4ClassRunner.invok eTestMethod(JUnit4ClassRunner.java:88)
    at org.junit.internal.runners.JUnit4ClassRunner.runMe thods(JUnit4ClassRunner.java:51)
    at org.junit.internal.runners.JUnit4ClassRunner$1.run (JUnit4ClassRunner.java:44)
    at org.junit.internal.runners.ClassRoadie.runUnprotec ted(ClassRoadie.java:27)
    at org.junit.internal.runners.ClassRoadie.runProtecte d(ClassRoadie.java:37)
    at org.junit.internal.runners.JUnit4ClassRunner.run(J Unit4ClassRunner.java:42)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestR eference.run(JUnit4TestReference.java:38)
    at org.eclipse.jdt.internal.junit.runner.TestExecutio n.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.main(RemoteTestRunner.java:196)

    In looking at the Jaxb2Marshaller code it appears that the JAXBContext.newInstance(getContextPath()) is returning null so that when the AbstractJaxbMarshaller tries to create a marshaller, there is no context.

    My question now is what is needed to create the JAXBContext and how do I get it the right information.

    Any help would be appreciated, I have not been able to find an example either in the spring-ws-1.0.3 samples or on the web where the client is using jaxb.

    Thanks

    andersondk7

  • #2
    ObjectFactory missing?

    Hi,

    check your clients jar file if it contains Objectfactory.
    You set:
    Code:
    marshaller.setContextPath("gov.nwcg.isuite.webserv ice.api.schema");
    Basically this means to JAXB: look here for ObjectFactory to create needed objects.

    See also:
    https://jaxb.dev.java.net/nonav/jaxb...XBContext.html

    Comment


    • #3
      Thanks for your quick reply.

      I have checked the jar and it does indeed have a ObjectFactory.class. I checked the ObjectFactory.java and it looks like


      package gov.nwcg.isuite.webservice.api.schema;

      import javax.xml.bind.annotation.XmlRegistry;


      /**
      * This object contains factory methods for each
      * Java content interface and Java element interface
      * generated in the gov.nwcg.isuite.webservice.api.schema package.
      * <p>An ObjectFactory allows you to programatically
      * construct new instances of the Java representation
      * for XML content. The Java representation of XML
      * content can consist of schema derived interfaces
      * and classes representing the binding of schema
      * type definitions, element declarations and model
      * groups. Factory methods for each of these are
      * provided in this class.
      *
      */
      @XmlRegistry
      public class ObjectFactory {


      /**
      * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: gov.nwcg.isuite.webservice.api.schema
      *
      */
      public ObjectFactory() {
      }

      /**
      * Create an instance of {@link OisData }
      *
      */
      public OisData createOisData() {
      return new OisData();
      }
      // other create methods ommited for clarity
      }

      the test case has:

      @Test
      public void testNotifyMarshall() {
      log4j.fine("testNotifyMarshall");
      Jaxb2Marshaller marshaller = new Jaxb2Marshaller();

      marshaller.setContextPath("gov.nwcg.isuite.webserv ice.api.schema");


      From the JaxBContext api:

      " JAXB Providers must generate a jaxb.properties file in each package containing schema derived classes. The property file must contain a property named javax.xml.bind.context.factory whose value is the name of the class that implements the createContext APIs."

      I don't see a jaxb.properties file in the generated output from the xjc compiler and so therefore it does not exist in the jar.

      Could this be the root of the problem and if so how does it get generated?

      Thanks again

      Doug

      Comment


      • #4
        When you use and instantiate Jaxb2Marshaller in your testcase, you must remember to call afterPropertiesSet so that it gets propertly initialized

        This is normally done by the springframework, and thats why it works for you on the server.


        Code:
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("......");
        marshaller.afterPropertiesSet();
        Regards,
        Paul Nyheim

        Comment


        • #5
          Thanks, that was the problem!

          Comment


          • #6
            me too!

            Thanks, I also was having trouble figuring out this one!

            Comment


            • #7
              Thanks for marshaller.afterPropertiesSet(), it really helped.

              Comment


              • #8
                That worked

                That made me go further. Thanks !!

                Comment

                Working...
                X