Thursday, January 23, 2014

Usage trends of JavaScript MVC Frameworks

Analysis

JavaScript MVC frameworks became very popular during the last 5 years. Naturally there are a lot of such frameworks. I spent most of my time as a developer at server side, so I am not very familiar with those framework but want to learn them. But where to start? I do not want to spend time on framework that will be obsolete in a year because I do not want to look like people that start learning J2ME, applet programming, Log4J API and configuration or start new project with Ant and CVS these days.

So, I googled "JavaScript MVC framewors" and found the following articles:

I know that it the list is not full but if it is good enough for authors it is good enough for me :).
Then I wanted to check whether these libraries are good for other people using google trends. Unfortunately Google trends does not allow to compare more than 5 search targets, so I splitted the list into groups and then compared the best libraries from the first round. 

Here are links to the results.

Semi final


Final




According to this graph AngularJS wins.

Conclusions

It seems that AngularJS is the most popular JS MVC framework now and its popularity is growing very fast, so I am going to learn it. 

Thursday, July 11, 2013

Performance of checking computer clock

Very often we check computer clock using either System.currentTimeMillis() or System.nanoTime(). Often we call these methods to check how long certain part of our program runs to improve performance. But how much does the call of mentioned methods cost? Or by other words

How long does it take to ask "What time is it now?"

I asked myself this question and wrote the following program.

public static void main(String[] args) {
long tmp = System.nanoTime();
long before = System.nanoTime();
for (int i = 0; i < 1000_000_000; i++) {
// do the call
}

long after = System.nanoTime();
System.out.println((after - before) / 1000_000);
}

Then I replaced the comment "do the call" with interesting code fragments and measured the time. Here are my results.

Code Elapsed time, ms
nothing 5
call of foo() {return 0;} 5
f+=f 320
call of foo() {return f+=f;} where f is a class level static variable initiated to System.nanoTime() 325
call of System.nanoTime() 19569
call of System.currenTimeMillis() 22639

This means that:

  1. method that just returns constant is not executed at all. Call of method that returns 0 takes exactly the same time as doing nothing.
  2. call of method itself does not take time. Execution of f+=f and call of method that does the same take exactly the same time. We have to say "thanks" to JVM that optimizes code at runtime and  uses JIT.
  3. Call of currentTimeMillis() is about 10% heavier than nanoTime()
  4. Both methods of taking time are comparable with ~65 arithmetic operations. 

Conclusions

  1. Checking computer clock itself can take time when it is used for measurement of performance of relatively small pieces of code. So, we should be careful doing this. 
  2. Using nanoTime() is preferable when checking time period not only because it gives higher precision and is not sensitive to changing of computer clock but also because it runs faster. Moreover this method returns more correct results because it is using monotonic clock. It guaranties that if you perform 2 consequent calls the second call returns number greater than previous that is not guaranteed when executing currentTimeMillis().
  3. Do not try to optimize code by manual inlining of your logic. JVM does it for us at runtime. Indeed running arithmetic operation directly or by calling method that contains only this operation take exactly the same time. 

Acknowledgements

I would like to thank Arnon Klein for his valuable comments. 

Wednesday, January 9, 2013

Annotation based design patterns


Annotations introduced to Java 5.0 became a very well known and widely used language feature. There are more or less "standard" solutions where annotation can be successfully used. This article tries to classify different usages and to define some annotation based design patterns.

Introduction

Annotations define metadata that can be discovered using reflection API. They do not affect neither class hierarchy nor objects relationship. However, they can be used to label classes, methods and fields, to lookup services, to define model transformation rules, to configure proxies etc. These use cases can be classified as re-usable patterns exactly like design patterns in object oriented programming. 

Scope

This article is not a tutorial that explains what annotations can do. It assumes that a reader is familiar with annotations. The article shows the most popular patterns that can be used for solving typical tasks. Annotations can be classified by their retention policy. This article discusses annotations that can be retained by VM at runtime, e.g. marked as

@Retention(RUNTIME)  

Classification of annotations

Annotations may be classified by:
  • target (type, method, field, annotation etc)
  • role (stereotype, transformation, validation etc)
  • module that uses this annotation. Usually annotation is used by other class but sometimes annotated class itself uses its own annotation. 
  • instance lifecycle phases
    • before instance creation
    • before executing business logic (runner, injector)
    • during executing business logic (discovering stack trace)

Annotation based design patterns

Stereotype (Tag)

Tag interfaces (interfaces that do not declare any method and are used as a kind of label of class that implements them) were used for a long time before inventing of annotations. The classic example of such interface is java.io.Serializable. Since tag interface does not declare methods there are two ways to use it:

if (obj instanceof Serializable) {...}
or
if (Serializable.isAssignableFrom(clazz)) {...}

If we use annotations instead of tag interface we can replace definition:

class MyClass implements MyTag {...}

where MyTag is defined as 

interface MyTag {}

by the following one:

@MyTag
class MyClass {...}

where MyTag is defined as:

@interface MyTag {}

Class marked with this annotation can be detected using code:

if (clazz.getAnnotation(MyTag.class)) {...}

Using annotation instead of tag interface does not require additional efforts during implementation and has advantage: annotation can hold one or several parameters.

Tags or Stereotypes allow defining what the class does in different contexts.

Examples:

  • org.springframework.transaction.annotation.Transactional
  • javax.persistence.Transient
  • java.lang.annotation.Documented
  • java.lang.annotation.Retention
  • java.lang.annotation.Target

Service locator

Typical software product consists of modules or services. Components should be able to find other services that provide required functionality. Service as well as tag pattern may be defined as a class that implements specific interface. But contrary to tag interface service interface declares methods.

Before annotations were invented frameworks could locate service if it implemented required interface. This method does not allow distinguishing between two different implementations of the same interface. Annotations allow this. For example Service annotation of Spring Framework can hold service name:

@Service("manager1") 
public class FirstManager implements Manager {}

@Service("manager2") 
public class SecondManager implements Manager {}

This example shows two services that implement the same interface but can be identified by the name written as an annotation argument. 

Not only class but also separate method can be a service. For example, each test in the test case is "service" that validates specific testing scenario. Particular test is labeled with annotation @Test and framework can find it. 

More complicated example of service pattern is @RequestMapping of Spring MVC. This annotation supports several attributes that help the framework to choose suitable services according to HTTP request parameters. Both classes and methods can be annotated with @RequestMapping. 


Injector

Injector is an annotation that helps framework to inject (or initialize) method arguments when calling business method. @PathVariable of Spring MVC that is used in conjunction with @RequestMapping instructs the framework how to initialize method arguments:


@RequestMapping(value = "/user/{username}", method = RequestMethod.GET)
@ResponseBody
public User getUser(@PathVariable("username") String userName) {...}


Now when URL looks like http://thehost/app/user/johnsmith the framework extracts johnsmith from the URL and passes it as a method argument userName because this argument is marked with annotation @PathVariable("username"). 



Master (Runner)

Contrary to Service Locator that defines metadata of the class itself the runner refers to other class that will be used to run the current class. The typical example is @RunWith annotation of JUnit. This annotation marks test case and defines the runner that will execute current test case:


@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {...}


Configurer

Annotation may configure class at runtime. An example is @Parameters annotation of JUnit that must be used in conjunction with Parametrized test runner.
We can run the same test case with different set of arguments and expected results using @Parameters. The following simple example shows how to use these annotations:

@RunWith(value = Parameterized.class)
public class MatchTest {
private Pattern pattern = Pattern.compile("^\\d+$");
private String number;
private boolean expected;


public MatchTest(String number, boolean expected) {
this.number = number;
this.expected = expected;
}

@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { 
    {"100 kg", false}, {"123", true}, {"220 lb", false} 
  });
}

@Test
public void match() {
Assert.assertEquals(expected, pattern.matcher(number).find());
}
} 

In the above example JUnit runs this test case 3 times passing "100 kg", "123", "220 lb" as the test arguments and false, true, false as the expected results.


Proxy/Wrapper/AOP

Annotations may be used to create and configure class wrapper or dynamic proxy or even to modify the byte code of the class itself utilizing byte code engineering. Spring security framework implements this pattern as follows:


@PreAuthorize("hasRole('ROLE_USER')")
@PostFilter("hasPermission(filterObject, 'read') or hasPermission(filterObject, 'admin')")
public List<Contact> getAll();



The example above shows how to annotate bean method so that its invocation is permitted only if current user has role ROLE_USER. Moreover, the returned collection is filtered automatically and the result contains only elements for which the condition is defined by @PostFilter is true. Spring wraps the  application level bean with dynamic proxy to perform security check and filter results according to annotation based configuration.

Validator

Annotations can be used for configuration of data validation. Two types of validation can be distinguished: bean validation (JSR 303) and method validation. Hibernate validation framework supports both types using the similar way. 


Bean validation

public class Car {

    @NotNull 

    private String manufacturer;

        @NotNull

        @Size(min = 2, max = 14)

        private String licensePlate;



        @Min(2)

        private int seatCount;

        ................

}




Method validation

public @NotNull @Size(min-1) Collection<Role> findRolesOfUser(@NotNull User user) {...}

Both bean and method validations use similar annotation syntax. However they differ in implementation.

  • Method validator typically uses dynamic proxy or byte code engineering. Bean validation may be implemented utilizing validation mechanisms of other systems. For example, @NotNull annotated field may be validated using appropriate constraint of target relational database. 
  • Method validator is always synchronous while validation of bean field may be asynchronous. For example, in Hibernate persisted entity the constraint violation can be found when transaction is being committed. It is not necessarily happens directly after bean field modification.

Transformer

Transformer defines how to convert value from one form to another. Typical usage is marking bean properties or appropriate getters. The most popular examples are:
  • JaxB annotations @XmlElement@XmlAttribute@XmlTransient that define how to transform bean properties to XML elements and vice versa.
  • Hibernate annotations: @Table@Id, @Column etc. that define how to transform objects to records stored in relational database and vice versa.
The above mentioned  @PostFilter annotation that configures dynamic proxy can be classified also as a transformer. It defines additional criteria for filtering of collection retrieved from database. 


Annotation container

Two or more annotations of the same type are not allowed on specific element. This is forbidden by the java compiler. One solution is to use array instead of simple value for the specific attribute. For example, already mentioned  above  @RequestMapping can map specific controller or its method to several URLs:

@RequestMapping(value = {
    "/user/{username}", 
    "/userlist?username={username}"}, 
method = RequestMethod.GET)

@ResponseBody
public User getUser(@PathVariable("username") String userName) {...}

This is a good solution if the value of the attribute is not used in conjunction with the value of the other attribute: mappings of both URLs are valid for HTTP GET.

 Let's see another example. 

@XmlElement(name = "user-name", required=true)
public String getUsername() {return username;}

In this example the field username is mapped to mandatory XML element user-name.  How can we support mapping of the same bean field to additional XML element UserNameWe cannot add annotation:

@XmlElement(name = "UserName", required=false)

to the same getter getUsername(). Fortunately JAXB provides another annotation   @XmlElements  that plays role of the container for other annotations:

@XmlElements ({
    @XmlElement(name = "user-name", required=true),
    @XmlElement(name = "UserName", required=false)
)}
public String getUserName() {return username;}

The getter is annotated once using @XmlElements. However, both object-to-XML mappings are provided. 

Definition of @XmlElements is very simple. The value type is an array of XmlElement:


public @interface XmlElements {

    XmlElement[] value();

}

Custom annotation

Regular classes can be customized using inheritance. Annotations do not support inheritance. How can we customize generic annotations?

Possible solution is to use custom annotation which is annotated with another annotation provided by framework. @Profile annotation of Spring framework is an example of this pattern. As described here Spring supports profiles. We can define several profiles and run different set of beans for each one. Bean can be associated with profile using @Profile annotation. Both FirstDevService and SecondDevService will run when profile is dev.


@Profile("dev") @Service
public class FirstDevService { ... }


@Profile("dev") @Service
public class SecondDevService { ... }

Using @Profile("dev")annotation is relatively verbose and error prone: a bean which is by mistake marked as @Profile("deu")will not start in mode "dev" and no error message will be generated. Fortunately Spring allows creating custom annotation @Dev and mark it with @Profile:



@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Profile("dev")
pubilc @interface Dev {}

Now we can use this new annotation as following:


@Dev @Service
public class FirstDevService { ... }


@Dev  @Service
public class SecondDevService { ... }

Syntax that uses custom annotations is shorter, more readable and less error prone: simple mistake in annotation name will produce compilation error.

Caller identifier

Sometimes code has to discover its caller. Let's examine the following examples. The trick is to iterate over stack trace and to look for specific annotation.

  • Factory will create an instance of a special mockup implementation instead of real implementation when running in test environment. Test context may be identified if one of stack trace elements is annotated with @Test.
  • Special logic can be required when running in web context. Web context can be detected if @WebServlet or @Controller annotations are found.


Here is a simple implementation of utility that checks whether the code was called by class annotated with specified annotation. For example CallerUtil.isCallerClassAnnotatedBy(Controller.class) determines whether the caller is Spring MVC controller. 

public class CallerUtil {
private static Map<String, Class<?>> classes = new HashMap<String, Class<?>>();

public static boolean isCallerClassAnnotatedBy(
Class<? extends Annotation> annotationClass) {
for (StackTraceElement e : new Throwable().getStackTrace()) {
Class<?> clazz = getClazz(e.getClassName());
if (clazz.getAnnotation(annotationClass) != null) {
return true;
}
}
return false;
}

private static Class<?> getClazz(String className) {
Class<?> clazz = classes.get(className);
if (clazz == null) {
try {
clazz = Class.forName(className);
classes.put(className, clazz);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}
return clazz;
}
}

Annotated interface

Annotation targeted to type and annotated as @Inherited can be retrieved even if it is used to annotate not the class itself but its super class:


@Retention(RUNTIME) 
@Target(TYPE)
@Inherited
public @interface  MyAnnotation  {}

@MyAnnotation
public class Base {}

public class Child extends Base {}

The call Child.class.getAnnotation(MyAnnotation.class) will return instance of MyAnnotation although class Child is not annotated with MyAnnotation because base class is annotated and MyAnnotation is annotated itself as @InheritedUnfortunately annotation are inherited only from super classes. Method getAnnotation() does not return annotations used for interface implemented by current class

@MyAnnotation
public interface Foo {}

public class FooImpl implements Foo {}

The call FooImpl.class.getAnnotation(MyAnnotation.classwill return null because Foo is an interface. 

Although I have not seen this pattern utilized by popular libraries I personally think that annotated interfaces may be very useful. To retrieve annotation from the interface we have to iterate over all interfaces implemented by class and try to retrieve the annotation from each interface separately. The following utility method retrieves annotation applied to class itself, its base class or any of interfaces implemented by this class directly or indirectly.

public static <A extends Annotation> A getAnnotation(Class<?> clazz, Class<A> annotationType) {
A classAnnotation = clazz.getAnnotation(annotationType);
if (classAnnotation != null) {
return classAnnotation;
}
for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
  for (Class<?> implementedInterface : c.getInterfaces()) {
  A interfaceAnnotation = implementedInterface.getAnnotation(annotationType);
  if (interfaceAnnotation != null) {
  return interfaceAnnotation;

  }

  }
}

return null;
}





Shared constructor parameter

Let's review the example. There is an abstract class Base with constructor that accepts parameters of type Class

public abstract Base {
    protected Base(Class<?> type) {
        // uses argument type here
    }
}


There is an abstract subclass Intermediate that has nothing to do with the parameter. 
typical tasks
public abstract Intermediate extends Base {
    protected Intermediate(Class<?> type) {
        super(type); 
    }
}


There is the concrete class Concrete that sends the same value of the parameter for all its instances.

public Concrete extends Intermediate {
    protected Intermediate(Class<?> type) {
        super(String.class); 
    }
}

Although Intermediate has nothing to do with type it must declare constructor that just passes the parameter to its base class. The inheritance chain may be longer. But each class in the chain must have such trivial constructor, i.e. must be aware of the base class parameter existence.

Alternatively we can pass this data using annotations.

Let's define annotation CocreteType:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@interface ConcreteType {
    Class<?> value();
}

The constructor of the base class does not have to accept the parameter. It extracts this information from annotation that exists in the concrete class:

public abstract Base {
    protected Base(Class<?> type) {
        Class<?> type = 
            getClass().getAnnotation(ConcreteType.class).value();
        // deal with type
    }
}


Both Intermediate and Concrete classes do not have explicit constructor at all:

public abstract Intermediate extends Base {
}

The value of type is defined using annotation.

@ConcreteType(String.class)
public Concrete extends Intermediate {
}

This implementation is shorter and easier for modification. For example, if  parameter type is changed Intermediate class should not be modified at all. 

By the way, Concrete class can be subclassed too:

public MoreConcrete extends Concrete {
}

Class MoreConcrete is not annotated with @ConcreteType but since @ConcreteType is annotated as @Inherited, MoreConcrete  inherits it from Concrete.



Conclusions

Design patters are well known technique for creating robust and reusable software components. Various ways of using annotations in Java programming language can be classified as annotation based design patterns. This article suggests classification of typical tasks that can be implemented by using annotations. Author hopes that this classification may be helpful when designing and choosing instruments for implementation of other similar tasks.





Wednesday, October 17, 2012

Java tricky questions

Introduction

There are a lot of articles that describe various java tricky questions. But IMHO most of that questions can be easily answered by person that knows java well. However there are more complicated tricks that typically cause even experienced people to fail. This article tries to put such kind of trick together.

Tricks classification

The tricks are typically based on

  • internal caches managed by JDK classes or JVM itself
  • compiler optimizations
  • hidden and not obvious type transformations including autoboxing
  • magic of generics
  • tricks of terminology
  • using of uncommon, bad and anti-conventional coding and naming that are expected to confuse the person being interviewed.

This classification as well as the following list are not full and cannot be full. However the examples show the general ideas.

Please be aware of the fact that author classify people that use such questions during job interview as criminals. Such questions do not check knowledge of programming language but can confuse even experienced programmer.


String concatenation

What will the following code fragment print? 


String str1 = "abc:5";
String str2 = "abc:5";
String str3 = "abc:"+5;
String str4 = "abc:"+(1+4);
String str5 = "abc:"+str1.length();
System.out.println(str1 == str1);
System.out.println(str1 == str2);
System.out.println(str1 == str3);

System.out.println(str1 == str4);
System.out.println(str1 == str5);
System.out.println(str1 == new String(str1));



Answer


true
true
true
true

false
false



Description

Even beginners know that direct comparison of references is not the same as invocation of equals() method. So, we can think that every invocation of == will return false. So, why does it return true in 4 first cases?  Let's review the results one by one. 

  1. First true is trivial. Reference is equal to itself. 
  2. String is not a regular class. It is built-in java type. String constants are cached, so str1 and str2 refer to exactly the same object. This is the reason for the second true.
  3. str3 is defined as "abc:"+5, so it should not be the same as str1: value of the variable is calculated at runtime. In fact java compiler performs all calculations of constant expressions, so expression "abc:"+5 is transformed to "abc:5" at compile time and therefore cached by regular string cache. 
  4. This case is similar to #3. Both mathematical expression and concatenation are done at compile time, so the string is taken from cache.  
  5. The case of str5 is special: java compiler cannot call method, so the string value calculation is done at runtime and the string cannot be cached. 
  6. This case is similar to #5. Constructor cannot be called at compile time, so new object with the same value is created. 

Magic integers

What will this code snippet print?

Integer v1_1 = 1;
Integer v1_2 = 1;

Integer v127_1 = 127;
Integer v127_2 = 127;

Integer v128_1 = 128;
Integer v128_2 = 128;

System.out.println(v1_1 == v1_2);
System.out.println(v127_1 == v127_2);
System.out.println(v128_1 == v128_2);


The answer is:
true
true
false

Now the question is "why?!" Indeed, how can value of variable affect the comparison result? How is it possible that 127==127 while 128!=128?

The reason is that line 

Integer v127_1 = 127;

is compiled to 

Integer v127_1 = Integer.valueOf(127);

Here is how de-compiled byte code looks like:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;


that uses internal cache to retrieve the value. Only if value is not in cache new instance of Integer is created. The cache is initialized to numbers from 0 to 127 inclusive. So, when we try to get value of 127 we get the same instance every time. However attempt to get value greater than 127 creates new object.


int method that returns null


Everyone understands that the following code cannot be compiled:

private int temp() {
    return null; 
}

The reason is that int type is incompatible with null value.

But the following code is compiled perfectly:

private int temp() {
    return (true ? null : 0); 
}

This code is compiled because compiler interprets null as a legal value of Integer and then performs autoboxing, i.e. calls intValue() of  Integer object that contains null. This causes NullPointerException at runtime. 
This question and description are taken from stackoverflow (feel free to up-vote). 




int method that does not return anything



If Method declared contains return type the method must return value:

private int temp() {
    return 0; 
}


The following declaration will cause compilation error:

private int temp() {
}

This method must return a result of type int



Actually each execution path of the method must end with either return or throw statement:


private int temp(int i) {
    if (i < 0) {
        throw new IllegalArgumentException("negative");
    }
    return i; 
}

So, is it indeed possible to create int method that neither returns value nor throws exception? The answer is yes:


private int temp() {
    while(true);
}

This method can be successfully compiled and however does not return value and doesn't throw exception. The reason is that this method also never terminates. Compiler knows this and does not complain that return statement is missing.

Now here is a tricky question: write the shortest syntactically correct method so that its return type is int. Every normal person will write something like:

int f() {return 0;} 

while the right answer is:

int f() {for(;;);} 

because it is shorter by 1 character. 


Arithmetic operations on values of byte and/or short types

Let's say that we have the following declaration:

byte b = 0;

Are the following 3 operators equal?

b++;
b+=1;
b = b + 1;

All three should increment the variable by 1, right? Yes, it is correct for first 2 lines. The third line cannot be compiled:

ByteIncrement.java:5: possible loss of precision
found   : int
required: byte
                b = b + 1;

This happens because numeric constants automatically belong to type int that bigger than byte. So, to make this line to work we have to add explicit casting:

b = b + (byte)1;

Now all operations indeed equal and increment the variable b by 1. 
This trick is taken from stackoverflow, so feel free to up-vote.

Throwing checked exception without declaration

Everyone knows that there are checked and unchecked exception in java. Unchecked exceptions extend directly or indirectly from RuntimeException and do not have to be declared. Checked exceptions extend directly or indirectly from Exception (but not from RuntimeException) and must be declared. Otherwise attempt to throw them causes compilation error. 

So, what do you think about the following code:



import java.sql.SQLException;

public class Test {

    // No throws clause here
    public static void main(String[] args) {
        doThrow(new SQLException());
    }

    static void doThrow(Exception e) {
        Test.<RuntimeException> doThrow0(e);
    }

    static <E extends Exception> void doThrow0(Exception e) throws E {
        throw (E) e;
    }
}


Methods main() and doThrow() do not have "throws SQLException" declaration. Method doThrow0() defines expected exception using generic parameter E. Sending RuntimeException as a method generic parameter satisfies compiler and it does not require "throws SQLException" declaration. But in fact SQLException is created and thrown:

$ java Test
Exception in thread "main" java.sql.SQLException
        at Test.main(Test.java:7)
This trick was discussed by Lukas Eder here and here.




Terminology tricks

These tricks are typically used in multi and single-selection tests. Often both question and answers are very long and almost equal, so very small but significant differences must be found. Other type of the questions is based on the fact that people do not remember the exact meaning of terms. Here is an example.

Please select choose the list of words that contains maximal number of java keywords
  1. abstract, continue, true
  2. sealed, foreach, unless
  3. goto, const, strictfp
  4. class, for, null, false
Here is how typical person is thinking:
#2 may be rejected immediately. #1, #2, #3 contain words we use in java every day but #4 is longer, so the right answer is 4.


And this is wrong. true, false and null are not keywords. They are literals (see here). So, #1 and #4 contain only 2 java keywords. What happens with #3? Everyone knows that goto is not supported by java as well as constant values are defined using keyword final. The third word in the list strictfp looks strange at all. However all these words are legal java keywords:

  1. goto and const are reserved but not used (see here).
  2. strictfp was added in java 1.2 (!). It restricts floating point calculations to ensure portability.

Thursday, April 19, 2012

Initiate current Spring profile from custom properties file

Recently released Spring 3.1 has a very useful new feature named profile. Shortly speaking we can now say that certain bean of group of beans will be deployed only for current profiles or environments. This feature is perfectly explained here.

There is a very simple way to define current profile(s): just specify system property "spring.profiles.active" with -D command line switch:

spring.profiles.active=production

You can even specify several profiles, e.g.

spring.profiles.active=production,oracle

(that probably means that your application is running in production mode and uses to Oracle DB).

You can also set the current profile programmatically:

ctx.getEnvironment().setActiveProfiles("production", "oracle");


or using configuration file:



ctx.getEnvironment().getPropertySources().addFirst(
    new ResourcePropertySource(conf)
)



(where ctx is of type ConfigurableEnvironment.)




The question is only where to write this code when you using starting Spring in web environment? You can define bean that implements ApplicationContextAware interface. The setApplicationContext method declared by this interface is called by container when bean is being initialized. The problem is that this is too late. When this method is called the current profile has been already initialized.

Better way is described here.

We have to define our custom ApplicationContextInitializer and configure it using special  context parameter contextInitializerClasses using web.xml:


<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.alexr.spring.ProfilesInitializer</param-value>
</context-param>




Here is how the code of ProfilesInitializer.initialize() looks like.


@Override
public void initialize(ConfigurableApplicationContext ctx) {
    try {
        String profilesSysProp = System.getProperty("spring.profiles.active");
if (profilesSysProp != null) {
        return;
}
String panpwrConfDir = System.getProperty(PANPWR_CONF_PROP);
String confFile = System.getProperty(CONF_PROP);
ctx.getEnvironment().getPropertySources().addFirst(
            new ResourcePropertySource(confFile));
      } catch (IOException e) {
        throw new RuntimeException(e);
   }
}

This simple solution allows initializing of profile using the same configuration file where all other custom parameters are stored. The profile defined in custom file can still be overridden using system property spring.profiles.activeThis is done by if statement that checks whether the property exists.

Conclusions

Profiles is a very useful feature of Spring 3.1. This post shows how to initiate profile using custom properties file.