Spotify’s Metadata Api released

November 19th, 2009

My favourite music streaming service released the first version of its Metadata API to provide information about available artists, tracks and albums. Currently there exist two services: one service to search for artists, tracks and albums and another one to lookup detailed information about the items retrieved through a search-request.

Unfortunately it’s not possible to create playlists inside your account with that API. For services like that you still have to use libspotify (a library written in C) together with a Premium Account.


Happy Coding,
Tino

Share/Save/Bookmark

tino Uncategorized

Google App Engine 1.2.6 released

October 14th, 2009
Five weeks after the last update, Google’s App Engine received another one to version 1.2.6 today. Besides some administrative enhancements in the admin console like exploring more detailed statistics of your datastore or deleting an app, it’s now possible to receive emails within your application.

Unfortunately, these are not the features I was waiting for…

More information can be found on Google’s App Engine Blog or in the release notes.

Happy Coding,
Tino

Share/Save/Bookmark

tino Google App Engine

Using static Factory-methods to create Generics

October 7th, 2009
Today I browsed through Project Coin and had a closer look at the language changes that made it into Java 7. Especially the proposal named ‘Improved Type Inference for Generic Instance Creation’ attracted my attention, because I already discovered a technique in Joshua Bloch’s great book Effective Java (2nd Edition) that helped me to reduce the effort to create Generics.
All you need is a Factory-class with static methods:

 Java |  copy code |? 
1
2
package com.java_blog.generics;
3
import java.util.HashMap;
4
 
5
public class GenericsFactory {
6
	public static <K, V> HashMap<K, V> newHashMap() {
7
		return new HashMap<K, V>();
8
	}
9
}


If you import these methods statically into your code, Generics-creation becomes very handy:


 Java |  copy code |? 
01
package com.java_blog.generics;
02
 
03
import java.util.HashMap;
04
import static com.java_blog.generics.GenericsFactory.newHashMap;
05
 
06
public class GenericsTest {
07
	public static void main(String[] args) {
08
 
09
		// old style
10
		HashMap<String, Integer> oldMap = new HashMap<String, Integer>();
11
 
12
		// new style
13
		HashMap<String, Integer> newMap = newHashMap();
14
	}
15
}


Happy Coding,
Tino


Share/Save/Bookmark

tino Java ,

Task Queue API for Java in Google’s App Engine

September 25th, 2009
I’m a big fan of Google’s Cloud Computing service Google App Engine (GAE), because

  • It’s free for my low personal requirements
  • It’s very easy to code and deploy GAE-projects using the available Eclipse-plugin
  • Together with Google Apps you get a free and easy to use Web-Hoster for your Java-Web-projects
Of course there are also quite many things I don’t like about GAE, but as long as I need not pay for the service, I’ll have to cope with them.

One of those limitations got removed during the last update couple of weeks ago:
The Task Queue API was finally released for Java! The Task Queue API for Python has been available since June, now Google gives the Java-version a try, too.

For my little personal web-application I need to do a bit of background-processing (and therefor created some ugly, but functioning workarounds using cronjobs), so I started playing around with the Task Queue trying to replace that code.
My conclusion? Very simple but yet powerful API! Works like a charm! Great work, Google-guys!

Though I have to admit that I really do not exhaust the 10k-tasks-per-day-limit, it would be nice if the duration-limit of 30 seconds per request could be doubled up to 60 seconds or so. The option of splitting long-running tasks into multiple short-running-ones is unfortunately not always feasible, so a higher limit of Task Queue requests compared to regular ones seems to be reasonable.

Happy Coding,

Tino.

Share/Save/Bookmark

tino Google App Engine, Java ,

Creating a simple cache in Java using a LinkedHashMap and an Anonymous Inner Class

June 28th, 2009
The processing costs for selecting a value from a database-table are fairly high compared to the costs having the value already in memory. So it seems preferrable to use some smart caching-mechanism that keeps often used values in your application instead of retrieving these values from resources somewhere ‘outside’.

Most frameworks have at least one cache implementation onboard, but there also exist several other implementations of caches like e.g. EHCache. Even ordinary HashMaps/Hashtables can serve as caches also.

A critial factor when using caches in Java is the size of the cache: when your cache grows too big, the Java Garbage Collector has to cleanup more often (which consumes time) or your application even crashes with a java.lang.OutOfMemoryError.

One way to control the memory-consumption of caches is to use SoftReferences in HashMaps/Hashtables, another one is to throw away old or unused content by implementing a caching-strategy like e.g. LRU.

A simple LRU-cache already ships within the components of the Java Standard Library: the LinkedHashMap. All you have to do is to tell your application whether the eldest entry in the map should be retained or removed after a new entry is inserted. Additionally a special constructor has to be used that defines the orderingMode for the map: ‘true’ for access-order (LRU), ‘false’ for insertion-order.

Suppose we want to cache a mapping of String-Names to Integer-Ids with a maximum size of 100 entries.
How that can be done is shown by the example below with the use of an Anonymous Inner Class that overrides the removeEldestEntry-method of the LinkedHashMap.
 Java |  copy code |? 
01
package com.java_blog;
02
 
03
import java.util.LinkedHashMap;
04
import java.util.Map;
05
 
06
 public class LinkedHashMapExample { 
07
 
08
      private final static int CACHE_MAX_SIZE = 100; 
09
      private LinkedHashMap<String, Integer> cache;
10
 
11
     @SuppressWarnings("serial")
12
      public LinkedHashMapExample() { 
13
 
14
            this.cache = new LinkedHashMap<String, Integer>(CACHE_MAX_SIZE, 0.75f, true) { 
15
                  protected boolean removeEldestEntry(
16
                             Map.Entry<String, Integer> eldest) {
17
                        // Remove the eldest entry if the size of the cache exceeds the
18
                        // maximum size
19
                        return size() > CACHE_MAX_SIZE;
20
                  }
21
            };
22
      } 
23
 
24
      public Integer getIdForName(String name) {
25
             Integer id = cache.get(name);
26
 
27
             if (id != null)
28
                  return id;
29
 
30
            else {
31
                  id = getIdForNameFromExternal(name);
32
                   // TODO Tino, 24.06.2009: what to do if no id could be found for the
33
                  // provided name in external resource?
34
                  cache.put(name, id);
35
                  return id;
36
            }
37
      }
38
 
39
      private Integer getIdForNameFromExternal(String name) {
40
             // TODO Tino, 24.06.2009: replace dummy-code
41
            return 1;
42
      }
43
}

Happy Coding,

Tino


Share/Save/Bookmark

tino Java ,

Serializing Java-Objects to XML and JSON using XStream

June 6th, 2009
One of the great benefits when working with Java is the fact that there exists a library for almost everything. Today I’d like to present one of those libraries: XStream!

XStream is a simple but very useful library when you want to serialize Java-Objects to XML (or JSON) and read them back again. Of course it would not be much effort to do that on your own when knowing about the concepts of Reflection and Recursion, but why reinventing the wheel when thoroughly tested and widely used code is already available?

The ease of use of the XStream-library can be described best by providing an example.

Let’s suppose we have the following class:

 Java |  copy code |? 
01
package com.java_blog.xStreamTest;
02
 
03
public class Person {
04
 
05
	private String firstName;
06
	private String lastName;
07
 
08
	public Person(String firstName, String lastName) {
09
		super();
10
		this.firstName = firstName;
11
		this.lastName = lastName;
12
	}	
13
}


and this TestCode:

 Java |  copy code |? 
01
package com.java_blog.xStreamTest;
02
 
03
import com.thoughtworks.xstream.XStream;
04
 
05
public class Test {
06
	public static void main(String[] args) {
07
 
08
		Person germanChancellor = new Person("Angela", "Merkel");
09
		Person usPresident = new Person("Barack", "Obama");
10
 
11
		XStream xStream = new XStream();
12
		xStream.alias("Person", Person.class);
13
 
14
		StringBuilder sb = new StringBuilder();		
15
		sb.append(xStream.toXML(germanChancellor));
16
		sb.append("\n");
17
		sb.append(xStream.toXML(usPresident));		
18
		System.out.println(sb);		
19
	}
20
}

output:
<Person>
  <firstName>Angela</firstName>
  <lastName>Merkel</lastName>
</Person>
<Person>
  <firstName>Barack</firstName>
  <lastName>Obama</lastName>
</Person>


Without using the alias in line 12, the <Person>-tag would look quite ugly: <com.java__blog.xStreamTest.Person>

If you prefer JSON over XML, simply invoke another XStream-constructor:

 Java |  copy code |? 
1
XStream xStream = new XStream(new JsonHierarchicalStreamDriver());

output:
{"Person": {
  "firstName": "Angela",
  "lastName": "Merkel"
}}
{"Person": {
  "firstName": "Barack",
  "lastName": "Obama"
}}


Further examples and features as well as limitations can be found on the XStream-project-page.

Happy Coding,

Tino.


Share/Save/Bookmark

tino Java, Libraries , , , ,

Mapping Java-Objects to a database using Reflection and Generics (Part 2)

May 2nd, 2009
This post is the second part of the series ‘Mapping Java-Objects to a database using Reflection and Generics’. In part one we covered the process of selecting entries from a database-table and instantiating Java-Objects with these entries using Reflection and Generics. Now we’ll have a look at the other side and insert some entries into the database. If you’ve understood the code-examples of the last post you won’t have any problems with the following snippets either.

 Java |  copy code |? 
01
import java.beans.IntrospectionException;
02
import java.beans.PropertyDescriptor;
03
import java.lang.reflect.Field;
04
import java.lang.reflect.InvocationTargetException;
05
import java.lang.reflect.Method;
06
import java.sql.Connection;
07
import java.sql.PreparedStatement;
08
import java.sql.SQLException;
09
import java.util.List;
10
 
11
/**
12
 * 
13
 * Class that inserts a list of <T>s into the corresponding database-table.
14
 * 
15
 * @author Tino for http://www.java-blog.com
16
 * 
17
 * @param <T>
18
 */
19
public class DatabaseInserter<T> extends AbstractDatabaseHandler<T> {
20
 
21
	public DatabaseInserter(Class<T> type,
22
			DatabaseConnecter databaseConnecter) {
23
		super(type, databaseConnecter);
24
	}
25
 
26
	@Override
27
	protected String createQuery() {
28
 
29
		StringBuilder sb = new StringBuilder();
30
 
31
		sb.append("INSERT INTO ");
32
		sb.append(type.getSimpleName());
33
		sb.append("(");
34
		sb.append(super.getColumns(false));
35
		sb.append(")");
36
		sb.append(" VALUES (");
37
		sb.append(super.getColumns(true));
38
		sb.append(")");
39
 
40
		return sb.toString();
41
	}
42
 
43
	/**
44
	 * Inserts a list of <T>s into the corresponding database-table
45
	 * 
46
	 * @param list
47
	 *            List of <T>s that should be inserted into the corresponding
48
	 *            database-table
49
	 * 
50
	 * @throws SQLException
51
	 * @throws SecurityException
52
	 * @throws IllegalArgumentException
53
	 * @throws InstantiationException
54
	 * @throws IllegalAccessException
55
	 * @throws IntrospectionException
56
	 * @throws InvocationTargetException
57
	 */
58
	public void insertObjects(List<T> list) throws SQLException,
59
			SecurityException, IllegalArgumentException,
60
			InstantiationException, IllegalAccessException,
61
			IntrospectionException, InvocationTargetException {
62
 
63
		Connection connection = null;
64
		PreparedStatement preparedStatement = null;
65
 
66
		try {
67
			connection = databaseConnecter.createConnection();
68
			preparedStatement = connection.prepareStatement(query);
69
 
70
			for (T instance : list) {
71
				int i = 0;
72
 
73
				for (Field field : type.getDeclaredFields()) {
74
					PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
75
							field.getName(), type);
76
 
77
					Method method = propertyDescriptor
78
							.getReadMethod();
79
 
80
					Object value = method.invoke(instance);
81
 
82
					preparedStatement.setObject(++i, value);
83
				}
84
 
85
				preparedStatement.addBatch();
86
			}
87
			preparedStatement.executeBatch();
88
 
89
		} finally {
90
			DatabaseResourceCloser.close(preparedStatement,
91
					connection);
92
		}
93
	}
94
}

You’ve probably noticed that Prepared Statement are used for the inserts. The proper use and the advantages/disadvanteges of Prepared Statements are covered in a post I published a while ago.

The non-trivial part of the insertObjects()-method should be familiar to you. All the Reflection- and Generics-stuff has already been discussed in part one. Instead of the PropertyDescriptor that provides the set()-method of the bean-class we use the get()-method to retrieve the value of the object here.

Putting it all together and test it


Below is a small main-method that demonstrates how the presented code can be used.
 Java |  copy code |? 
01
import java.util.ArrayList;
02
import java.util.List;
03
 
04
public class Main {
05
 
06
	/** For testing purposes */
07
	public static void main(String[] args) {
08
 
09
		try {
10
 
11
			DatabaseConnecter connecter = new MySqlDatabaseConnecter(
12
					new DatabaseConnectionSettingsImpl(
13
							"127.0.0.1", 3306, "exampleDatabase",
14
							"user", "pass"));
15
 
16
			List<Test> list = new ArrayList<Test>();
17
			list.add(new Test(1, "one"));
18
			list.add(new Test(2, "two"));
19
 
20
			DatabaseInserter<Test> inserter = new DatabaseInserter<Test>(
21
					Test.class, connecter);
22
 
23
			inserter.insertObjects(list);
24
 
25
			DatabaseSelecter<Test> selecter = new DatabaseSelecter<Test>(
26
					Test.class, connecter);
27
 
28
			list = selecter.selectObjects();
29
 
30
			for (Test test : list)
31
				System.out.println(test);
32
 
33
		} catch (Exception e) {
34
			e.printStackTrace();
35
		}
36
	}
37
}

The output should look like this:
Test (
 Test@19821f    
     id = 1    
     name = one    
 )
Test (
 Test@addbf1    
     id = 2    
     name = two    
 )


So, that’s it! In the upcoming posts we’ll leave the JDBC-area and look at some other interesting Java-functionality.

Happy Coding,

Tino

Share/Save/Bookmark

tino JDBC, Java , , , ,

Mapping Java-Objects to a database using Reflection and Generics (Part 1)

April 12th, 2009
Nowadays there are lots of tools and frameworks out there that help you mapping your Java-Objects to a relational database and vice versa. But the overwhelming functionality that’s provided by frameworks like Hibernate (one of the most popular Object-Relational-Mapping-frameworks) goes along with the effort needed for the proper configuration of these monsters. The work that’s needed for this configuration is certainly justified when you’re developing a big application that needs lots of tables to store your objects, but you surely won’t break a butterfly on a wheel when your application only needs some config-tables, for example.

An alternative might be to write SQL-statements for every config-class/table on your own, but that’s boring ;-)
Within the next two posts I’ll demonstrate another way to build a bridge between your Java-Objects and database-tables using some nice Java-features called Generics and Reflection.

The first post covers the reading from a database and the dynamically creation of object-instances with correct values, the second post will describe the writing into a database.

Gotten used to providing examples during my last posts about the proper use of Prepared Statements, the correct Closing of Database Resources and the Generation of a String from an Exception-Stacktrace, I’ll continue with the ‘example-first’-approach.

Prerequisites


Given the class listed below and a table like that:

CREATE TABLE `Test` (
`id` int(11) NOT NULL, `
name` varchar(255) NOT NULL)
ENGINE=InnoDB DEFAULT CHARSET=utf8;

 Java |  copy code |? 
01
public class Test {
02
	private int	     id;
03
	private String     name;
04
 
05
	public Test() {}
06
 
07
	public Test(int id, String name) {
08
		super();
09
		this.id = id;
10
		this.name = name;
11
	}
12
 
13
	public int getId() {
14
		return id;
15
	}
16
 
17
	public void setId(int id) {
18
		this.id = id;
19
	}
20
 
21
	public String getName() {
22
		return name;
23
	}
24
 
25
	public void setName(String name) {
26
		this.name = name;
27
	}
28
 
29
	public String toString() {
30
	    final String TAB = "    \n";
31
 
32
	    StringBuilder retValue = new StringBuilder();
33
 
34
	    retValue.append("Test (\n ")
35
	        .append(super.toString()).append(TAB)
36
	        .append("     id = ").append(this.id).append(TAB)
37
	        .append("     name = ").append(this.name).append(TAB)
38
	        .append(" )");
39
 
40
	    return retValue.toString();
41
	}	
42
}


We have to make some assumptions here that are reflected in the code later:

  1. The name of the table must exactly match the name of the Java-class (case-sensitive).
  2. The names of the table-columns must exactly match the name of the Java-fields (case-sensitive).
  3. The class itself must follow the Java-Beans convention:
    • The class must contain a public no-arg constructor.
    • For every field in the class there must exist a getxxx- and a setxxx-operation to access and mutate the fields.
If you don’t feel comfortable with these limitations, the code gets a little more complex, because you have do define some mappings between database- and Java-world by introducing e.g. Annotations.

Before we’ll divide the code into the reading- and writing-part, let’s create an abstract class that provides methods and attributes that are needed for reading from, as well as writing into the database. The code, respectively the code-comments, should be self-explaining, but have a look at the ‘<T>’ in the class-definition. This kind of definition allows us to parametrize the AbstractDatabaseHandler-class with the type of Java-object we want to handle. But more on that later.

 Java |  copy code |? 
01
02
 
03
/**
04
 * An abstract class that handles insert/select-operations into/from a database
05
 * 
06
 * @author Tino for http://www.java-blog.com
07
 * 
08
 * @param <T>
09
 */
10
public abstract class AbstractDatabaseHandler<T> {
11
 
12
	/**
13
	 * The type of the objects that should be created and filled with values
14
	 * from the database or inserted into the database
15
	 */
16
	protected Class<T>     type;
17
 
18
	/**
19
	 * Contains the settings to create a connection to the database like
20
	 * host/port/database/user/password
21
	 */
22
	protected DatabaseConnecter     databaseConnecter;
23
 
24
	/** The SQL-select-query */
25
	protected final String     query;
26
 
27
	/**
28
	 * Constructor
29
	 * 
30
	 * @param type
31
	 *            The type of the objects that should be created and filled with
32
	 *            values from the database or inserted into the database
33
	 * @param databaseConnecter
34
	 *            Contains the settings to create a connection to the database
35
	 *            like host/port/database/user/password
36
	 */
37
	protected AbstractDatabaseHandler(Class<T> type,
38
			DatabaseConnecter databaseConnecter) {
39
 
40
		this.databaseConnecter = databaseConnecter;
41
		this.type = type;
42
		this.query = createQuery();
43
	}
44
 
45
	/**
46
	 * Create the SQL-String to insert into / select from the database
47
	 * 
48
	 * @return the SQL-String
49
	 */
50
	protected abstract String createQuery();
51
 
52
	/**
53
	 * 
54
	 * Creates a comma-separated-String with the names of the variables in this
55
	 * class
56
	 * 
57
	 * @param usePlaceHolders
58
	 *            true, if PreparedStatement-placeholders ('?') should be used
59
	 *            instead of the names of the variables
60
	 * @return
61
	 */
62
	protected String getColumns(boolean usePlaceHolders) {
63
		StringBuilder sb = new StringBuilder();
64
 
65
		boolean first = true;
66
		/* Iterate the column-names */
67
		for (Field f : type.getDeclaredFields()) {
68
			if (first)
69
				first = false;
70
			else
71
				sb.append(", ");
72
 
73
			if (usePlaceHolders)
74
				sb.append("?");
75
			else
76
				sb.append(f.getName());
77
		}
78
 
79
		return sb.toString();
80
	}
81
}


Reading from the database


We start with the class that reads rows from a database and automatically creates and fills instances of Java-objects:

 Java |  copy code |? 
001
002
/**
003
 * 
004
 * Class that creates a list of <T>s filled with values from the corresponding
005
 * database-table.
006
 * 
007
 * @author Tino for http://www.java-blog.com
008
 * 
009
 * @param <T>
010
 */
011
public class DatabaseSelecter<T> extends AbstractDatabaseHandler<T> {
012
 
013
	public DatabaseSelecter(Class<T> type,
014
			DatabaseConnecter databaseConnecter) {
015
		super(type, databaseConnecter);
016
	}
017
 
018
	@Override
019
	protected String createQuery() {
020
 
021
		StringBuilder sb = new StringBuilder();
022
 
023
		sb.append("SELECT ");
024
		sb.append(super.getColumns(false));
025
		sb.append(" FROM ");
026
 
027
		/* We assume the table-name exactly matches the simpleName of T */
028
		sb.append(type.getSimpleName());
029
 
030
		return sb.toString();
031
	}
032
 
033
	/**
034
	 * Creates a list of <T>s filled with values from the corresponding
035
	 * database-table
036
	 * 
037
	 * @return List of <T>s filled with values from the corresponding
038
	 *         database-table
039
	 * 
040
	 * @throws SQLException
041
	 * @throws SecurityException
042
	 * @throws IllegalArgumentException
043
	 * @throws InstantiationException
044
	 * @throws IllegalAccessException
045
	 * @throws IntrospectionException
046
	 * @throws InvocationTargetException
047
	 */
048
	public List<T> selectObjects() throws SQLException,
049
			SecurityException, IllegalArgumentException,
050
			InstantiationException, IllegalAccessException,
051
			IntrospectionException, InvocationTargetException {
052
 
053
		Connection connection = null;
054
		Statement statement = null;
055
		ResultSet resultSet = null;
056
 
057
		try {
058
			connection = databaseConnecter.createConnection();
059
			statement = connection.createStatement();
060
			resultSet = statement.executeQuery(query);
061
 
062
			return createObjects(resultSet);
063
 
064
		} finally {
065
			DatabaseResourceCloser.close(resultSet, statement,
066
					connection);
067
		}
068
	}
069
 
070
	/**
071
	 * 
072
	 * Creates a list of <T>s filled with values from the provided ResultSet
073
	 * 
074
	 * @param resultSet
075
	 *            ResultSet that contains the result of the
076
	 *            database-select-query
077
	 * 
078
	 * @return List of <T>s filled with values from the provided ResultSet
079
	 * 
080
	 * @throws SecurityException
081
	 * @throws IllegalArgumentException
082
	 * @throws SQLException
083
	 * @throws InstantiationException
084
	 * @throws IllegalAccessException
085
	 * @throws IntrospectionException
086
	 * @throws InvocationTargetException
087
	 */
088
	private List<T> createObjects(ResultSet resultSet)
089
			throws SecurityException, IllegalArgumentException,
090
			SQLException, InstantiationException,
091
			IllegalAccessException, IntrospectionException,
092
			InvocationTargetException {
093
 
094
		List<T> list = new ArrayList<T>();
095
 
096
		while (resultSet.next()) {
097
 
098
			T instance = type.newInstance();
099
 
100
			for (Field field : type.getDeclaredFields()) {
101
 
102
				/* We assume the table-column-names exactly match the variable-names of T */
103
				Object value = resultSet.getObject(field.getName());
104
 
105
				PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
106
						field.getName(), type);
107
 
108
				Method method = propertyDescriptor.getWriteMethod();
109
 
110
				method.invoke(instance, value);
111
			}
112
 
113
			list.add(instance);
114
		}
115
		return list;
116
	}
117
}

The createQuery()- and selectObjects()-methods are trivial stuff, but the createObjects()-method deserves a closer look:

  • line 98: For every row in the resultSet a new instance of T is created.
  • line 100: We iterate over all fields that are declared in T. getDeclaredFields() returns even private fields in contrast to getFields().
  • line 103: Because we decided to have an exact match between the Java-field-names and the table-column-names, we can retrieve the value of the table-column by using the field-name.
  • line 105: The PropertyDescriptor gives us the method that can be used to mutate the value of a field (remember the Java-Bean convention mentioned above).
  • line 110: This method is invoked on the instance of type T with the value extracted from the resultSet.
  • line 113: At the end of the method we add every instance of T to a list of T’s that will be returned.
So guys, I think that’s enough for now! I’ll continue the post with the write-part and a test-method within the next days.

Happy Coding,

Tino

Share/Save/Bookmark

tino JDBC, Java , , ,

Generating String from Exception-Stacktrace

April 5th, 2009
When it comes to Exceptions in Java there are lots of strategies how to deal (or not to deal) with them. But don’t be scared: I won’t blog about correct Exception-Chaining or stuff like that.
But did you ever think about converting an Exception including the complete stacktrace into a String and e.g. send that String by email?

As Java developer you might think: Hey, an Exception extends java.lang.Object and therefore must have a toString()-method, that returns a String. That’s absolutely correct! But the resulting String only gives you the type of the Exception, rather than the complete stacktrace.

If you want to include all the information that is printed on std.err when doing a exception.printStackTrace(), a little more effort has to be made.

The class in the listing below shows how to achieve that with the use a StringWriter and a Printwriter.

 Java |  copy code |? 
001
import java.io.Closeable;
002
import java.io.Flushable;
003
import java.io.IOException;
004
import java.io.PrintWriter;
005
import java.io.StringWriter;
006
 
007
public class ExceptionToString {
008
 
009
	private final static String	SEPARATOR	= "\n -------- \n";
010
 
011
        /** For testing purposes */
012
	@SuppressWarnings("null")
013
	public static void main(String[] args) {
014
		try {
015
 
016
			Integer i = null;
017
			System.out.println(i.intValue());
018
 
019
		} catch (NullPointerException exception) {
020
 
021
			System.out.println("exception.printStackTrace():");
022
			exception.printStackTrace();
023
			System.out.println(SEPARATOR);
024
 
025
			System.out.println("exception.toString():");
026
			System.out.println(exception.toString());
027
			System.out.println(SEPARATOR);
028
 
029
			System.out.println("getStringFromException(exception):");
030
			System.out.println(getStringFromException(exception));
031
		}
032
	}
033
 
034
	/**
035
	 * Generates a String from the stacktrace of an Exception and returns that String
036
	 * 
037
	 * @param exception
038
	 * 
039
	 * @return the stacktrace of an Exception as String.
040
	 */
041
	protected static String getStringFromException(Exception exception) {
042
 
043
		if (exception == null)
044
			return null;
045
 
046
		StringWriter stringWriter = null;
047
		PrintWriter printWriter = null;
048
 
049
		try {
050
			stringWriter = new StringWriter();
051
			printWriter = new PrintWriter(stringWriter);
052
 
053
			exception.printStackTrace(printWriter);
054
 
055
			return stringWriter.toString();
056
 
057
		} finally {
058
			flush(printWriter, stringWriter);
059
			close(printWriter, stringWriter);
060
		}
061
	}
062
 
063
	/**
064
	 * Flushes any given Flushables
065
	 * 
066
	 * @param flushables
067
	 */
068
	private static void flush(Flushable... flushables) {
069
 
070
		if (flushables == null)
071
			return;
072
 
073
		for (Flushable flushable : flushables) {
074
			if (flushable != null)
075
				try {
076
					flushable.flush();
077
				} catch (IOException exception) {
078
					exception.printStackTrace();
079
				}
080
		}
081
	}
082
 
083
	/**
084
	 * Closes any given Closeables
085
	 * 
086
	 * @param closeables
087
	 */
088
	private static void close(Closeable... closeables) {
089
 
090
		if (closeables == null)
091
			return;
092
 
093
		for (Closeable closeable : closeables) {
094
			if (closeable != null)
095
				try {
096
					closeable.close();
097
				} catch (IOException exception) {
098
					exception.printStackTrace();
099
				}
100
		}
101
	}
102
}

Below is a summary of the output of the three possibilities - exception.printStackTrace() prints to std.err, the other two to std.out.

exception.printStackTrace():
java.lang.NullPointerException
at ExceptionToString.main(ExceptionToString.java:16)

——–

exception.toString():
java.lang.NullPointerException

——–

getStringFromException(exception):
java.lang.NullPointerException
at ExceptionToString.main(ExceptionToString.java:16)

By the way: the first line of the stacktrace contains the toString()-result of the Exception.

Happy Coding,

Tino

Share/Save/Bookmark

tino Exception Handling, Java ,

Correct closing of JDBC-resources

March 14th, 2009
After posting about the proper use of Prepared Statements last time, I have another topic today that deals with JDBC: the art of closing your database-ressources in a correct way.

Let’s assume you have a method that uses a Connection to a database, a Statement that executes a query and a ResultSet that holds the result of a query.

I’ll start with some practical examples, how you should not handle your database-resources.

In listing 1 no closing is done at all. That’s a really bad idead, folks!

 Java |  copy code |? 
01
private void badExample() throws SQLException {
02
 
03
		Connection connection = getConnection();
04
		Statement statement = connection.createStatement();
05
 
06
		ResultSet resultSet = statement
07
				.executeQuery("SELECT some crazy stuff FROM table");
08
 
09
		while (resultSet.next())
10
			System.out.println(resultSet.getString(1));
11
	}

The coder of listing 2 remembered the reasons why database-ressources should be closed, but if the statement.executeQuery()-call throws an SQLException, the closing of the resources at the end of the method is ignored.

 Java |  copy code |? 
01
private void badExample() throws SQLException {
02
 
03
		Connection connection = getConnection();
04
		Statement statement = connection.createStatement();
05
 
06
		ResultSet resultSet = statement
07
				.executeQuery("SELECT some crazy stuff FROM table");
08
 
09
		while (resultSet.next())
10
			System.out.println(resultSet.getString(1));
11
 
12
		resultSet.close();
13
		statement.close();
14
		connection.close();
15
	}

Listing 3 shows the correct use of a finally-block. The only thing that had been forgotten: resultSet.close(), statement.close() and connection.close() can throw SQLExceptions themselves!
So the Statement and the Connection remain open, if the resultSet.close()-call throws such an exception.

 Java |  copy code |? 
01
private void badExample() throws SQLException {
02
 
03
		Connection connection = null;
04
		Statement statement = null;
05
		ResultSet resultSet = null;
06
 
07
		try {
08
			connection = getConnection();
09
			statement = connection.createStatement();
10
 
11
			resultSet = statement
12
					.executeQuery("SELECT some crazy stuff FROM table");
13
 
14
			while (resultSet.next())
15
				System.out.println(resultSet.getString(1));
16
 
17
		} finally {
18
			resultSet.close();
19
			statement.close();
20
			connection.close();
21
		}
22
	}

A correct example how resources should be closed can be found in listing 4: the close()-calls are exectued in a finally-block and wrapped itself in a try-catch-clause. Even if the resultSet.close()-call fails, your application tries to close the Statement and the Connection.

 Java |  copy code |? 
01
private void goodExample() throws SQLException {
02
 
03
		Connection connection = null;
04
		Statement statement = null;
05
		ResultSet resultSet = null;
06
 
07
		try {
08
			connection = getConnection();
09
			statement = connection.createStatement();
10
 
11
			resultSet = statement
12
					.executeQuery("SELECT some crazy stuff FROM table");
13
 
14
			while (resultSet.next())
15
				System.out.println(resultSet.getString(1));
16
 
17
		} finally {
18
			try {
19
				resultSet.close();
20
			} catch (SQLException e) {
21
				e.printStackTrace();
22
			}
23
 
24
			try {
25
				statement.close();
26
			} catch (SQLException e) {
27
				e.printStackTrace();
28
			}
29
			try {
30
				connection.close();
31
			} catch (SQLException e) {
32
				e.printStackTrace();
33
			}
34
		}
35
	}

Though the example above is a correct one, it’s very ugly to have all that try-catch-stuff multiple times in your method. Suppose how the finally-block would look like, if you need more than one Connection, multiple Statement-objects and a couple of ResultSets in your method!

Unfortunately the classes mentioned above do not implement a common Closeable-interface with a close()-method. If they would do, a single method would be sufficient, that takes Closeables, checks upon != null and closes the Closeables (wrapped in a try-catch-block, of course). By the way: you can do that with the various InputStream-/OutputStream- and Reader-/Writer-classes.

Because the described Closeable is not available, we have to go a different way: we combine the concept of overloading methods with a feature the Java-guys provided with Java 5: Varargs!

A sample-implementation that uses overloading and varargs is listed below.

 Java |  copy code |? 
01
import java.sql.Connection;
02
import java.sql.ResultSet;
03
import java.sql.SQLException;
04
import java.sql.Statement;
05
 
06
/**
07
 * A class that closes any open database-resources.
08
 * 
09
 * @author Tino for http://www.java-blog.com
10
 * 
11
 */
12
public class JDBCCloser {
13
 
14
	/**
15
	 * Closes the provided ResultSets
16
	 * 
17
	 * @param resultSets
18
	 *            ResultSets that should be closed
19
	 */
20
	public static void close(ResultSet... resultSets) {
21
 
22
		if (resultSets == null)
23
			return;
24
 
25
		for (ResultSet resultSet : resultSets)
26
			if (resultSet != null)
27
				try {
28
					resultSet.close();
29
				} catch (SQLException e) {
30
					/* Do some exception-logging here. */
31
					e.printStackTrace();
32
				}
33
	}
34
 
35
	/**
36
	 * Closes the provided Statements
37
	 * 
38
	 * @param statements
39
	 *            Statements that should be closed
40
	 */
41
	public static void close(Statement... statements) {
42
		/*
43
		 * No need to create methods for PreparedStatement and
44
		 * CallableStatement, because they extend Statement.
45
		 */
46
 
47
		if (statements == null)
48
			return;
49
 
50
		for (Statement statement : statements)
51
			if (statement != null)
52
				try {
53
					statement.close();
54
				} catch (SQLException e) {
55
					/* Do some exception-logging here. */
56
					e.printStackTrace();
57
				}
58
	}
59
 
60
	/**
61
	 * Closes the provided Connections
62
	 * 
63
	 * @param connections
64
	 *            Connections that should be closed
65
	 */
66
	public static void close(Connection... connections) {
67
 
68
		if (connections == null)
69
			return;
70
 
71
		for (Connection connection : connections)
72
			if (connection != null)
73
				try {
74
					connection.close();
75
				} catch (SQLException e) {
76
					/* Do some exception-logging here. */
77
					e.printStackTrace();
78
				}
79
	}
80
}

It can be called very easily like that:

 Java |  copy code |? 
01
private void goodAndElegantExample() throws SQLException {
02
 
03
		Connection connection = null;
04
		Statement statement = null;
05
		ResultSet resultSet = null;
06
 
07
		try {
08
			connection = getConnection();
09
			statement = connection.createStatement();
10
 
11
			resultSet = statement
12
					.executeQuery("SELECT some crazy stuff FROM table");
13
 
14
			while (resultSet.next())
15
				System.out.println(resultSet.getString(1));
16
 
17
		} finally {
18
			JDBCCloser.close(resultSet);
19
			JDBCCloser.close(statement);
20
			JDBCCloser.close(connection);
21
		}
22
	}

Looks much more elegant, doesn’t it?


Why should database-resources be closed after use at all?


  • Closing resources gives chance to the garbage collector to recollect memory as soon as possible. Keep in mind that especially ResultSets may occupy lots of memory depending on your query.

  • If your JDBC-driver uses Connection- or Statement-pooling, non-closed Connections/Statements might not be returned to the pool and are therefore not marked as free. This may cause performance issues.

  • A JDBC application does not only allocate resources in Java, but also on your database-server. So wasting resources affects your Java application as well as the database you’re connecting to.

  • And last but not least from the Java docs : ” It is generally good practice to release resources as soon as you are finished with them to avoid tying up database resources.”

I will end my posts with two additional comments:

  • It’s essential that your resources are closed in the opposite order to that in which you opened them! This means: close ResultSets, then close Statements, then close Connections.

  • It’s a good idead to close the resources on the same layer, where they had been created/occupied. This reduces headaches when some resources are being adressed that should be open (but are closed instead). It also decreases the risk that closing is forgotten completely.

Happy Coding,

Tino

Share/Save/Bookmark

tino JDBC, Java ,