Category Archives: Foundations

Scheduling Tasks/Jobs with Spring (Boot)

Static Scheduling

Spring offers the annotation @Scheduled to define a task and its corresponding scheduling, e.g., execute this method every 5 minutes. The annotation saves you a great deal of work: in the background, it creates or looks up a scheduler, creates a task which invokes your method, and passes the task to the scheduler with your scheduling arguments (here: every 5 minutes).

Scheduling Parameters

The annotation @Scheduled allows to specify a fixed delay (in ms), a fixed rate (in ms), or a more flexible cron expression if the first two options are not expressive enough for your use case. The following code snippet shows an implementation of our “every 5 seconds”-example from above:

@Component // or any subtype like @Service
public class AnyComponent {

    private static final Logger log = LoggerFactory.getLogger(AnyComponent.class);

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() { // visibility is irrelevant: even private is possible
        log.info("The time is now {}", dateFormat.format(new Date()));
    }
}
Task Method Requirements

The method, which is annotated with @Scheduled, must fulfill the following requirements:

  • The enclosing class of the method must be a Spring component. That is, the class must be annotated with the annotation @Component or an annotation which includes @Component like @Service, for example.
  • The method must be void.
  • The method must have no parameters.
  • The method may be private.
Read Parameter Values from a Properties File

If you do not want to specify the delay or the rate directly in the code, you can read it from the configuration context. For this purpose, Spring provides the parameters fixedDelayString and fixedRateString. The following example reads the seconds of the delay from the configuration key my.property.fixed.delay.seconds. If the value is not available or invalid, a default value of 60 is used. Since the delay expects a value in milliseconds, 000 is appended to the read value.

// with a default value of 60
@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds:60}000")

Further examples:

// without a default value
@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds}000")
// without appending
@Scheduled(fixedDelayString = "${my.property.fixed.delay.milliseconds}")
// hard-coded value as string (not recommended due to missing static type checking)
@Scheduled(fixedDelayString = "7000")

With these *String variants, you can define the delay or, respectively, the rate from aproperties file. Note that the value is read only once at startup time. Thus, this approach is still static. You cannot change the value at runtime. We refer to the Javadoc of @Scheduled for more detailed information on the parameters.

Dynamic Scheduling

If you need to read your scheduling arguments dynamically, that is, at runtime, then you @Scheduled is not sufficient. Instead, your can use Spring’s interface TaskScheduler. Declare a field with this type and annotate it with Spring’s @Autowired annotation. Then, you can pass a dynamically created task to the scheduler and specify whether it should be executed once or repeatable with a fixed delay or at a fixed rate. We refer to the documentation of the TaskScheduler for more information.

Sources

Join Points and their Pointcuts in AspectJ

In the following list, we name each join point with its corresponding pointcut because it was initially not apparent to me how to capsure all calls (or executions). You cannot use one single * wildcard to match all method and constructor calls. You need to define a composite pointcut which capsures on the one hand all method calls and on the other hand all constructor calls. This differentiation by AspectJ is not directly reflected by the documentation, but only by AspectJ’s different pattern syntax for call (or execution). To capsure method calls, you need to use MethodPattern. To capsure constructor calls, you need to use ConstructorPattern. The complete syntax for all patterns of AspectJ can be found here.

  • method-calls: call(MethodPattern)
  • method-execution: execution(MethodPattern)
  • ctor-calls: call(ConstructorPattern)
  • ctor-execution: execution(ConstructorPattern)
  • static init: staticinitialization(TypePattern)
  • preinit: preinitialization(ConstructorPattern)
  • init: initialization(ConstructorPattern)
  • field-reference (a.k.a. field-read): get(FieldPattern)
  • field-set (a.k.a. field-write): set(FieldPattern)
  • handler: handler(TypePattern)
  • advice-execution: adviceexecution()

Aspect-oriented Programming with AspectJ

AspectJ is an open-source framework that allows you to write Java code following the aspect-oriented programming (AOP) paradigm. AOP provides an alternative way of programming in the following situation:

Let us assume you want to implement some functionality which is required at multiple locations in your application’s source code. If we follow the object-oriented programming (OOP) paradigm, we would proceed as follows. First, we declare a new class. Then, within this class, we declare a new method which implements the required functionality. If necessary, we add some associated fields. Afterwards, we place an invocation of the method (together with the class instantiation) at each of the required locations in our source code.

If we follow the AOP paradigm, we would proceed as follows. First, we declare a new aspect which is similar to a class. Then, within this aspect, we declare a new advice which corresponds to the method from above. If necessary, we add some associated fields to the aspect. So far, we have proceeded exactly as if we had followed the OOP paradigm – only with different terms. But now, we do not place an invocation of the advice at each of the required locations. Instead, we write down these locations in our aspect and pass it to an additional compiler – the AOP compiler. This AOP compiler reads in the aspect and automatically places an invocation of the advice at each of the designated locations. Thereby, it also handles the instantiation of the aspect. The set of our locations is called a pointcut and is associated with our advice. In this way, the AOP compiler knows which code it should place at which locations. However, most AOP compilers cannot insert advices at arbitrary locations, but only at well-defined locations. For example, the AspectJ compiler can insert advices at method calls and field accesses, but not at loops or if-statements. Such well-defined locations are called joinpoints. Thus, a pointcut is not a set of arbitrary locations, but a set of joinpoints.

Hence, an aspect is not instantiated and accessed directly from within your source code. Instead, it is automatically inserted into your source code by the AOP compiler. For this reason, we do not term it class, but aspect. In summary, the AOP paradigm allows to insert some functionality at multiple locations in your application without the effort of touching the source code at each individual location by hand. In this way, it provides a clean modularization of crosscutting concerns and thus serves as a complement to the OOP paradigm.

AOP terms in short:

  • A jointpoint is a location in code at which the AOP compiler is able to automatically insert new code either before, after, or around (i.e., before and after). Valid joinpoints in AspectJ are, for example, method declarations, method calls, and field read/write accesses. So far, AspectJ does not support inserting code at loops and if-statements. So, AspectJ does not consider these constructs as joinpoints.
  • A pointcut is a set of joinpoints at which we want to insert the same new code. This set of joinpoints is not described as an enumeration of each and every individual joinpoint, but instead as a single compact expression similar to a regular expression.
  • An advice contains the new code which we want to insert at multiple joinpoints in our application’s source code.
  • An aspect contains one or more advices and their associated pointcuts. By default, AspectJ creates and uses one instance per aspect. So, you can consider an aspect as singleton. However, you can change this behavior to a per-object or per-joinpoint base (see aspect instantiation for more details).

For more information, we refer to the official Getting Started and the mapping of join points and pointcuts.

What is a UML Software Component?

Introduction

Since I work at the Kiel University, I teach UML to the students in the 3rd and 4th semester of computer science. At the latest when they need to work out a UML component diagram and a corresponding deployment diagram, the following questions arise:

What is a UML software component? What is the difference between a class, a package, and a component?

For this reason, we address these questions in this post. First, we look at some definitions to distinguish a component from other UML entites.

Component vs. (Class, Package, and Library)

Let’s start with the most important message of this post: Consider a component as a composition of classes, packages, and sub components that is accessible only by other components and only via interfaces.

TODO

Communication within and between components

TODO UML notation

Example Component Diagram

When creating a component diagram, remember that it must depict additional semantics compared to all other diagram types such as class and package diagrams. Otherwise a component diagram is useless and can be thrown away.

TODO diagram with components (android, server, db) and sub components: A3, User, Role, ORM, …

Example Component Representations in Java

Since the Java programming language does not provide the abstraction of components, we need to represent it with the means Java offers us.
Hence, we discuss the three following representations of a component possible in the Java universe.

  1. The class-based approach
  2. The package-based approach
  3. The library-based approach

Due to Java’s direct support for interfaces, we represent a component’s interface by one or more Java interfaces.

The class-based approach

In this approach, we represent a component by a class that implements all interfaces the corresponding component should provide.

 

The package-based approach

TODO

The library-based approach

TODO