Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use an alternative XML parser with Weblogic and Spring-ws?

I'm using WebServiceGatewaySupport to implement a SOAP client. As part of those SOAP calls I'm implementing my own org.springframework.ws.client.core.SourceExtractor to map the returned XML to my domain objects.

I seem to be getting a DOMSource object sent to SourceExtractor, so I'm trying to use the DOM API and implementation built into my application server (which happens to be the ancient Weblogic 10.0 MP2). The implementation, however, seems to be incomplete as evidenced by the following trace.

java.lang.AssertionError: UNIMPLEMENTED
    at weblogic.xml.domimpl.NodeImpl.getTextContent(NodeImpl.java:198)
    at com.cinfin.ecm.security.CICUserSourceExtractor.extractData(CICUserSourceExtractor.java:22)
    at com.cinfin.ecm.security.CICUserSourceExtractor.extractData(CICUserSourceExtractor.java:1)
    at org.springframework.ws.client.core.WebServiceTemplate$SourceExtractorMessageExtractor.extractData(WebServiceTemplate.java:807)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:596)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:537)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:492)
    at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceive(WebServiceTemplate.java:479)
    at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceive(WebServiceTemplate.java:470)
    at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceive(WebServiceTemplate.java:458)
    at com.cinfin.ecm.security.CICSecurityService.getRolesForUser(CICSecurityService.java:32)
    at com.cinfin.ecm.security.CICSecurityServiceTest.testGetRolesForUser(CICSecurityServiceTest.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:592)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

My first question is, obviously, how am I to get the text value of the nodes in this DOMSource? Can I use Spring/Spring-ws to replace the XML parser used to unmarshall the source? Secondly, is this implementation on the right path? Is there an easier, more Spring-like way to do what I'm doing?

like image 432
Mike Yockey Avatar asked Jan 27 '26 16:01

Mike Yockey


1 Answers

The problem ended up being that Bea/Oracle, rather than implementing the DOM standard interface, uses their own private API. While debugging through my code trying to understand where to insert a different XML parser, I noticed that the text data of the node was indeed being retrieved. It was on a protected member variable String data in an instance of class weblogic.xml.domimpl.TextImpl. Since the source isn't published I couldn't just look in the class to see how that variable was accessed, so I went looking through the method names for something that looked close. I found a method named getData().

Here's what my implementation tried to do before (which may or may not be correct based on the DOM interface):

public T extractData(Source source) throws IOException {
    Node rootNode = ((DOMSource)source)
    NodeList nodes = rootNode.getChildElements();
    for (int i = 0; i < nodes.getLength(); i++) {
        String nodeText = nodes.item(i).getTextContent();
        /* Remainder of loop and method elided */
    }
}

What is now working:

public T extractData(Source source) throws IOException {
    Node rootNode = ((DOMSource)source)
    NodeList nodes = rootNode.getChildElements();
    for (int i = 0; i < nodes.getLength(); i++) {
        TextImpl nodeTextImpl = (TextImpl) nodes.item(i).getFirstChild();
        String nodeText = nodeTextImpl.getData();
        /* Remainder of loop and method elided */
    }
}

I would still appreciate comments from those more familiar with the Java DOM API, especially comments that would correct my usage of the get*() methods available on org.w3c.dom.Node.

like image 77
Mike Yockey Avatar answered Jan 29 '26 06:01

Mike Yockey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!