Friday, January 14, 2011

et tu log4j? java.lang.classnotfoundexception: org.apache.log4j.enhancedpatternlayout

While I was setting log4j for our new project I got the following exception:

1log4j:ERROR Could not instantiate class [org.apache.log4j.EnhancedPatternLayout].
2java.lang.ClassNotFoundException: org.apache.log4j.EnhancedPatternLayout


I have log4j in my pom and its jar in my local repository so why EnhancedPatternLayout is missing?
This class is not in our log4j but in log4j-extras. You have to add the necessary extras jar to your pom.

1<dependency>
2    <groupid>log4j</groupid>
3    <artifactid>apache-log4j-extras</artifactid>
4    <version>1.0</version>
5</dependency>


I added the version 1.0 because version 1.1 requires log4j 1.2.16 while I'm using log4j 1.2.15.

classcastexception while working with quartz + spring

I was trying to integrate Quartz to Spring and while everything seemed OK I got the following exception:

1java.lang.ClassCastException: org.quartz.impl.StdScheduler


I had everything in hand for the simple job I implemented to work.

A simple Job class that implements QuartzJobBean:

1public class Job extends QuartzJobBean{
2 
3    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
4        System.out.println("working!");
5    }
6}


The necessary spring context:

01<!-- A JobDetailBean with property as my Job-->
02 
03 <bean name="exampleJob" class="org.springframework.scheduling.quartz.JobDetailBean">
04        <property name="jobClass" value="job.Job">
05    </property></bean>
06 
07<!--A trigger with JobDetail and other necessary properties-->
08 
09    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
10        <!-- see the example of method invoking job above -->
11        <property name="jobDetail" ref="exampleJob">
12        <!-- 10 seconds -->
13        <property name="startDelay" value="10000">
14        <!-- repeat every 50 seconds -->
15        <property name="repeatInterval" value="50000">
16    </property></property></property></bean>
17 
18<!--And a Scheduler for working with triggers (and corresponding jobdetails)-->
19 
20    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
21        <property name="autoStartup" value="false">
22        <property name="triggers">
23            <list>
24                <ref bean="simpleTrigger">
25            </ref></list>
26        </property>
27    </property></bean>


All I had to do is instantiate the bean with getBean() but I was getting "java.lang.ClassCastException: org.quartz.impl.StdScheduler" everytime. My code for instantiating the SchedulerFactoryBean was below:

1SchedulerFactoryBean d = (SchedulerFactoryBean) appCon.getBean("scheduler");


I was trying to downcast to a wrong class. It seemed quite straightforward to use SchedulerFactoryBean but it was wrong. As the exception said I changed it to StdScheduler (of Quartz) and I fixed it.
Here's the correct form:

1StdScheduler d = (StdScheduler) appCon.getBean("scheduler");


I hope that easy solution will be helpful for somebody out there.

Tuesday, January 11, 2011

datetime fun with mysql: when do i lost my time?

In our project, we chose the data type of a column as datetime in MySQL. We built models that are in line with our tables. For the datetime attribute in the database I chose to use the Date object in Java model and the show begun.

When I tried to use my model's Date attribute for setting the corresponding field (with setDate()) on the prepared statement I saw that the object types dont match. What I have in the model is java.util.Date while the prepared statement asks for java.sql.Date. Ok then I'll convert it. I googled a bit and found a solution, or rather thought that I found a solution.

1ps.setDate(1, new java.sql.Date(model.getDateField().getTime()) )


First I was converting to a millisecond unix timestamp with getTime() and then converting it to second (by dividing with 1000) and then wrapping the result into a java.sql.Date object.
The result was far from satisfying. The time part of the date (hour, minute and second) were missing in the result. The date in the model was '2010-10-26 14:13:33' and the result in the database was '2010-10-26 00:00:00'.

After that I googled a bit more and inspected few javadocs then came up with not one but two solutions.

1SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2ps.setString(1, dateFormat.format( model.getDateField() ));

The first solution creates a SimpleDateFormat object which formats the Date attribute of the model as a String and we use setString() of the prepared statement for setting it.

The second solution is below.

1ps.setTimestamp(1, new java.sql.Timestamp(model.getDateField().getTime()));


We first get the Date attribute and then convert it to unix timestamp in milliseconds for wrapping it into a Timestamp object and call the related setter.

I didn't notice major performance difference in one of the solutions I offer which means that you have to test it in your cases.