2013-03-30

UUID Values From JDBC to Postgres

I'm a big fan of UUIDs in general and especially for database record identifiers. If using a modern database such as Postgres that natively understands and stores the 128-bit value of a UUID, then you gain many benefits with the main cost being the double or quadruple storage space of the otherwise common 32-bit or 64-bit serial integer number.

Unfortunately, neither the SQL standard nor JDBC has seen fit to recognize UUIDs as a data type. So that means a second cost to using UUIDs in a database: Dragging those UUID values across the chasm of JDBC + SQL. One one end, we have Java which understands UUID as a built-in class (java.util.UUID). That's good. On the other end, we have Postgres which understands UUID as a native data type. That's good. The problem is in between.

The solution is that JDBC has a trap-door to handle data types unknown to SQL, called simply object. Let's look at an example, a snippet of Java code.

// Generate or obtain data to store in database.
java.util.UUID uuid = java.util.UUID.randomUUID(); // Generate a random UUID. 
String foodName = "Croissant";
// JDBC Prepared Statement.
PreparedStatement preparedStatement = conn.prepareStatement( "INSERT INTO food_ (pkey_, food_name_  ) VALUES (?,?)" );
int nthPlaceholder = 1; // 1-based counting (not an index).
preparedStatement.setObject( nthPlaceholder++, uuid ); 
preparedStatement.setString( nthPlaceholder++, foodName ); 
// Execute SQL.
if ( !( preparedStatement.executeUpdate() == 1 ) ) { 
  // If the SQL reports other than one row inserted…
  this.logger.error( "Failed to insert row into database." );
}

This code is simpler than you might expect. No need to transform the UUID as textual hex representation on the Java side. No need to cast the value on the Postgres side. By calling the ".setObject" method, and passing an actual UUID value, it all works.

Going the other direction, retrieving a UUID value from the database, call the getObject method and cast the result to a java.util.UUID object. Like so, where `rs` is a ResultSet:

java.util.UUID uuid = ( java.util.UUID ) rs.getObject( "uuid_" );

By the way, if you need to pass an empty or 'nil' value for a UUID, generate a UUID with all bits of all zero values. This is commonly understood to mean "no value" in UUID-speak. One way to generate such a UUID is:

java.util.UUID emptyUuid = new java.util.UUID( 0L, 0L );

2013-03-28

Using SLF4J With Tomcat

A few days ago I posted about using getting started with SLF4J, the logging façade framework for Java.

Well, I ran into a surprise using SLF4J with the SimpleLogger implementation while developing a web app in the Eclipse IDE for Java EE Developers edition of Eclipse Juno using an external copy of Apache Tomcat 7.0.39. As my previous post documented, you can configure settings for SimpleLogger by programmatically setting Java System properties.

That works – the first time you run. I found on successive runs that my settings were being ignored. I suspect the System properties are being restored to default thereby wiping out the values I set programmatically since I was not persisting my values. I don't know exactly what is happening. But I'm guessing that because Eclipse is eager to do incremental compiles, and Tomcat is eager to redeploy the changed web app, somewhere in there the System properties in memory are being cleared and reset to the persisted defaults. If so, this would be a feature, not a bug.

I did find a solution to the problem of configuring SimpleLogger for use inside the whirlwind that is Eclipse+Tomcat. The SimpleLogger API doc page mentions that it checks for a class loader resource named simplelogger.properties. Translated to English, that means creating a text file with a few key-value pairs, and placing that file in an appropriate folder to be noticed by Eclipse+Tomcat at runtime.

First, the file.

The .properties format is super simple, defined by the Java platform. Read about it in this Wikipedia page. Start with a plain text file, but in Latin-1 (ISO-8859-1) character encoding rather than the more modern UTF-8 encoding. For our purposes with SimpleLogger, Latin-1 in convenient. But for other purposes, you may want to explore the alternative .properties format using XML and therefore using UTF-8.

Put some comments at the top, each line starting with a hash mark (#). After that, add a key-value pair on each line of text. Unlike Java code, no end-of-line marker is needed. The key-value pair is delimited by your choice of an Equals sign (=), Colon (:), or a Space character. Accordingly, if either your key or value text contains one of those three characters, you must escape such occurrences by a preceding backslash. Notice the escaping in the last line of my example below, for the colons that appear in the time format.

Second, the location.

This page in Tomcat doc explains the complexities of class loaders in Tomcat due to the nature of web servers and servlet containers. Assuming that you, like me, want to keep your settings close to your web app rather than in a global Tomcat-wide scope, then practically that leaves a single location in which to place your properties text file: Your web app folder > WEB-INF > classes folder. In Unix-speak:
/WEB-INF/classes of your web application

In the Eclipse Project Explorer pane, you probably will find a WebContent folder nest inside your project. Expand that to find META-INF and WEB-INF folders. Expand WEB–INF to find the classes folder. If classes folder does not exist, create it.

Third, an example.

Here's an example from my work.

# Settings for the slf4j logging API implementation "SimpleLogger".
# http://www.slf4j.org/apidocs/org/slf4j/impl/SimpleLogger.html
# http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
# http://en.wikipedia.org/wiki/.properties

# By Basil Bourque. 2013-03.
# This example is provided without warranty or guarantee to anyone taking full responsibility for its use.

# Override default of outputting to System.err. Use System.out instead.

# Eclipse (Juno and earlier) has a known bug where System.out & System.err are incorrectly interleaved (out of order). So use one or the other, but not both.
org.slf4j.simpleLogger.logFile=System.out
# Override default of tracking only 'info' and higher. Track all levels of messages.
org.slf4j.simpleLogger.defaultLogLevel=trace
# Drop the package name from the class calling to the logger.
org.slf4j.simpleLogger.showShortLogName=true
# Log the datetime rather than the number of milliseconds into the run of the app.
org.slf4j.simpleLogger.showDateTime=true
# Format the datetime in ISO 8601 format. Escape the colons by prefixing with a backslash.
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd'T'HH\:mm\:ss.SZ


I would rather see that datetime as Zulu time (UTC time zone), but I can't seem to find the correct format for that. Please comment if you have a solution to that.

For deployment, you will almost certainly want to replace the SimpleLogger implementation with something more robust or flexible such as Logback. But for a quick set up in a new project to use during development, SimpleLogger is handy. Also, there is a plugin for Eclipse for reading logs, called Logback-beagle, but I've not yet tried it.

2013-03-24

Drano for Eclipse

There are at least four ways Eclipse's complicated plumbing gets stopped up.

For any kind of app, the compile and build feature can get messed up because of the incremental compile feature and other glitches that can result in your programming changes effectively being ignored while previous versions of classes continue to be used in your test runs. Drano: Select the project (highest folder) in the Project Explorer, and choose Project > Clean.

For apps using Apache Ivy to manage Maven to manage dependencies to include libraries in your project, Ivy can get confused causing failures in downloading fresh copies of needed libraries. Drano: I'm not quite sure of the correct menu item, but I believe on the context menu that appears when you click the project (highest folder) in the Project Explorer, you can choose Ivy > Clean All Caches.

When building web apps in the edition Eclipse Java EE IDE for Web Developers, a couple more pipes can easily become clogged. When configured with an external copy of Apache Tomcat, Eclipse does not actually run your app inside the folder of that Tomcat. Instead, Eclipse creates a hidden folder, nesting there the necessary folders in which to write your servlets, caches, logs, and other such files when debugging your web app. Those files can get out of whack, such as failing to update the servlets or related libraries. Drano: On the context menu that appears when clicking the server configuration listed in the Servers pane, choose Clean. Remember to stop the server first (click the red square icon).

Yet another problem with web apps is the built-in web browser using its cache rather than refreshing a page. Or the web browser may store cookies that need to be deleted for fresh testing. How does one clear Eclipse's internal web browser's cookies & cache? I don't know yet. Perhaps someone will answer my StackOverflow.com question.

2013-03-22

Getting Started With SLF4J (Java Logging Façade)

SLF4J is a next-generation logging façade API for Java. SLF4J supplants the older Apache Commons Logging.

You write your code to call SLF4J’s logging commands. Those commands are actually just an empty interface. You plug in a particular logging framework to actually record messages. You can plug in an adapter to work with Java's built-in but limited logging facility. Or you can plug in an adapter to add an insulating layer to the venerable but aging log4j already in use by your projects. Or for a greenfield project, drop in Logback to do your logging. Logback is the successor to log4j, created by the same man.

Alternatively, just to get started, you can use the SimpleLogger implementation of the SLF4J API. SimpleLogger simply dumps messages to the Standard Error console (stderr or System.err in Java terms) console. This is handy during development. Later you can drop in a more serious logging framework such as Logback. Those other framework may require more configuration, coordination with your sysadmins, so you may want to defer that until later.

SimpleLogger has a few options. You may tweak those merely by setting Java System Properties. I like to switch SimpleLogger from using System.err to System.out because Eclipse has a known nasty bug where lines from those two streams can be improperly mixed on console pane with lines appearing out of order. I also tell SimpleLogger to show me all levels of messages rather than ignoring the lower-level ones. Lastly I add the datetime and shorten the class name to hide the package name.

Here's my code called at the launch of my app, or for web apps, the initialization of the servlet.

// Logging
// 5 levels: "trace", "debug", "info", "warn", or "error".
// For now, we use the "SimpleLogger" implementation.
// But let's tweak "Simple" to use System.out rather than System.err because Eclipse has a bug interleaving the two
// out of order.
// And let's override "Simple" default of ignoring lower-level messages to track all levels of messages.
// We communicate with "Simple" via System Property settings (key-value pairs).
// Doc: http://www.slf4j.org/api/org/slf4j/impl/SimpleLogger.html
System.setProperty( "org.slf4j.simpleLogger.logFile", "System.out" );
System.setProperty( "org.slf4j.simpleLogger.defaultLogLevel", "trace" );
System.setProperty( "org.slf4j.simpleLogger.showShortLogName", "true" );
System.setProperty( "org.slf4j.simpleLogger.showDateTime", "true" );
SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SZ" );
System.setProperty( "org.slf4j.simpleLogger.dateTimeFormat", simpleDateFormat.toPattern() );

// Above is the setup needed to run at the beginning of your app.
// Next two lines are what you use in the various classes to actually do logging.
this.logger = LoggerFactory.getLogger( this.getClass() );
logger.info( "Hello World from slf4j." );




2013-03-21

Different Tools, Same Job

Sometimes I just have to laugh when programmers and IT folk engage in silly debates about tools and techniques. Perhaps computer geeks can learn something from musicians and artists…

About the song

Alphabet St. | Prince

Alphabet St. | Sufjan Stevens

Alphabet St. | Erik Ostrom

Alphabet St. | The Jesus & Mary Chain

Alphabet St. | Steve Cann

Alphabet St. | Purple Yoda

2013-03-18

Crucial Tips for Tomcat in Eclipse

This one post in Fruzenshtein's notes blog could have saved me many hours of futzing with Tomcat in Eclipse. I highly recommend anyone new to Vaadin read that article.

2013-03-12

Java Serialization Articles

Some articles I found useful when studying Java Serialization.

Serialization is the process of "dehydrating" an object's state (fields of data) and its meta-data (its Class, super-classes, number and data type of its fields, and so on). This information is written into a file or other stream of octets. The format of those octets is a part of the Java standard, the same across various host platforms. Later, a serialized Java object may be "rehydrated" into an instance in memory in the same Java Virtual Machine or any other JVM.

Serialization (Wikipedia)
For those new to the concept.

5 things you didn't know about ... Java Object Serialization
By Ted Neward.

Official spec for Java 7 Serialization

Top 10 Java Serialization Interview Questions

Testing object serialization
by Elliotte Rusty Harold

2013-03-03

Another Font for Programmers: Adobe "Source Code Pro"

Source Code Pro by Adobe is a new (2012) free-of-cost and open-source monospace font designed for programming use.



Designed for programmers means, among other things, similar characters are made distinct. Indeed, I read about this string that makes a cute example of three such similar characters:
1 illinois
 Read more about this new font in this Adobe blog by Paul D. Hunt.

The reigning king of programmers' fonts is still Pragmata. But it is nevertheless nice to have another choice alongside Apple Menlo, DejaVu Mono (the mother of Menlo), Microsoft Consolas, and Ubuntu Monospace.

By the way, this font is a follow-up to another open-source font from Adobe, Source Sans Pro discussed in this announcement. Adobe hosts these and other open source projects at SourceForge.