Posted tagged ‘java’

Java-Cron-Jobs with Spring and Quartz

3. Februar 2012

We have several Jobs running the business. At the moment they are implemented as Spring-driven TimerTasks. But the next job should be run only nightly and a cron-like configuration syntax would be fine.

So I found Quartz and had to integrate that. For getting familiar with Quartz+Spring I wrote a small proof of concept.

The job implementation is just a POJO with a public void method. It should not throw any exception. The bean can be configured via usual Spring DI:

public class MyBean {

private String message;

public void doIt() {
System.out.println("Hello World: " + message);
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

}

So fine. But how to test? For this PoC a very simple test is ok – just wait for some Quartz run and check the output manually:

import static org.junit.Assert.assertNotNull;

import org.junit.AfterClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class QuartzTest {

@Test
public void context() {
System.out.println("Starting Spring and within that: Quartz");
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
assertNotNull(ctx);
}

@AfterClass public static void sleep() throws InterruptedException {
System.out.println("Wait for job output");
Thread.sleep(8000);
System.out.println("ready");
}
}

When using Spring, we have to provide the configuration.
First I define my Job-bean

<bean id="myBean">
<property name="message" value="TEST" />
</bean>

After that I configure Quartz:

<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
scope="singleton">
<property name="triggers">
<list>
<!-- trigger list -->
<ref bean="job1" />
</list>
</property>
</bean>

The binding between job and Quartz is done via a configured CronTriggerBean.

<bean id="job1">
<property name="cronExpression" value="0/2 * * * * ?" />
<property name="jobDetail">
<bean>
<property name="name" value="job1" />
<property name="group" value="nightlyJobs" />
<!-- Delegieren auf unsere Bean und unsere Methode -->
<property name="targetObject" ref="myBean" />
<property name="targetMethod" value="doIt" />
<property name="concurrent" value="false" />
</bean>
</property>
</bean>

This CronTriggerBean defines two values:
1. cronExpression specifies when to run the job. An explanation about that syntax can be found at http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger.
2. jobDetail specifies a JavaBean with information about the job. But we dont have to write this Bean, we just can configure the generic one from Spring:
– name and group for controlling the execution via control interfaces
– targetObject and targetMethod for the delegation to our JobBean
– specify if this job should run in concurrent mode (where concurrent means in one VM!)

Building this sample with Maven is easy. You’ll need just following dependencies:

  • org.springframework::spring-core::3.0.5.RELEASE
  • org.springframework::spring-context::3.0.5.RELEASE
  • org.springframework::spring-context-support::3.0.5.RELEASE
  • org.springframework::spring-tx::3.0.5.RELEASE
  • org.quartz-scheduler::quartz::1.8.5
  • junit::junit::4.9::{scope=test}

As far as I read you can’t use Quartz 2.x because Spring 3 doesnt support that. But I havent tried it.

When running you’ll get this output:

Starting Spring and within that: Quartz
... logs from Spring
... infos from SLF4J
INFO: Starting Quartz Scheduler now
Wait for job output
Hello World: TEST
Hello World: TEST
Hello World: TEST
Hello World: TEST
Hello World: TEST
ready
Advertisements

Links for 2010-11-08

8. November 2010

TecChannel had a (German) article about one of my favorite tools: Launchy – a program for starting applications or opening web pages …

 

If you are a PHP programmer and interested in CakePHP, CakeFest was a conference for you. Not attended? There are slides online:

And according to Entwickler.COM the conference should be held in 2011 too…

 

If you are a Java programmer unit tests are a standard. Therefore mocking is also a discipline you know. If you are interested in the mock library Mockito, the DZone article „5 minute Mockito“ is worth reading.

 

 

Links for 2009-10-30

30. Oktober 2009

77 Windows 7-Tips by Jeffrey Hick, Don Jones, Pav Cherny, J. Peter Bruzzese and Bill Boswell.

Webcast zur Windows Power Shell 2.0 by Holger Schwichtenberg. In this first of three episodes he talks about Commandlets, Pipelining, direct use of .NET- and WMI-Classes and remote access.

Java: If you want to have the diff between two lists (Arrays.asList(„a“, „b“, „c“) vs. Arrays.asList(„a“, „c“, „d“)), then you should have a look at this blog entry.

Microsoft Press publishes a new eBook „Deploying Windows 7“ for free. It is an introduction by the authors from Windows 7 Resource Kit and TechNet Magazine.

🙂 If you are interested in Darth Vaders daily routine … here are some pictures.

DE: Webcast: NET for JEE-Developer – In this first of six episodes Golo Roden shows „From Java to C#“

With „Mastering PowerShell“ there is another free eBook available. Content: The PowerShell Console, Interaktive PowerShell, Varables, Arrays and Hashtables, The PowerShell Pipeline.

Links for 2009-04-06

6. April 2009

In Novells Wiki there is a nice code sample which tries to read all available security features from the request (Client Certificates, Encoding type, Cipher Suite, …)

Getting the Type of a generic class at runtime

10. Oktober 2008

How should I get the type of a parametrized class? … mmh … let me explain what mean:

import java.util.ArrayList;

public class Generic<T> {
  @Override
  public String toString() {
    return "Type Parameter is unknown.";
  }

  public static void main(String[] args) {
    System.out.println(new Generic<String>());
    System.out.println(new Generic<Integer>());
    System.out.println(new Generic<ArrayList>());
  }
}

and the output is (as expected)

Type Parameter is unknown.
Type Parameter is unknown.
Type Parameter is unknown.

But I want to have

Type Parameter is java.lang.String.
Type Parameter is java.lang.Integer.
Type Parameter is java.util.ArrayList.

The problem is that the „type erasure“ erased exactly that information. But the compiler does something with that information. Otherwise – why having that? Ok, I dont know any reflection API or getter for that. (As I said: type erasure). But maybe I can write a workaround …

Ok, what about having a member variable of type T and asking for its type?

public class Generic<T> {
  T type;

  public Class getGenericType() {
    return type.getClass();
  }

  @Override
  public String toString() {
    return "Type Parameter  is " + getGenericType().getName() + ".";
  }
}

The main-method is unchanged. But in that case I get a NullPointerException because the field is not initialized. But how to do that? Ok, no idea … but maybe I can now ask the reflection API …

Getting the field is easy

Field field = this.getClass().getField("type");</code>

but with the field I cant do any meaningful 😦

System.out.println(field.getGenericType()); // T
System.out.println(field.getType()); // class java.lang.Object
System.out.println(field.getDeclaringClass()); // class MyGeneric

Sadly type erasure hit me again, so field.getType() returns the class which can catch all possibilities: java.lang.Object. If I change the type parameter from Generic to Generic (just for the String-invocation in main()) I’ll get java.lang.CharSequence. In that case the global superclass Object isnt required any more.

But the result: I dont know how to get the type parameter … Maybe I should investigate in initializing the field and asking the real object for its type.

Links for 2008-10-06

6. Oktober 2008

Five tips for better developing PHP applications: use MVC framework, use AJAX library, use IDE, use DB management software, use an O2R mapper. With more details in that blog.

Core Java Refcard Available

Long time ago …

19. Juni 2008

My last commit to Args4J was long time ago. But I was happy, that my environment works – and also my knowledge about the project itself 😉 And the pause was fine because I startet a new try to implement the setting of Map-entries …. with success. Now you can have a bean with

@Option(name="-map") java.util.Map map;

and set the values from command line via

java MyApp -map key1=value1 -map key2=value2