SOA / Web Services / Java

A Technology Blog

Posts Tagged ‘xml’

Access User-Defined SOAP Header Elements in Service

Posted by Vivek on February 13, 2010

There could always be a requirement that some data be sent only in SOAP Header. Usually SOAP Header contains data that is system specific and is dissimilar to the message payload that is contained in the SOAP Body. The information that a SOAP Header carries could be user-defined and generally used for tracking and logging. This data could be required by your service but is lost when a SOAP engine unmarshals the SOAP Request and provides just payload to the service i.e., applies the binding mechanism to convert an XML into a VO for the service to access elements using accessors and mutators.  To make this user-defined data available to the service, use of ThreadLocal can be advocated.

ThreadLocal allows you to have copy of variable per thread, which are subject to garbage collection when the thread goes away. Before the binding framework of SOAP engine performs any logic, a SOAP Handler can be placed to access the original SOAP request message and let the handler set the data in a threadlocal variable and use this data, which remains alive till the thread is active.

Here is the sample code which allows a bean injection and makes it available for setting values in the handler class.

<bean id=”myUserDefinedInfoBean”
class=”org.springframework.aop.framework.ProxyFactoryBean”>
<property name=”targetSource” ref=”threadLocalUserInfo” />
</bean>

<bean id=”threadLocalUserInfo”
class=”org.springframework.aop.target.ThreadLocalTargetSource”
destroy-method=”destroy”>
<property name=”targetBeanName” value=”userInfoVO” />
</bean>
<bean id=”userInfoVO”
class=”mypackage.vo.UserInfoVO” scope=”prototype” />

UserInfoVO defines setters and getters for the user defined elements . The values can be set in the handler class and can be obtained anytime till the thread remains active.

For ex, the following code snippet will set the values in SOAP Handler

private UserInfoVO userInfoBean;

….

public UserInfoVO getUserInfoBean() {
return userInfoBean;
}

public void setUserInfoBean(UserInfoVO userInfoBean) {
this.userInfoBean = userInfoBean;
}

….

getUserInfoBean()
.setUserElementValue(myVal);

….

Once the above code is executed, value set in myVal can be accessed anywhere using getUserInfoBean()
.getUserElementValue();

Posted in SOA, Web Services | Tagged: , , , , | 2 Comments »

Is your web-service conforming to WSI-Basic Profile?

Posted by Vivek on January 23, 2010

Though there are various ways to design a service and since webservices are XML based and XML is tagged as platform independent, different programming languages and different application server have their own set of rules while defining a web service. WSI-Basic Profile helps address some interoperability issues that might arise because of the proprietary nature of majority of tools and languages. Listed out below are some of the guidelines that can be useful while defining a service:

XML version is 1.0

Encoding must be UTF-8 or UTF-16

Namespace for WSDL is defined as http://schemas.xmlsoap.org/wsdl/?

Namespace for SOAP binding is defined as http://schemas.xmlsoap.org/wsdl/soap/

Namespace for SOAP encoding is defined as http://schemas.xmlsoap.org/soap/encoding/

Namespace should not be as http://www.w3.org/XML/1998/namespace

Custom Data types used in WSDL should conform to XML Schema version 1.0

Data Type that causes interoperability issues should not be used. For ex. wsdl:arrayType, arrayOfStrings etc. should not be used.

All the xsd:import elements should be used within the xsd:schema element of the types section

The attribute wsdl:required=”true” should not be used by any element.

wsdl:import URIs should be absolute and not relative.

wsdl:import should precede all other wsdl types , except wsdl:documentation. Similarly, wsdl:types should precede all other elements, except wsdl:documentation and wsdl:import

targetNamespace value of WSDL that is being imported should have the same value as wsdl:import.

All the imported schemas should have a root element defined with namespace http://www.w3.org/2001/XMLSchema

Part attribute, if any, in a document literal style of web service should be defined within binding or operation.

In Document Literal style, wsdl:part elements that are used in soapbind:body should have ‘element’ attribute defined.

In a wsdl:message/wsdl:part element, the ‘element’ attribute should refer to a global element declaration and not to any xsd types.

In an RPC Literal style, envelope should not have xsi:nil attribute value = “1” or “true”.

In an RPC Literal style, wsdl:part elements that are used in soapbind:body should have ‘type’ attribute defined.

In a wsdl:portType definition, Solicit-Response/Notification type operations should not be used.

A wsdl:message element should not have both type and element attributes defined.

The values for name attribute of wsdl:portType elements should be distinct.

In soap:binding element, the transport attribute should be defined and the value should be http://schemas.xmlsoap.org/soap/http.

In a soap:operation, the value of style attribute should be either “rpc” or “document”.

In a soap:operation, the soap:bodyelement should have use attribute set to “literal” ?

If soap:header/soap:headerfault/soap:fault elements are defined, the use attribute should be set to “literal”

The location attribute should have distinct value for different ports wsdl:port.

A soap:fault should be defined for each fault defined and it should contain name attribute. If use attribute is defined, it should contain a value ‘literal’

Similarly, a soap:headerfault should exist for each header fault defined.

If SOAP Action is defined within operation, it should be set in the HTTP header of the request otherwise, it should be set to empty quoted string.

SOAP envelope should contain namespace http://schemas.xml.soap.org/soap/envelope whereas SOAP encoding namespace should be http://schemas.xmlsoap.org/soap/encoding/A SOAP message should also use UTF-8 or UTF-16 encoding.

Intermediaries, if present while transmitting SOAP message, should modify the header only if the must-understand attribute is set to true. Intermediaries should not modify the payload or elements with the SOAP Body.

A must understand faultcode must be generated in case receiver is unable to process the mandatory header of the SOAP message.

In case of a fault, soap:Fault must not have childrens other than faultcode, faultstring, faultactor and detail. In case of fault,  children of the soap:Fault element must be unqualified. There can be zero or more child elements of the detail element, which can be either qualified or unqualified.

Values of the faultcode element are defined by SOAP specification and preferably should not be modified.

 

Posted in Web Services | Tagged: , , , , | 8 Comments »

What XML parser to use?

Posted by Vivek on February 3, 2009

XML, being the lingua franca of web services, has found its use in many applications mostly because of its platform agnostic feature. Applications using XML and XML-based artifacts like SOAP, WSDL etc. tremendously require traversal, customization and transformation of these artifacts to suit its needs. This is the reason why we see parsing and binding (marshalling and unmarshalling) of XML documents at various critical points in an application. One important thing to note is that XML is verbose and leads to various performance issues when processed, especially in complex environments. Over the years, we have seen use of DOM (Document Object Model) and SAX (Simple API for XML) parsers but these parsers have their own limitations and require trade-offs in some situations. For example,  

DOM requires in-memory representation of the XML document, which exerts unnecessary pressure on system resources and is thus considered impractical for large documents. Also, DOM APIs introduces complexity while processing XML nodes.

Other alternatives or parsers that use tree-based APIs are dom4j, JDOM and XOM. While dom4j document object model is fast and memory-efficient and offers great extensibility, JDOM is mostly known for its ease of use. The XOM document object model protects users from common mistakes in the use of XML, while offering good performance and memory efficiency. 

SAX, on the other hand, is inappropriate when reordering or cross-referencing of XML nodes is desired. 

WoodStox is an XML processor that combines the best of both the worlds. In other words, it is easy to use or convenient like DOM and efficient like SAX. It is an open source implementation of StAX pull parser standard. It, however, encounters performance issues like Xerces2, the Apache Implementation of the W3C document object model standard, when dealing with small documents, for eg. SOAP. 

To improve the performance of such widely-used XML parsers, Apache introduced a new parser. This new parser, AXIs Object Model (AXIOM), is considered not just another object model but a very useful and performance enhancing parser for CPU and Memory intensive applications. AXIOM tries to achieve its objective of being a memory-efficient parser by deferring creation of XML tree when not required. AXIOM is StAX (Streaming Api for XML) based object model and it implements “pull-parsing” methodology, unlike SAX and DOM. It also has built in support for XML Optimized Packaging (XOP) and MTOM, the combination of which allows XML to carry binary data efficiently and in a transparent manner. Another important feature supported by AXIOM is that it provides APIs to parse SOAP (Simple Object Access Protocol) documents effectively. When the APIs are already defined, complexity can be easily avoided and performance overhead can be easily tackled. Apache’s SOAP engine Axis2, thus, has provision for AXIOM. AXIOM’s ability to support various binding mechanisms helps it optimize the marshalling and unmarshalling of XML fragments and hence, results in improved performance.

 

While AXIOM has pre-defined APIs for parsing a SOAP message, it should also be possible to define APIs that can extract elements from a WSDL (Web Services Description Language) file.

 

Posted in Java/J2EE, Web Services | Tagged: , , | 2 Comments »

Preserve white spaces in a SOAP message

Posted by Vivek on January 30, 2009

Sometimes, the business requirement mandates that a SOAP request/response should maintain leading or trailing spaces that are present in a variable. By default, this does not happen. For example, you may expect ” ABC” or “ABC “, but you get “ABC”. The spaces are removed. Also, you may encounter issues if you use a binding mechanism like JAXB to marshal/ unmarshal xml fragments.  This requires modifying the default marshalling or unmarshalling behavior. This is how you can still maintain any whitespaces:

Before marshalling call

marshaller.setPropertyMarshaller.JAXB_ENCODING, “UTF-8”)

 which informs MarshallerImpl#createWriter(…) to create a UTF8XmlOutput instead of SAXOutput. 

UTF8XmlOutput escapes line-break into “ ”, which will be preserved when unmarshalling is performed by any xml parser.

Posted in Web Services | Tagged: , , | Leave a Comment »

Oracle-o-phobia

Posted by Vivek on July 27, 2008

Came across a very good post on Oracle forum. Worth mentioning as there are lot of people experiencing problems with oracle products.

Oracle BPEL + Oc4j + Jdeveloper = brain damage

We have been using Oracle BPEL 10.1.2.0.2 and now upgraded to 10.1.3.3.0 (oc4j, bpel and jdeveloper) when I came into contact with it.

Since then, we ran into loads of bugs that didn’t accelerate our development as Oracle promises, but slows us down by a factor of 3 at least.

Just to name a few issues:
– 10.1.3.3.0 is not 100% stable in cluster mode. Deployment of processes fails randomly, they have to be redeployed several times. Before deployment, you have to undeploy old version to minimize risk of this problem.
– XSDs, XSLTs in BPEL process are sometimes not refreshed after deployment, resulting in reporting bugs that shouldnt exist.
– Oracle parser V2 cannot parse XML correctly, in certain cases when elements are separated by line feeds, it reports “null” elements.
– the whole oc4j uses old JAXB, leading to insurmountable problems if you try to use anything that requires newer version
– if you hope that you can fix problems with Oracle support, forget it, they will want an Oracle web conference with you for every bug. The process takes several days, and in most cases you will solve the issue before them.
– oc4j/opmn binding to multiple IP addresses is not functional, although according to manual it should work
– JDeveloper randomly deletes source code from other projects when deleting web service proxies
– JDeveloper can’t refactor java if the code is in SVN, it leads to corrupt project
– JDeveloper cant delete web service proxies correctly, it leaves old files on disk
– JDeveloper sometimes cant import java code, java sources dont appear in JDeveloper
– JDeveloper generated deserializing code for web service proxies is buggy, cant deserialize null Double, Integer etc. Sometimes it generates code that first uses obejct, and then checks for null …
– if JDeveloper is run from directory containing a space, it doesnt work correctly, unexpected bugs can occur. For example after adding email activity to BPEL project it becomes uncompilable. According to Oracle support this is ok, its mentioned in installation guide and is fully standard nowadays.
– JDeveloper BPEL designer is known to give errors like “Error: null” or ‘Reason: “” ‘ during compilation, meaning its impossible to fix probleme easily.
– in BPEL designer, xpath expression checking is not done, if something is wrong, project compiles but then leads to weird exceptions when deployed.
– when using switch activity, and string xpath in it like xp20:ends-with(), the content must be explicitly converted to string() or you get FOTY001 type error during runtime.
– when using transform activity in bpel designer, if you do not assign certain output nodes, they are deleted from the XML, so no further assign activities work on it.
– as we use custom bpel security module, we found out the BPEL runtime incorrectly passes information about domains when calling process from other domain from another process – leading to weird error that called process doesnt exist.
– when using transformations, bpel designer often says transformation is ok, but then in runtime you get FOTY001 type error, with no hint where the problem might be…
– correlation sets are not working under certain circumstances
– no refactoring in bpel designer, you cant even copy certain activities and paste them elsewhere. So you have to click, click, click everything again or copy in source code
– assign and transform activies are particularly touchy on whether there is element with some data, whether there is no element, or nil element. If the element is missing in input and you use assign copy on it, you are in trouble.
– icons in bpel designer are too big, if zooming is used, activity editing dialogs cannot be used
– when using JDeveloper generated web service proxies to invoke bpel processes, virtually only strings can be passed, if you pass anything else back, you will get various deserialization errors due to badly generated jdeveloper code
– if Oracle support on metalink cant replicate the problem, the problem “doesnt exist”.
– if you tell Oracle support you are going to use another product, they ask whether you still want to continue working on fixing reported bug. Obviously if you dont use oc4j, bugs in it dont need to be fixed.

I can’t imagine any serious company using JDeveloper and oc4j as these 2 are a deadly combination resulting in brain damage.

If you are considering buying BPEL or using Oc4j, think carefully, better take my warning seriously and look for other solutions until Oracle gets its problems sorted out.

Posted in jdeveloper, oracle | Tagged: , , , , , , | Leave a Comment »