Monday, May 31, 2010

Spring 3: OXM... Castor, JAXB, JibX and xmlBeans (And XStream)

Updated to include XStream

Another reason to love Spring... OXM...

Basically there are 5 common Object to XML mapping projects out there... Castor, JaxB, XStream ,JibX and xmlBeans. Since I am lazy an a fan of reuse I won't be going into JibX as this other blogger (Guido Schumtz) did it quite nicely:
JibX Maven Spring OXM

I won't describe xmlBeans either, 'cause as soon as I saw that the objects need to extend XmlObject I lost interest... I don't wanna have to change my class hierarchy just to do mappings, that is so very 90's.

I did however slap together a quick Castor, JaxB and XStream example:
You need a bean that you want to map in and out of xml in this case (ClassToXMLMap.java)
package javaitzen.spring.oxm;

import javax.xml.bind.annotation.XmlRootElement;
import com.thoughtworks.xstream.annotations.XStreamAlias;

@XmlRootElement(name="ClassToXMLMap")
@XStreamAlias( "ClassToXMLMap" )
public class ClassToXMLMap {
 private String data;
 private String history;
 
 public String getData() {
  return data;
 }
 
 public void setData(String data) {
  this.data = data;
 }
 
 public String getHistory() {
  return history;
 }
 
 public void setHistory(String history) {
  this.history = history;
 } 
}


Then a class to use the Spring marshallers:
package javaitzen.spring.oxm;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;

public class OXMarshall {
    
    private Marshaller marshaller;
    private Unmarshaller unmarshaller;

    public void setMarshaller(Marshaller marshaller) {
        this.marshaller = marshaller;
    }

    public void setUnmarshaller(Unmarshaller unmarshaller) {
        this.unmarshaller = unmarshaller;
    }

    public void saveXML(ClassToXMLMap message, String fileName) throws IOException {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(fileName);
            this.marshaller.marshal(message, new StreamResult(fos));
        } finally {
            if (fos != null) {
                fos.close();
            }
        }
    }

    public ClassToXMLMap loadXML(String fileName) throws IOException {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(fileName);
            return (ClassToXMLMap) this.unmarshaller.unmarshal(new StreamSource(fis));
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
    }    
}


The JUnit Test:
package javaitzen.spring.oxm;

import static org.junit.Assert.assertNotNull;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@ContextConfiguration(locations={"/javaitzen/spring/oxm/applicationContext.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class OXMTest {

 @Autowired
 OXMarshall castor;
 
 @Autowired
 OXMarshall jax;

 @Autowired
 OXMarshall xtream;
 
 ClassToXMLMap message;
 
 @Before
 public void setup(){
     message = new ClassToXMLMap();
     message.setData("I am data");
     message.setHistory("in the past");
 }
 
 @Test
 public void testCastor() throws Exception{
  String castorFile = "castor.xml";
  castor.saveXML(message, castorFile);
        assertNotNull(castor.loadXML(castorFile));
 }
 
 @Test
 public void testJaxB() throws Exception{
  String jaxbFile = "jaxb.xml";
     jax.saveXML(message,jaxbFile);
        assertNotNull(jax.loadXML(jaxbFile));
 }

 @Test
 public void testXStream() throws Exception{
        String xtreamFile = "xtream.xml";
        xtream.saveXML(message,xtreamFile);
        assertNotNull(xtream.loadXML(xtreamFile));
    }
 
}


The mapping file for Castor:



The application context for the Test:


Hint: If you want to use xmlBeans or JibX there are tags defined for them by Spring, and you will be able to substitute them for the ones in my example.



Last but not least the Maven pom file:

Wednesday, May 26, 2010

Exposing a Java Class Via Spring and HTTP Invoker

Some time back I needed to expose a class as a "webservice", being lazy and crazy about Spring, I, like always, had a look at the framework that takes us all to a happy place.

a little while later, with a config here.. and a config there... A class exposed via http.

Ok so you need a web project with a web.xml that looks like:



    
  remoting
  
org.springframework.web.servlet.DispatcherServlet

  1
  
 
  remoting
  /httpremote/*
 


    
        
            30
        
    
    
        index.jsp
        
    


a remoting-servlet.xml Spring context file:



    
        
            
        
        
            bob.blog.NormalPojo
        
    





And the Java interface and class you want to expose:
package bob.blog;

public interface NormalPojo {

    void myExposedMethod(final String input);
    
}

package bob.blog;

public class NormalPojoImpl implements NormalPojo {

    public void myExposedMethod(String input) {
 System.out.println("Method Called with: " + input);
    }

}


That is all for the "Service" part... Once the war is deployed you can call it via http from a client. The client is also pretty simple, the reason I included the org.apache.commons.httpclient.HttpClient config in the application context was to be able to configure the timeout of the http call and one very nasty little thing you wouldn't expect. The default implementation is not thread safe.... that lead to some lets say "interesting" bugs, thankfully there is a thread safe implementation (MultiThreadedHttpConnectionManager, the one I used in the config below).

Hint: make sure the bean name in you server "/pojo-httpinvoker", the context in you web.xml "/httpremote/*" and client config all tie up "http://localhost:80/httpremote/pojo-httpinvoker".

You'll need an applicationContext.xml:



    
        
            
                
                    60000
                
            
        
        
            
                
                    
                        20
                    
                
            
        
    

    
        
    

    
        

http://localhost:80/httpremote/pojo-httpinvoker"

        
            bob.blog.NormalPojo
        
        
    




And then just use it as per any other Spring bean:

ApplicationContext ctx = new ClassPathXmlApplicationContext("bob/blog/applicationContext.xml");
NormalPojo testhttp = (NormalPojo) ctx.getBean("pojoHttp");
testhttp.myExposedMethod("whoo hoo");

Tuesday, May 25, 2010

Little Eclipse Gem - Regex Syntax in search...

I have been using eclipse for quite some time, but discovered a neat little feature today. When doing a file search select the Regular Expression checkbox... then hit Ctrl + Space on the search field.

Tah-dahh Content assist and basic syntax checking for regular expression searches...

Very handy when I needed to find / replace some very specific XML used across about 30 projects...

The query:
\Q\E.+\Q\E

Sunday, May 23, 2010

String Regex and Date Format

Even though these classes have been around for years, I quite often see people handle String manipulation and Date formatting is some "interesting" ways.

I was reading some log files checking dates and graphing the result with jfreechart and came up with, seems quite clean and neat.

package bob.blog;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * The Class FindADateInAString.
 */
public class FindADateInAString {
 
 /** The formatter. */
 private static SimpleDateFormat formatter = (SimpleDateFormat) DateFormat
 .getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
 
 
 /**
  * The main method.
  *
  * @param args the arguments
  * @throws ParseException the parse exception
  */
 public static void main(String[] args) throws ParseException {
  List< Date > dates = returnDatesFromAString("This string contains some random dates: 2010-03-06 01:11:06 and 2009-03-10 23:11:05");
  System.out.println(dates);
 }
 
 
 /**
  * Return dates from a string.
  *
  * @param toParse the to parse
  * @return the list
  * @throws ParseException the parse exception
  */
 public static List< Date > returnDatesFromAString(final String toParse) throws ParseException{
  List< Date > dates = new ArrayList< Date >();
  String regex = "(\\d+\\-)+\\d+\\s(\\d+\\:)+\\d+";
  Pattern pattern = Pattern.compile(regex);
  Matcher matcher = pattern.matcher(toParse);

  while (matcher.find()) {
   formatter.applyPattern("yyyy-MM-dd hh:mm:ss");
   dates.add(formatter.parse(matcher.group()));
  }
  
  return dates;
 }
 
 
}


Saturday, May 22, 2010

Hashtable vs. HashMap and a little thing called Entry

This was just to check if there are any real performance issues between Hashtable, HashMap and Collections.synchronizedMap(map), and as it turns out... it ain't that that bad... and even though the Hashtable is synchronized it still reads faster.

Something else to note, iterating via the entry set far out performs a regular get.
So when sequentially going through a map it's probably the way to go.

Hashtable

Does NOT allow null in either the key or the value. Will throw java.lang.NullPointerException.
It is synchronized.

HashMap

Allows null in either the key or the value.
It is NOT synchronized.

package bob.blog;

import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;

/**
 * The Class HashtableVsHashmap.
 */
public class HashtableVsHashmap {

    private static Map< String, String > map;

    private static String bob = new String("bob");

    private static final int iter = 500000;

    private static long start = 0;

    private static long end = 0;

    /**
     * The main method.
     * 
     * @param args the arguments
     */
    public static void main(final String[] args) {

 hashtablePerf();
 hashmapPerf(false);
 hashmapPerf(true);
    }

    /**
     * Hashmap perf.
     */
    private static void hashmapPerf(final boolean syncd) {

 // HashMap
 map = new HashMap< String, String >();
 if (syncd) {
     map = Collections.synchronizedMap(map);
 }
 start = System.currentTimeMillis();
 for (int i = 0; i < iter; i++) {
     map.put(bob + i, bob);
 }
 map.put(null, null);
 end = System.currentTimeMillis();
 System.out.println("Inserting HashMap: " + (end - start) + " ms - Synchronized: " + syncd);

 start = System.currentTimeMillis();
 for (int i = 0; i < iter; i++) {
     map.get(bob + i);
 }

 end = System.currentTimeMillis();
 System.out.println("Reading HashMap: " + (end - start) + " ms - Synchronized: " + syncd);
 
 start = System.currentTimeMillis();
 for(Entry< String, String > e : map.entrySet()){
     String val = e.getValue();
 }
 end = System.currentTimeMillis();
 System.out.println("Reading HashMap by Entry: " + (end - start) + " - Synchronized: " + syncd);
    }

    /**
     * Hashtable perf.
     */
    private static void hashtablePerf() {
 // Hashtable
 map = new Hashtable< String, String >();
 start = System.currentTimeMillis();
 for (int i = 0; i < iter; i++) {
     map.put(bob + i, bob);
 }
 end = System.currentTimeMillis();
 System.out.println("Inserting Hashtable: " + (end - start) + " ms");

 start = System.currentTimeMillis();
 for (int i = 0; i < iter; i++) {
     map.get(bob + i);
 }
 end = System.currentTimeMillis();
 System.out.println("Reading Hashtable: " + (end - start) + " ms");

 start = System.currentTimeMillis();
 for(Entry< String, String > e : map.entrySet()){
     String val = e.getValue();
 }
 end = System.currentTimeMillis();
 System.out.println("Reading Hashtable by Entry: " + (end - start) + " ms");
 
    }

}

Output:
Inserting Hashtable: 640 ms
Reading Hashtable: 172 ms
Reading Hashtable by Entry: 31 ms
Inserting HashMap: 610 ms - Synchronized: false
Reading HashMap: 265 ms - Synchronized: false
Reading HashMap by Entry: 47 - Synchronized: false
Inserting HashMap: 625 ms - Synchronized: true
Reading HashMap: 282 ms - Synchronized: true
Reading HashMap by Entry: 46 - Synchronized: true

Wednesday, May 19, 2010

ArrayList vs. LinkedList

Today a colleague of mine raised the question of why use a ArrayList? and he that personally likes the LinkedList structure... obviously depending on situation.

We then posed the question,
How often do developers actually think why they use a certain collection... the answer is probably not enough :)

So anyways to brush up again I went digging:

From the Sun Java Tutorial:

There are two general-purpose List implementations — ArrayList and LinkedList. Most of the time, you'll probably use ArrayList, which offers constant-time positional access and is just plain fast. It does not have to allocate a node object for each element in the List, and it can take advantage of System.arraycopy when it has to move multiple elements at the same time. Think of ArrayList as Vector without the synchronization overhead.
If you frequently add elements to the beginning of the List or iterate over the List to delete elements from its interior, you should consider using LinkedList. These operations require constant-time in a LinkedList and linear-time in an ArrayList. But you pay a big price in performance. Positional access requires linear-time in a LinkedList and constant-time in an ArrayList. Furthermore, the constant factor for LinkedList is much worse. If you think you want to use a LinkedList, measure the performance of your application with both LinkedList and ArrayList before making your choice; ArrayList is usually faster.


So lets test that:
package bob.blog;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * The Class ArrayListVsLinkedList.
 */
public class ArrayListVsLinkedList {

 private static List< String > list;
 private static String bob = new String("bob");

 /**
  * The main method.
  * 
  * @param args
  *            the arguments
  */
 public static void main(String[] args) {
  long start = 0;
  long end = 0;
  final int iter = 2000000;
  // ArrayList
  start = System.currentTimeMillis();

  list = new ArrayList< String >();
  for (int i = 0; i < iter; i++) {
   list.add(bob);
  }
  end = System.currentTimeMillis();
  System.out.println("ArrayList: " + (end - start) + " ms");

  // LinkedList
  start = System.currentTimeMillis();

  list = new LinkedList< String >();
  for (int i = 0; i < iter; i++) {
   list.add(bob);
  }
  end = System.currentTimeMillis();
  System.out.println("LinkedList: " + (end - start) + " ms");
 }

}

The output for that on my machine:
ArrayList: 138 ms
LinkedList: 481 ms

So that is +-3.5 times faster...

I still need to come up with a nice way to compare memory size, and maybe some other operations to compare and test, but this is start.

Monday, May 17, 2010

ClassNotFoundException vs. NoClassDefFoundError

I have quite often seen people mistake a ClassNotFoundException for a NoClassDefFoundError and vice versa. So here is a break down on the differences.

java.lang.ClassNotFoundException: Class is not in the classpath, this could be due to there being 2 different active class loaders and each having different visibility, (this is often the case when working within application servers where you are not in control of the current class loaders), or just that the class is actually no there.

java.lang.NoClassDefFoundError: Is quite different, and generally means that the class is there but there was error reading the class definition. This quite often happens when an exception occurs in a static initializer block or static variable instantiation. The JVM throws a java.lang.ExceptionInInitializerError and the "unloads" the definition, any further attempts at accessing this class then result in a java.lang.NoClassDefFoundError.

While discussing it with a work colleague of mine he wrote the following code to illustrate the behaviour:

public class App {
  public static void main(String[] args) {
    try {
      App.class.getClassLoader().loadClass("NonExistent");
    } catch (Throwable e) {
      System.out.println(e.getClass().getName());
    }
    
    try {
      new BadStatic();
    } catch (Throwable e) {
      System.out.println(e.getClass().getName());
      System.out.println(e.getCause().getClass().getName());
    }
    
    try {
      new BadStatic();
    } catch (Throwable e) {
      System.out.println(e.getClass().getName());
    }
    
  }

}

package za.co.classNotFoundBadness;

public class BadStatic {

  static {
    if(true){
      throw new IllegalArgumentException("I am a bad static initialiser.");
    }
  }
  
  public BadStatic() {
    
  }
  
}

Output:
java.lang.ClassNotFoundException
First attempt:
java.lang.ExceptionInInitializerError
java.lang.IllegalArgumentException
Second attempt:
java.lang.NoClassDefFoundError

Sunday, May 16, 2010

JAXB Context

Recently in one of the systems I work on, went through some bad times, we were struggling with performance, memory, and stability issues... during the days and days of investigations one of the many little improvements we made was the JAXBContextFactory. The JAXBContext proved to be a very very expensive object to make so I created a little Factory to cache the instances we created and reuse them:
package bob.blog;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

public final class JAXBContextFactory {

    private static JAXBContextFactory instance = new JAXBContextFactory();
    private static final Map< String, JAXBContext > instances = new ConcurrentHashMap< String, JAXBContext >();

    private JAXBContextFactory() {
    }

    /**
     * Returns an existing JAXBContext if one for the particular namespace exists, 
     * else it creates an instance adds it to a internal map.
     * @param contextPath the context path
     * @throws JAXBException exception in creating context
     * @return a created JAXBContext
     */
    public JAXBContext createJAXBContext(final String contextPath) throws JAXBException {
        JAXBContext context = instances.get(contextPath);
        if (context == null) {
            context = JAXBContext.newInstance(contextPath);
            instances.put(contextPath, context);
        }
        return context;
    }


        /**
     * Returns an existing JAXBContext if one for the particular namespace exists,
     * else it creates an instance adds it to a internal map.
     * @param contextPath the context path
     * @throws JAXBException exception in creating context
     * @return a created JAXBContext
     */
    public JAXBContext createJAXBContext(final Class contextPath) throws JAXBException {
        JAXBContext context = instances.get(contextPath.getName());
        if (context == null) {
            context = JAXBContext.newInstance(contextPath);
            instances.put(contextPath.getName(), context);
        }
        return context;
    }

    /**
     * Get instnace.
     * @return Instance of this factory
     */
    public static JAXBContextFactory getInstance() {
        return instance;
    }
}

Thursday, May 13, 2010

Looking for the .Jar a class belongs to?

Common issue in the life of a Java developer... Long time ago I used a site Jarhoo but unfortunately it is no longer free.
Thankfully jarfinder is still free

Wednesday, May 12, 2010

JNDI Tree viewer

If you have ever had to work with Weblogic 10... and actually had to use the JNDI tree, you will understand why I have the following piece of code. I know I grabbed bits of it off the net ages ago, no idea where though.

You just need the relevant jar in your classpath and the correct initial context and this should work for all J2EE servers.

If you want the whole JNDI Tree call with no context: printTree("");. If you aren't running on weblogic obviously remove "weblogic/jms".



package bob.blog;

import java.util.Properties;

import javax.naming.CannotProceedException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;


/**
 * The Class JNDITreePrinter.
 */
public class JNDITreePrinter {

    /**
     * The context.
     */
    private Context context = null;

    /**
     * The indent level.
     */
    private int indent = 0;

    /**
     * The main method.
     * 
     * Leave the param blank for the whole tree.
     * 
     * @param args the arguments
     * @throws Exception the exception
     */
    public static void main(String[] args) throws Exception {
    JNDITreePrinter printer = new JNDITreePrinter();
    System.out.println("----JMS---- ");
    printer.printTree("weblogic/jms");
    System.out.println("\n----JDBC---- ");
    printer.printTree("jdbc");
    System.out.println("\n----EJBS---- ");
    printer.printTree("ejb");
    System.out.println("--------");
    }

    /**
     * Instantiates a new jNDI tree printer.
     * 
     * @throws NamingException the naming exception
     */
    public JNDITreePrinter() throws NamingException {
    init();
    }

    /**
     * Inits the context.
     * 
     * @throws NamingException the naming exception
     */
    private void init() throws NamingException {
    Properties env = new Properties();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "user");
    env.put(Context.SECURITY_CREDENTIALS, "pass");
    env.put(Context.PROVIDER_URL, "t3://localhost:7001");
    context = new InitialContext(env);
    }

    /**
     * Prints the jndi tree.
     * 
     * @param ct the ct
     */
    public void printTree(String ct) {
    try {
        printTheEnum(context.list(ct), ct);
    } catch (CannotProceedException ce) {
        ce.printStackTrace();
    } catch (NamingException e) {
        e.printStackTrace();
    }

    }

    /**
     * Prints the NamingEnumeration.
     * 
     * @param namingEnum the naming enum
     * @param parentctx the parentctx to start with
     * @throws NamingException the naming exception
     */
    private void printTheEnum(NamingEnumeration<NameClassPair> namingEnum, String parentctx) throws NamingException {

    while (namingEnum.hasMoreElements()) {
        NameClassPair next = namingEnum.nextElement();
        System.out.println(createNextIndent() + "-->" + next);
        indent += 4;
        printTree((parentctx.length() == 0) ? next.getName() : parentctx + "/" + next.getName());
        indent -= 4;
    }

    }

    /**
     * Creates the next indent.
     * 
     * @return the string
     */
    private String createNextIndent() {
    StringBuilder bobthebuilder = new StringBuilder(indent);
    for (int i = 0; i < indent; i++) {
        bobthebuilder.append(" ");
    }
    return bobthebuilder.toString();
    }
}

Tuesday, May 11, 2010

5 Things Series at IBM

A guy at Neward & Associates, Ted Neward, started a Series "5 things you didn't know about ..." centered around Java.

They are roughly 10 page PDF's with some pearls of useful information, well worth the read.

http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=5+things+you+did

Popular Posts

Followers