Sunday, December 9, 2012

Google Guava Introduction

Google Guava is the most popular java library in developer community. Recently I prepared some slides to introduce few API.

Saturday, December 1, 2012

Axis2 web service client with services host by Weblogic 10.x

After upgrading web service client from Axis1 to Axis2(1.6.2 version), the client was getting the following service fault from the service methods implemented under Weblogic server.

Caused by: org.apache.axis2.AxisFault: Couldn't create SOAP message due to exception: Unable to create StAX reader or writer

After little research, the issue was related with chunked streaming support from Axis2. The Axis2 chunked streaming is enabled by default and so it needs to disabled at runtime. I think there are some problems with chunking and some servers don’t allow chunked requests. 

serviceStub._getServiceClient().getOptions().setProperty(HTTPConstants.CHUNKED, false);

How to marshal XML as encrypted file using CipherOutputStream

CipherOutputStream can be used to marshal XML as encrypted file to protect some confidential information. The CipherOutputStream overrides all methods underlying output stream to support encryption needs. It takes OutputStream and Cipher in the constructor and the incoming Cipher must need to be initialized before passing in. 

The following code shows how to use CipherOutputStream to marshal XML to encrypted file.

List<Object> data = new ArrayList<Object>(); //data with large list
      JAXBContext jc = JAXBContext.newInstance("XML SCHEMA PATH");
      Marshaller m = jc.createMarshaller();
      byte[] key = new byte[]{/*key bytes*/};
      final SecretKey secretKey = new SecretKeySpec(key, "AES");  
      Cipher cipher = Cipher.getInstance("AES", "SunJCE");
      cipher.init(Cipher.ENCRYPT_MODE, secretKey);
OutputStream outputStream = new CipherOutputStream(new FileOutputStream(new File("largetest.xml")), cipher);       
      m.marshal(data, outputStream);

Effective way to parse very large XML without using excessive memory allocation

The common scenario is to use JAXB memory marshalling. It is quick and easy way to marshal and unmarshal small size XML. However the same JAXB code can consume tons of memory for large XML files. There are few different approaches to marshal and unmarshal very large XML files without using excessive memory allocation. 

JAXB with File streams –The JAXB with File streams can provide the memory effective solution for marshalling and unmarshalling xml. Here is some sample code that explains how to use File streams.

        List<Object> data = new ArrayList<Object>(); //data with large list
        JAXBContext jc = JAXBContext.newInstance("XML SCHEMA PATH");
        Marshaller m = jc.createMarshaller();
        OutputStream outputStream = new                                    FileOutputStream(new File("largetest.xml"));
        m.marshal(data, outputStream);       
        Unmarshaller um = jc.createUnmarshaller();
        InputStream inputStream = new FileInputStream(new File("largetest.xml"));
        data = (List<Object>)um.unmarshal(inputStream);

JAXB with STax parser –The STax parser provides a capabilities to pull XML elements instead of bringing whole XML file in a memory.  JAXB with STax parser can provide another alternative solution where we have tight memory requirements. Here is some pseudo code that explains how to use STax technology.

        final XMLInputFactory xmlif = XMLInputFactory.newInstance();
        xmlif.setProperty(XMLInputFactory.IS_COALESCING, true);
        XMLStreamReader xmlr = null;      
        JAXBContext objectHeaderTypeCtx = JAXBContext.newInstance("Name of your unmarshal class");
        StringReader input;
        xmlr = xmlif.createXMLStreamReader(input);
        while (xmlr.getEventType() != XMLStreamConstants.END_DOCUMENT) {
            if (xmlr.isStartElement() &&                               "ObjectHeader".equals(xmlr.getLocalName())) {
                Unmarshaller um = objectHeaderTypeCtx.createUnmarshaller();
                JAXBElement<ObjectHeaderType> header = um.unmarshal(xmlr,ObjectHeaderType.class);