The Logging Mess

Every application needs logging. And right now there are a lot of options on what exactly to use for logging in Java. The most famous frameworks are: log4j, logback, commons-logging, slf4j, java.util.logging. And there are a lot more – every now and then someone decides to write his own logger – just go to the Open Type dialog of your IDE and type “Logger” (not to mention that some use the name “Log”). And there’s also the ServletContext.log(..) and stuff like that. It is indeed a mess. But let’s start with some history (note: here’s another post on the topic) . First there was System.out and System.err. But they were inflexible, so a need for a feature-rich logging has arisen (note that I was in elementary school at that time). Logging that can be customized format, that can go to multiple targets – files, consoles, emails, etc. So log4j has appeared – in 1999. But other solutions spawned as well, including java.util.logging – an attempt to have standard JDK logging. Note a very successful attempt, as it turned out. java.util.logging appeared with JDK 1.4 in the beginning of 2002. A few months later the realized need for a common logging interface for all existing loggers resulted in apache common-logging. The idea of commons-logging was viable – libraries should not force a particular logging implementation on applications that use them. So each logging implementation gets adapted to a common API which is used by the library – so a library does not use org.apache.log4j.Logger – it uses org.apache.commons.logging.Log, and it delegates to whatever logging framework exists on the classpath. That...

How to map dates with hibernate – use joda-time

This is always a question – how to map temporal data in our hibernate entities – whether to use java.util.Date, java.util.Calendar or simply long. The correct answer is: neither of these. Use joda-time – the de-facto Java datetime API. Using it throughout the whole project is a no-brainer, but how to use it with hibernate – you can’t use @Temporal. Hibernate supports custom types, so there’s a little project that solves the issue – joda-time – hibernate support. The user guide is pretty clear: @Column @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime") private DateTime fromDate; However, there’s one issue with that library – it uses static final fields from hibernate, which requires recompilation if the version of hibernate changes (see here). For that reason you may need to extend the PersistentDateTime class, override the 2 methods that use the static final TIMESTAMP field, and copy the exact same code from the superclass. Using joda-time throughout the whole project will save tons of headaches. So I strongly suggest the above mechanism to use joda-time in your hibernate entities as well. This is always a question – how to map temporal data in our hibernate entities – whether to use java.util.Date, java.util.Calendar or simply long. The correct answer is: neither of these. Use joda-time – the de-facto Java datetime API. Using it throughout the whole project is a no-brainer, but how to use it with hibernate – you can’t use @Temporal. Hibernate supports custom types, so there’s a little project that solves the issue – joda-time – hibernate support. The user guide is pretty clear: @Column @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime") private DateTime fromDate; However, there’s one issue with that library...

Google App Engine and Maven

I created a small project that I wanted to host somewhere for free. Amazon free tier or Google App Engine? I already have experience with AWS, so I decided to try GAE. It is completely different, of course. And it didn’t start quite well, with some NullPointerExceptions from the eclipse plugin. But ultimately, it worked fine. However, I was a bit confused how to use Maven in a GAE project. By default, everything should go to the /war directory, and that’s not maven’s directory structure. And this post scared me even more – the pom.xml looks appalling. What I ultimately achieved is workable, and the pom remains simple. mavenzie your project (m2eclipse). Update project configuration to have everything in place In right click > Properties > Google > Web applications have the path pointing to “target/project-0.0.1-SNAPSHOT” (or whatever your assembly folder is), and uncheck the “launch and deploy from this directory”. Move everything from “war” to “src/main/webapp”. Parhaps without the jars, which you can add as maven dependencies run maven > package, so that the target directory is populated Right click > Deploy to Google App Engine – it will ask you for a directory the first time – choose “…/target/project-0.0.1-SNAPSHOT” again (this is absolute path). It will remember this decision, but don’t commit the .settings/com.google.gdt.eclipse.core.prefs, because it now contains an absolute path That way everything works fine. Before each deploy you should make a maven build, but that’s not that bad (well, generally speaking, it is bad, but you don’t have hot-deploy here anyway. And my build is really quick. If I had a huge project with a...

How to Handle Project Configuration

Every web project needs some environment-specific configurations. Database credentials, root url, smtp settings, to name a few. It’s a recurring question on stackoverflow, and I’ve seen a lot of variations on the topic, and here I’ll describe the one that I think is best. put all such properties in a .properties file (for example application.properties) have that application.properties sitting outside the web application. It is not bundled with the build provide a command-line option that indicates where that file is located. For example -Dconfig.location=/home/you/config on application startup (in a ServletContextListener usually) load the file and put it in a map. Can be java.util.Properties or a HashMap for spring users – use <context:property-placeholder-configurer location="file://${config.location}/application.properties" . Other frameworks will likely have some mechanism for loading such global properties hold a skeleton properties file in the SCM repository. It should contain all properties, but their values are irrelevant – they will change on each environment the ops team is likely to benefit from versioning different environment configurations (production, qa, stage), so a separate /config folder/subproject can be created and all environment-specific properties can be stored there. When adding a property developers should go and update all files accordingly properties that are not dependent on the environment, but are still global for the project, can be stored within the project (src/main/resources for maven), and committed to SCM. They can be merged with the external properties on startup (merged in memory, that is) most of the externalizable properties can have reasonable defaults – the smtp server of the company, the database driver, etc. They can be placed in a application-defeault.properties within the project, and...

What to Do With IDE Project Files

Each IDE generates its specific project/config/build files. Eclipse generates .project and .classpath, and also the .settings directory. IntelliJ IDEA has its .iml files. And it is always a question what to do with these files in terms of source control management (SVN, CVS, git, etc) The generally accepted practice is to add them to the SCM ignore list (svn:ignore for example). Why? the project does not become aware of the IDE it is developed in. Each team member can use an IDE of their choice there is no danger of sneaking absolute path configurations into the repository no developer can override the local settings of other developers This practice makes sense, but it has one major drawback – the complexity of setting up a project has to be repeated every time. In other words, you can’t start developing immediately after you checkout – you have to configure tons of things – deployment on local server, checkstyle configurations, plugin configurations, etc. Joel Spolsky insists on having a one-step build. Using a build tool instead of the IDE build process is preferable (ant, maven). But in addition to that you should also have a one-step development environment setup (apart from installing a database/search engine/etc.). So how to do that? I know this is an unpopular advice but: commit the IDE project files in the repository. Once a member has a successful local setup, the files should be committed so that everyone else can just checkout/update, and get the project running. I’m sure everyone has gone through the trouble of helping set up the project for new team members, or when getting...