Sunday, January 23, 2011

Parsing large XML files.

Today I will write about parsing XML files from the Java perspective. Recently I faced a task of reading and eliciting some certain data from a bigger than usually XML file – over half a GB. The most desirable approach when it's about parsing XML files is to use a parser that implements a DOM API interface. For those of you who are not familiar with this mechanism – in a nutshell, it's a tree based API which reads the entire document into memory and represents it as a tree of objects, to which we have random access. It makes a work with XML documents very convenient and easy thanks to the fact that we can easily retrieve any interesting node from the tree and read the data that we need. Unfortunately, there is a huge drawback with this solution – it requires lots of memory, depending on the implementation, up to a few times of the xml document's size which in my case, forced me to seek for another approach.
After a while, I came across to StAX, which stands for Streaming API for XML. It is much different API than the DOM. The first important thing – it does not convert the document into a tree. Instead, it treats it as it is – a stream. But that's not everything. The StAX is a pull streaming model which means that it is up to the programmer when he or she wants to start, pause or resume the parsing process.
Fine! I guess that's enough for an introduction. Let's have a look at the following example of parsing an xml file. First of all, here is how the xml file looks like:

<calendar>
<event type = "party">
<where>Club Mojito</where>
<whom>My friends</whom>
</event>
<event type = "meeting">
<where>A building</where>
<whom>Project Manager</whom>
<date>12/09/11</date>
</event>
<event type = "lunch">
<where>Canteen</where>
</event>
</calendar>

And the code that parses the file using StAX:

package stAX;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Iterator;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class StAXExample {
public static void main(String[] args) {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
try {
InputStream in = new FileInputStream("ourFile.xml");
XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
String currentElement = "";
while(eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if(event.isStartElement()) {
StartElement startElement = event.asStartElement();
currentElement = startElement.getName().toString();
System.out.println("Start element: " + startElement.getName());
@SuppressWarnings("unchecked")
Iterator<Attribute> it1 = startElement.getAttributes();
while(it1.hasNext()) {
Attribute attribute = it1.next();
System.out.println(" Attribute name: " + attribute.getName() + ", value: " + attribute.getValue());
}
}
if(event.isEndElement()) {
currentElement = "";
}
if(event.isCharacters()) {
if(currentElement.equals("whom") && event.isCharacters()) {
System.out.println(event.asCharacters().getData());
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(XMLStreamException xse) {
}
}
}

In lines 17 – 20 we initialize our parser. The most important thing, is to get an implementation of an XMLEventReader interface. This is the top level interface for parsing xml files which gives an access to all methods that we need. In order to get this implementation we need XMLInputFactory and InputStream with the xml file we want to parse.
In the next part of code we can see the usage of an XMLEventReader interface. The methods that we take advantage of are as follows:
hasNext() It checks if there are more events
nextEvent() returns the next event
isStartElement() checks if the event is a start element, which means, for instance, an opening tag
isEndElement() as the previous method, just that it relates to an end element.
IsCharacters() checks if the event is the plain text, which means, the text between opening and closing tags.

Ok, so for now, we know how to get opening and closing tags, as well the content between them but let's say we would like to get the attributes of some tag and their values. In the lines 29-33 I achieve this with an iterator. The interface StartElement has a method getAttributes() that returns an iterator to the attributes which we can cast to the Iterator. After that the Attribute interface has the methods getName() and getValue() which we use to get the name and value of the tag's attributes.
It is that simple. So now on, if you have a large XML file you will know how big boys do handle it ;-).

Sunday, December 19, 2010

Call me!


Today you will have a great occasion to call someone you would never expect to call... a thread. We talked already about the concurrency on the blog: Threads part 1: The basics and Threads part 2: functions overview. But the problem with the previous solution to achieve simultaneous computation is the lack of explicit mechanism to retrieve the result from a thread. As luck would have it, since Java 1.5 we have an access to a new interface – Callable. In comparison to Runnable there are a few significant differences:
  • with Callable you can easily return a result of another execution thread.
  • with Callable you can throw checked exceptions.
  • with Callable you have to use a thread executor.
So far so good. Now, to get more familiar with it, let's have a look at some code:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


class Computation implements Callable<Integer> {

@Override
public Integer call() throws Exception {
int result = 0;
for(int i = 0; i < 10000; i++) {
for(int j = 0; j < 100000; j++) {
// Some taught computation
result += (i * j) - (i * j) + 1;
}
}
return result;
}

}

public class CallableExample {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(5);
Future<Integer> f1 = pool.submit(new Computation());
for(int i = 0; i < 10; i++) {
System.out.println(i);
}
try {
System.out.println(f1.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
pool.shutdown();
}
}

Ok, there are a few new elements regarding Callable. First of all, if we implement the Callable interface, we have to implement T call() method. This is where the action takes place, it's a method corresponding to the run() method from Runnable interface. And the other important thing – it's the place where we can throw an exception (Exception or any subclass).
When the class implementing Callable interface is ready, we can instantiate it and run through a submit() method of a thread executor what happens in line 27. The submit() method will return some implementation of a Future interface. It represents the thread's computation and provides a few useful methods, among others:
boolean isDone();
which returns true if the task is completed.
T get()
which returns a result of a task of type T, or if the task is not completed yet it waits until it's finished. Actually this could be achieved with a wait() method using a Runnable interface and calling it on the instance of a thread from the main execution thread.

And that's it. I'm sure that the above information and the sample code will let you use the Callable interface in appropriate way.

Wednesday, December 15, 2010

Type erasure in Java.

Probably every Java developer knows what type erasure is. In Oracle tutorial on Type Erasure we can read:

When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.

The generic types are only for the compile time - after the type checking they are removed and gone for good, for sake of legacy code. Are they really? Let's have a look at the code I just wrote:

import java.lang.reflect.Field;   
import java.lang.reflect.ParameterizedType;   
import java.lang.reflect.Type;   
  
class P1 {}   
class P2 {}   
class P3 {}   
  
class A<T1, T2, T3> { }   
  
public class Gen2 {    

    A<P1, Integer, P3> genTest = new A<P1, Integer, P3>();   
    public static void main(String[] args) throws Exception {      
        ParameterizedType genTestField = (ParameterizedType)Gen2.class.getDeclaredField("genTest").getGenericType();   
        for(Type type : genTestField.getActualTypeArguments() ) {   
            System.out.println(type);   
        }   
    }   


In the above code, we define a generic class A that can be parametrized - in the line 13 we instantiate this class with parameters P1, Integer and P3. And now,
through a reflection of Gen2 class and methods getDeclaredField(String) and getGenericType() we can elicit the parameters used during instantiating generic class A!
The code will print:
class P1
class java.lang.Integer
class P3
So in this way we can get exactly the generic parameters that were used. How this can be accomplished? As I already wrote, through a reflection. When we open a compiled Gen2.class file we can see a section "Signature":
Signature LA<LP1;Ljava/lang/Integer;LP3;>;
which shows the types that we were interested in. So apparently it seems that this information is not completely removed after the compilation time. From the bytecode yes, but in the .class file the information is still available!
In my opinion it's a very interesting and important example especially when we can read in many places that after the compilation we can't get the parameters anymore! Hope it was at least a little bit inspiring and encouraged you to read more on the reflection mechanism.

Saturday, December 11, 2010

String's split() method.


This will be short. Recently I had to use this simple String class method when developing a parser for some pdf documents. Everything was going well until one moment. In the document, among others I had to elicit a range value which was given in the format x..y (for instance, 1..32). After getting the string 1..32 I wanted to use split method to separate the bounds. So in the code it could look like this:


String range = "1..32";
String[] bounds = range.split("..");

But that didn't work! Why? The answer is very simple. The String's split method takes a regex expression as an argument! And in Java "." (a dot) in regex means any character. So that's why the returned array was empty! To solve it we have to use "\\" between any special regex character if we want it to be treated as a string character. So we should change the above code to:


String range = "1..32";
String[] bounds = range.split("\\.\\.");

That's simple! So remember: split's argument = regex expression! Wish all my readers remember this both on the exam and during the work with Java code.

Sunday, November 28, 2010

Java 7, where are you?


That's right. On the December 11 it will be round 4 years since the first release of Java 6. And I have to admit that it's quiet a long time in comparison to the previous versions. Ok, why don't have a little history lesson right now? Let's go back in time to end of 90s. Right before Christmas period, in '98, on December 8 Java 1.2 is published. A year and a half (May 8, 2000) after this Java 1.3 kicks in. Then again, not even 2 years and we had the Java 1.4 (February 6, 2002). And it keeps going. September 30, 2004 – Java 1.5, December 11, 2006 – 1.6. And today we have November 28 2010 and there is still no Java 7! Nearly 4 years! Of course we had plenty updates to Java 6 (more precisely 22) but I still claim it's a long time. You may probably wonder that there are lots of new features and important changes coming up soon. The reality though, is a little bit different. Soon – yes, in the mid of 2011. Lots and important? Let's have a look. As for the Java 7 we got 2 major Java Specification Requests. JSR #334 Small Enhancements to the Java Programming Language and JSR #335 Lambda Expressions for the Java Programming Language. In a nutshell, the #334 introduces the following features:
  • Strings in switch
  • Binary integral literals and underscores in numeric literals
  • Multi-catch and more precise rethrow
  • Improved Type Inference for Generic Instance Creation (diamond)
  • try-with-resources statement
  • Simplified Varargs Method Invocation
I don't say these changes are not cool. They actually are. For instance the Diamond syntax will let you replace
 Map<String, ArrayList<Integer>> m = new LinkedHashMap<String, ArrayList<Integer>>();  
with this:
 Map<String, ArrayList<Integer>> m = new LinkedHashMap<>();  

Another interesting feature is “try-with-resources statement”. You may wonder what this is. Have a look at the following example (sorry for the lack of proper code formatting but for some reason it doesn't work with this code):
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();

} finally {
br.close();
}
With the automatic resource management statement it will look like this:
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
This new enhanced try clause will automatically close the resource after the try block so in this case it will never happen that the programmer forgets about it. Oh, and any sorts of streams are welcome in the new try plus you can have more than one.

And my most favourite – the second point. You will be able to use underscores in numeric literals, like this:
int howCoolIsThis = 1_000_000;
No kidding. That's one of the points proposed for the Java 7 specification.

Ok. Let's go to the big one. Lambda expressions! Present in the huge rival of Java – C# and also in other languages like PHP or Javascript. And now very likely to be introduced to Java 7. Here is the glimpse of the request:
  • Lambda Expressions
  • SAM Conversion
  • Method References
  • Virtual Extension Methods
As for me, this is a real boost of Java 7 and the feature that will make an actual difference. Because let's be honest, the changes from the JSR #334 are really minor. Of course, they all are very useful (maybe except the underscore thing...), especially the Diamond syntax and will lead to the better quality of code but aren't these too few changes for 4 years?

Sunday, October 31, 2010

And here it is - certification summary!


Well, I must admit that it's been some time since the last article but I was really overwhelmed recently – I had to accommodate in a new apartment, settle down all the things at university and finally I have started to work as a Java Software Developer. But anyway, now all the issues are resolved and I'm back to blogging again!

So today I would like to make a summary of OCPJP certification. First of all, I'm really glad that I've taken upon this endeavor. I have learnt many new things about Java that I didn't use before. Actually I'm not sure if I will ever use it but it's good to know it anyway ;-). And as luck would have it, I already have noticed how has my marked value increased. I did mention that I got a job, didn't I? ;-) Alright but you might probably want to know what I did in preparation for this exam. So obviously on the first place there is a book, the only one, don't even think about getting any other - SCJP Sun Certified Programmer for Java 6 Exam. I read it twice. The first time was a quick review of the book and getting familiar with some completely new areas. The second time though was much more careful and full of experiments with the code. And that is really vital! Experiment with the code – without this you will score much lower than you could if you did it. I know, it takes some time but trust me on that, it's really worth it. Ok, so let's assume that you already read the book, as many times as you wanted and you are wondering what next... Well, in my case it was a series of mock tests. Mostly by Whizlab (http://www.whizlabs.com/scjp/certification-exam.html). But in this place I have one more important tip. After solving a mock test also do some experiments with the code in exercises, especially the ones that were not correct. And I guess that's all! If you do more or less what I've described I'm sure you will do well on the exam!

As for me, my next goal on the Oracle Certification path is Oracle Certified Professional, Java EE 5 Web Component Developer! Soon, you will be able to follow my preparation's activities to this exam!

Saturday, September 11, 2010

Oracle Certified Professional Java SE 6 Programmer exam passed!


Yes, that's it! On the 6th of September I made it with 95% score. Not bad at all! It means 57 out of 60 questions answered correctly! Frankly speaking, the exam didn't seem to be easy - many questions required me to think deeply not as it was with the Whizlabs' tests. Even though, I had had some spare time left at the end to review all the questions and afterwards could hit the magic button "end" which surprisingly... ended the exam! But don't worry! The fact that I passed the exam doesn't mean that I will stop posting the articles related to it. I have a list of topics that I want to bring up here and after my short holidays that I'm on right now I will resume writing! I will also say something more about my scores of the exam and add some important notes that might be helpful for other people preparing to become certified!