Back to Basics – Subtler Nuances – Part One

IllegalClass.java

//interfaces do not contain static methods – they are not overridden
public interface IllegalClass {
	public static void illegalMethod();
}

Parent.java

public class Parent {
	public static void toDo() {
		System.out.println("The Parent speaks!!");
	}
}

class Child extends Parent {
	public static void toDo() {
		System.out.println("The Child speaks!!");

	}

	public static void main(String args[]) {
		Parent parent = new Parent();
		parent.toDo();
		Parent child = new Child();
		child.toDo();
		Child childOfParent = new Child();
		childOfParent.toDo();
	}
}
/**
Note static toDo is not overridden. The execution sequence is not looked up at runtime!
And hence static methods cannot be contained in an interface.
C:\appletree>java Parent

The Parent speaks!!
The Parent speaks!!
The Child speaks!!
*/

ITooPromiseImplVarTest.java

class IPromiseImpl {
	String name = "Mattiz";
}

public class ITooPromiseImplVarTest extends IPromiseImpl {
	String name = "Porsche";

	public static void main(String[] args) {
		ITooPromiseImplVarTest iPromiseImpl = new ITooPromiseImplVarTest();
		System.out.println(iPromiseImpl.name);
		IPromiseImpl iPromise = new ITooPromiseImplVarTest();
		System.out.println(iPromise.name);
	}
};
/**
D:\appletree>java ITooPromiseImplVarTest
Porsche
Mattiz
*/

Original.java

public interface Original {
	public void doPicasso();
}

interface Duplicate {
	public void doMattisse(final int var);
}

interface Extender extends Original, Duplicate {
	public void cheapSkatePainting();
}

class AllRounder implements Extender {
	public void doPicasso() {
		System.out.println("Picasso Art Piece");
	}

	public void doMattisse(final int count) {
		System.out.println("Mattisse Art Piece number " + count);
	}

	public void cheapSkatePainting() {
		final int count = 10;
		System.out.println("My sad first attempt at painting " + count);
	}

	public static void main(String args[]) {
		AllRounder ronaldo = new AllRounder();
		ronaldo.doPicasso();
		int count = 11;
		ronaldo.doMattisse(count);
		ronaldo.cheapSkatePainting();
	}
}
/*
An interface can extend multiple interfaces!!

C:\appletree>java Original
Picasso Art Piece
Mattisse Art Piece number 11
My sad first attempt at painting 10
*/

MyPromise.java

public interface MyPromise{
int length = 10;
}
class MyPromiseImpl implements MyPromise
{
int length = MyPromise.length;//compiles fine
MyPromise.length = 25;//does not compile. length is by default - public static final in the interface
};

IPromise.java

public interface IPromise {
	void toDo();
}

class IPromiseImpl implements IPromise {
	private void toDo() {
		System.out.println("Promised");
	}
}
/*

toDo() is by default public in IPromise interface. It is overridden by a class in which toDo has lower visibility - compile time error

D:\appletree>javac IPromise.java
IPromise.java:7: toDo() in IPromiseImpl cannot implement toDo() in IPromise; attempting to assign weaker access privileges; was public
private void toDo(){
^
1 error
*/

IPromiseAnExceptionImpl.java

interface IPromiseAnException {
	public void toDo() throws Exception;
}

public class IPromiseAnExceptionImpl implements IPromiseAnException {
	public static void main(String[] args) {
		IPromiseAnExceptionImpl iPromiseImpl = new IPromiseAnExceptionImpl();// compiles
																				// fine
		iPromiseImpl.toDo();// compiles fine
		IPromiseAnException iPromise = new IPromiseAnExceptionImpl();// compiles
																		// fine
		iPromise.toDo();// compile time error
	}

	public void toDo() {
		System.out.println("Implemented");
	}
}
/*

Compiler sees an exception thrown by parent class, overriding occurs at runtime

D:\appletree>javac IPromiseAnExceptionImpl.java
IPromiseAnExceptionImpl.java:9: unreported exception java.lang.Exception; must be caught or declared to be thrown
iPromise.toDo();
^
1 error
*/

ITooPromiseAnExceptionImpl.java

import java.sql.SQLException;

class IPromiseAnExceptionImpl implements IPromiseAnException {
	public void toDo() throws Exception {
		System.out.println("Implemented");
	}
}

public class ITooPromiseAnExceptionImpl extends IPromiseAnExceptionImpl {
	public void toDo() throws SQLException {
		System.out.println("Done");
	}

	public static void main(String[] args) {
		try {
			ITooPromiseAnExceptionImpl iPromiseImpl = new ITooPromiseAnExceptionImpl();// compiles
																						// fine
			iPromiseImpl.toDo();
			IPromiseAnExceptionImpl iPromise = new ITooPromiseAnExceptionImpl();// compiles
																				// fine
			iPromise.toDo();// runtime selection of execution call in either
							// case.
		} catch (Exception e) {
			// do something
		}
	}
};
/*
SQL Exception subset of Exception - hence no compile time error
D:\appletree>javac ITooPromiseAnExceptionImpl.java

D:\appletree>java ITooPromiseAnExceptionImpl
Done
Done
*/

CastTester.java

//result of int sized or smaller expresssions is always an int
public class CastTester {
	public void toDo() {
		byte b = 2;// valid -> (byte)27
		char c = 8;// valid -> (char)89
		short m = 90;// valid -> (short)90
		byte a = (b + c);
		// expression equates to int, no casting done.. compile time error
	}

	public static void main(String args[]) {
		CastTester castTester = new CastTester();
		castTester.toDo();
	}
}
/*
C:\appletree>javac CastTester.java
CastTester.java:7: possible loss of precision
found   : int
required: byte
byte a = (b+c);
^
1 error
*/

CastTester2.java

//result of int sized or smaller expresssions is always an int
public class CastTester2 {
	public void toDo() {
		byte b = 2;// valid -> (byte)27
		char c = 8;// valid -> (char)89
		short m = 90;// valid -> (short)90
		short a = (b + c);// expression evaluates to int at runtime.. no
							// explicit cast to short
	}

	public static void main(String args[]) {
		CastTester2 castTester2 = new CastTester2();
		castTester2.toDo();
	}
}
/*
C:\appletree>javac CastTester2.java
CastTester2.java:7: possible loss of precision
found   : int
required: short
short a = (b+c);
^
1 error
*/

CastTester3.java

//result of int sized or smaller expresssions is always an int
public class CastTester3 {
	public void toDo() {
		byte b = 2;// valid -> (byte)27
		char c = 8;// valid -> (char)89
		short m = 90;// valid -> (short)90
		float f = 34.4;// not valid double assigned to float..no implicit cast
						// to float
	}

	public static void main(String args[]) {
		CastTester3 castTester3 = new CastTester3();
		castTester3.toDo();
	}
}
/*
C:\appletree>javac CastTester3.java
CastTester3.java:7: possible loss of precision
found   : double
required: float
float f = 34.4;//
^
1 error]
*/

MyOuter.java

public class MyOuter {
	static class MyNested {
		public MyNested() {
			System.out.println("Body of Nested Inner Class");
		}
	}

	public static void main(String args[]) {
		MyOuter.MyNested myNested = new MyOuter.MyNested();
	}
}
/*
C:\appletree>java MyOuter
Body of Nested Inner Class
*/

Marshalling a document using JIBX

Just as you can create objects out of XML, JIBX allows you to create XML out of objects too. The magic of JIBX is that it allows as many has-a relationships within a hierarchal structure. I made just the following changes to the MattizMain.java class. And it worked like a charm.

The MattizMain with changes from the previous example:

package com.mattiz.main;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.JiBXException;
import com.mattiz.vo.Author;
import com.mattiz.vo.Book;

public class MattizMain {
	public void convertToXMl() {
		try {
			Author author = new Author();
			author.setName("Mattiz Cuppajava");
			Book book1 = new Book();
			book1.setTitle("The follies of Old Age");
			book1.setIsbn("uio32o4324");

			Book book2 = new Book();
			book2.setTitle("Ethical shoplifting");
			book2.setIsbn("435rdfsgf");

			Book book3 = new Book();
			book3.setTitle("The purdah and beyond");
			book3.setIsbn("43543fdad");

			Book book4 = new Book();
			book4.setTitle("Tales by Hashmi");
			book4.setIsbn("fdsr34r332");

			ArrayList bookslist = new ArrayList();
			bookslist.add(book1);
			bookslist.add(book2);
			bookslist.add(book3);
			bookslist.add(book4);
			author.setBookList(bookslist);
			String mattizXml = null;
			// Marshall document using Jibx
			IBindingFactory bindingFactory = BindingDirectory
					.getFactory(Author.class);
			IMarshallingContext iMarshallingContext = bindingFactory
					.createMarshallingContext();
			ByteArrayOutputStream authorXmlOutputStream = new ByteArrayOutputStream();
			iMarshallingContext.marshalDocument(author, "UTF-8", null,
					authorXmlOutputStream);
			mattizXml = authorXmlOutputStream.toString();
			System.out.println(mattizXml);
		} catch (JiBXException jibxe) {
			jibxe.printStackTrace();
		}
	}

	public static void main(String args[]) {
		MattizMain mattizMain = new MattizMain();
		mattizMain.convertToXMl();
	}
}

Here is the output XML from the sys out.

<?xml version="1.0" encoding="UTF-8"?>
<Author xmlns="http://www.com/mattiz/vo">
    <Book>
        <Title>The follies of Old Age</Title>
        <Isbn>uio32o4324</Isbn>
    </Book>
    <Book>
        <Title>Ethical shoplifting</Title>
        <Isbn>435rdfsgf</Isbn>
    </Book>
    <Book>
        <Title>The purdah and beyond</Title>
        <Isbn>43543fdad</Isbn>
    </Book>
    <Book>
        <Title>Tales by Hashmi</Title>
        <Isbn>fdsr34r332</Isbn>
    </Book>
    <Name>Mattiz Cuppajava</Name>
</Author>

JIBX Unmarshalling

I am demonstrating a simple jibx example. Jibx is used to parse XML documents and create Java objects out of them by unmarshalling and vice versa through marshalling.
To begin with you only need the requisite jars, a meaningful xsd file, a build.xml for the purpose and a relevant folder structure.
If you are using Eclipse, remember to set the default output folder to the folder where the build delivers your class files, failing which you will get cryptic errors indicating that jibx is looking for the class files in the wrong folder.
The jars I needed were:

bcel.jar
commons-lang-2.0.jar
commons-logging-1.0.4.jar
jaxme-js-0.3.jar
jibx-bind.jar
jibx-extras.jar
jibx-run.jar
qdox-1.6.1.jar
stax-api.jar
wstx-asl.jar
xmlpull_1_1_4.jar
xpp3.jar
xsd2jibx.jar

You don’t even need to initially create classes, the objects of which you are going to create from the input xml file – jibx utilities can do it for you.
You need a proper directory structure. My directory structure looks as follows:

<root>
     <lib>
          jibx jars
     <src>
          <com.mattiz.main>
               MattizMain.java(class that does jibx unmarshalling)
          <com.mattiz.vo>
              (..jibx generator populates this folder with POJOs..)
     <classes>
          (..populated by java &amp; jibx compilers...)
     <docs>
          <xml>
              Author.xsd(used for creation of POJOs by jibx utility based on xsd)
              mattiz.xml(input xml to be unmarshalled)
build.xml(jibx compilation and java source compilation)
build-generate.xml(POJO creation - one time process)

Jibx utility jars allow you to create java classes on the fly from the description in the xsd file.
My xsd file looks like this:

Author.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.com/mattiz/vo" xmlns="http://www.com/mattiz/vo"
	xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
	<xs:complexType name="Book">
		<xs:sequence>
			<xs:element name="Title" type="xs:string" nillable="false" />
			<xs:element name="Isbn" type="xs:string" nillable="false" />
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="Author">
		<xs:sequence>
			<xs:element name="Book" type="Book" maxOccurs="unbounded" />
			<xs:element name="Name" type="xs:string" nillable="false" />
		</xs:sequence>
	</xs:complexType>
</xs:schema>

Now you are ready to create the pojos using the following build-generate.xml

<project name="Mattiz" default="generate-jibx">
	<property file="build.properties" />
	<target name="clean">
		<delete dir="classes" />
	</target>
	<path id="classpath">
		<fileset dir="lib" includes="**/*.jar" />
	</path>
	<target name="generate-jibx">
		<echo message="Generating Jibx mappings" />
		<java classname="org.jibx.xsd2jibx.Generate" fork="yes"
			classpathref="classpath" failonerror="true">
			<classpath path="src" />
			<arg value="-d" />
			<arg value="src" />
			<arg value="docs/xml/Author.xsd" />
		</java>
		<move file="src/com/mattiz/vo/binding.xml" tofile="src/com/mattiz/vo/binding-Author.xml" />
	</target>
</project>

Once you run build-generate.bat file you see that

src/<com.mattiz.vo>

is populated with Author.java and Book.java – jibx generated POJOs and a binding file – binding-Author.xml.
Generation is a one time process once you have no other changes to the xsd file.
Here is how my JIBX generated files look like:

Author.java

package com.mattiz.vo;

import java.util.ArrayList;

public class Author {
	protected String name;

	public void addBook(Book book) {
		bookList.add(book);
	}

	public Book getBook(int index) {
		return (Book) bookList.get(index);
	}

	public int sizeBookList() {
		return bookList.size();
	}

	public ArrayList getBookList() {
		return this.bookList;
	}

	public void setBookList(ArrayList bookList) {
		this.bookList = bookList;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	protected ArrayList bookList = new ArrayList();
}

Book.java

package com.mattiz.vo;

public class Book {
	protected String title;
	protected String isbn;

	public String getTitle() {
		return this.title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getIsbn() {
		return this.isbn;
	}

	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}
}

The binding-Author.xml is also system generated:
It looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<binding>
	<mapping name="Book" class="com.mattiz.vo.Book">
		<namespace uri="http://www.com/mattiz/vo" default="elements" />
		<value name="Title" field="title" usage="required" />
		<value name="Isbn" field="isbn" usage="required" />
	</mapping>
	<mapping name="Author" class="com.mattiz.vo.Author">
		<namespace uri="http://www.com/mattiz/vo" default="elements" />
		<collection field="bookList">
			<structure map-as="com.mattiz.vo.Book" />
		</collection>
		<value name="Name" field="name" usage="required" />
	</mapping>
</binding>

Jibx compilation compiles the POJOs created in the previous step into Jibx classes. The following build.xml does this:

<project name="Mattiz" default="compile">
	<target name="clean">
		<delete dir="classes" />
	</target>
	<path id="classpath">
		<fileset dir="lib" includes="**/*.jar" />
	</path>
	<target name="compile" depends="compile-src, compile-jibx" />
	<target name="compile-src" depends="clean">
		<mkdir dir="classes" />
		<javac srcdir="src" destdir="classes" classpathref="classpath"
			debug="on">
			<include name="**/*.java" />
		</javac>
		<copy file="docs/xml/mattiz.xml" tofile="classes/com/mattiz/vo/mattiz.xml" />
	</target>
	<target name="compile-jibx">
		<echo message="Compiling Jibx mappings" />
		<java classname="org.jibx.binding.Compile" fork="yes"
			classpathref="classpath" failonerror="true">
			<classpath path="classes" />
			<arg value="-l" />
			<arg value="src/com/mattiz/vo/binding-Author.xml" />
		</java>
	</target>
</project>

Once you run build.xml file you see that your classes folder has the Author.class and Book.class files and in addition to this, JIBX compiler generated class files beginning with JIBX_

Now you are ready to perform the final steps.
MattizMain.java performs the jibx conversion of an xml to objects(Author and Book classes)

package com.mattiz.main;

import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;

import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;

import com.mattiz.vo.Author;
import com.mattiz.vo.Book;

public class MattizMain {
	public void extractListFromXML() {
		ClassLoader classLoader = Thread.currentThread()
				.getContextClassLoader();
		if (classLoader == null)
			classLoader = this.getClass().getClassLoader();
		File xmlFile = new File(classLoader.getResource(
				"./com/mattiz/vo/mattiz.xml").getPath());
		try {
			InputStream in = new FileInputStream(xmlFile);
			Closeable stream = in;
			Reader reader = new InputStreamReader(in, "UTF-8");
			stream = reader;
			StringBuilder inputBuilder = new StringBuilder();
			char[] buffer = new char[1024];
			while (true) {
				int readCount = reader.read(buffer);
				if (readCount < 0) {
					break;
				}
				inputBuilder.append(buffer, 0, readCount);
			}
			stream.close();
			String authorXML = inputBuilder.toString();
			// Unmarshall document using Jibx
			IBindingFactory bindingFactory = BindingDirectory
					.getFactory(Author.class);
			IUnmarshallingContext unmarshallingContext = bindingFactory
					.createUnmarshallingContext();
			Author author = (Author) unmarshallingContext.unmarshalDocument(
					new ByteArrayInputStream(authorXML.getBytes("UTF-8")),
					"UTF-8");
			// Extract list
			List bookslist = author.getBookList();
			System.out.println(author.getName());
			Iterator bli = bookslist.iterator();
			while (bli.hasNext()) {
				Book book = (Book) bli.next();
				System.out.println(book.getIsbn());
				System.out.println(book.getTitle());
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException uee) {
			uee.printStackTrace();
		} catch (JiBXException jibxe) {
			jibxe.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String args[]) {
		MattizMain mattizMain = new MattizMain();
		mattizMain.extractListFromXML();
	}
}

The xml source is mattiz.xml

<?xml version="1.0" encoding="UTF-8"?>
<author xmlns="http://www.com/mattiz/vo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.com/mattiz/vo">
	<book>
		<title>
<![CDATA[Seven Ways to Success]]>
		</title>
		<isbn>4324fd3243dgfd</isbn>
	</book>
	<book>
		<title>
<![CDATA[Seven Ways to Learn Chinese]]>
		</title>
		<isbn>vcxzvvzczr34</isbn>
	</book>
	<book>
		<title>
<![CDATA[Success in Seven Days]]>
		</title>
		<isbn>dfvcz43432xrrerw</isbn>
	</book>
	<book>
		<title>
<![CDATA[Sailing the Seven Seas]]>
		</title>
		<isbn>ffadf34242</isbn>
	</book>
	<book>
		<title>
<![CDATA[Seven Times in a Row]]>
		</title>
		<isbn>fdsfa3432432</isbn>
	</book>
	<name>Marc Figowitz</name>
</author>

The output looks something like this:

Marc Figowitz
4324fd3243dgfd Seven Ways to Success
vcxzvvzczr34 Seven Ways to Learn Chinese
dfvcz43432xrrerw Success in Seven Days
ffadf34242 Sailing the Seven Seas
fdsfa3432432 Seven Times in a Row