Monday, July 22, 2013

Using Logback with Spring

The mandatory logging dependency in Spring is the Jakarta Commons Logging API (JCL). The nice thing about commons-logging is that you don't need anything else to make your application work. It has a runtime discovery algorithm that looks for other logging frameworks in well known places on the classpath and uses one that it thinks is appropriate (or you can tell it which one if you need to). If nothing else is available you get pretty nice looking logs just from the JDK (java.util.logging or JUL for short).

Unfortunately, the runtime discovery algorithm in commons-logging, while convenient for the end-user, is problematic. Switching off commons-logging is easy: just make sure it isn't on the classpath at runtime.
<dependencies> 
  <dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-context</artifactId> 
    <version>${spring.version}</version> 
    <exclusions> 
      <exclusion> 
        <groupId>commons-logging</groupId> 
        <artifactId>commons-logging</artifactId> 
      </exclusion> 
    </exclusions> 
  </dependency> 
</dependencies> 
Now this application is probably broken because there is no implementation of the JCL API on the classpath, so to fix it a new one has to be provided.Logback is very powerfull logging framework and is intended as a successor to the popular log4j project. Logback implements SLF4J api so we need slf4j-jcl brindge on classpath.
Final dependencies are:
<dependencies> 
  <dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-context</artifactId> 
    <version>${spring.version}</version> 
    <exclusions> 
      <exclusion> 
        <groupId>commons-logging</groupId> 
        <artifactId>commons-logging</artifactId> 
      </exclusion> 
    </exclusions> 
  </dependency> 
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>${jcl.over.slf4j.version}</version>  
  </dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
  </dependency>
</dependencies> 

Thursday, July 11, 2013

Cunning <mybatis:scan/> elemnt

In version 1.2.0 of Mybatis-Spring a possibility of scanning mapper interfaces via XML element <mybatis:scan/> has appeared. As a doc says  the <mybatis:scan/> XML element will search for mappers in a very similar way than the Spring built-in element <context:component-scan/>searches for beans. Here is an example:
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
               http://mybatis.org/schema/mybatis-spring 
               http://mybatis.org/schema/mybatis-spring.xsd"> 
     <mybatis:scan base-package="org.mybatis.spring.sample.mapper" /> 
</beans>

The base-package attribute lets you set the base package for your mapper interface files. You can set more than one package by using a semicolon or comma as a separator. Mappers will be searched for recursively starting in the specified package(s). 
Also, if we have only either one sqlSessionFactory in application context or one sqlSessionTemplate(but not both) we may not specify them in <mybatis:scan/>, but if we have more than one of them - we should. Also attribute is factory-ref or template-ref, but actually it's not a ref. Mybatis-Spring treats to the value pointed in that attribute as to bean name. So, in my opinion the correct meanning of that attributes are factoryBeanName and templateBeanName as known properties in MapperScannerConfigurer.

<mybatis:scan/> element is handled by org.mybatis.spring.config.NamespaceHandler which is pointed as handler in spring.handlers file under META-INF directory of mybatis-spring.jar.This handler just overrides init method and registers the beanDefinitionParser MapperScannerBeanDefinitionParser. This parser scan the packages specified in base-package attribute and creates bean definitions for MapperFactoryBeans. The default behavior involves beans created using BeanDefinition to have autowire-candidate property to be set to true. Then, if we haven't specified sqlSessionFactory-ref or sqlTemplate-ref in <mybatis:scan/> tag, the subclass of ClasspathBeanDefinitionScanner which is used in MapperScannerBeanDefinitionParser sets autowireMode on created bean to be AUTOWIRE_BY_TYPE. Thus, it produces the behavior similiar to @Autowire annotation on setSqlSessionFactory method of MapperFactoryBean

Sunday, July 7, 2013

Issue with MapperScannerConfigurer in mybatis-spring module

    Recantly I have encountered with interesting feature in mybatis-spring module. I have been developing persistance module for one project and need to write tests for it. Ofcourse I decided to use spring-test and also tried dbUnit. I wrote a base class for persistance test case which simply utilize dbUnit functionality(applying datasets). Also I've annotated that class with standart spring-test annotation:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@TransactionConfiguration(defaultRollback = true, transactionManager = "txManager")
@Transactional
which points to applicationContext and also uses transactionManager to roolback transactions(with dbUnit i clear the real table in test method, insert there test dataset, perform test and then rollback a transaction).
   All my persistance tests are focusing on testing mybatis mappers, so for that reason I used MapperScannerConfigurer to dynamically discover all mybatis mapper interfaces and create for each of them MapperFactoryBean instances which produce real instances of mapper interfaces. So, I configured a bean for MapperScannerConfigurer in applicationContext:
<bean id="mappeScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
  p:basePackage="com.mypackage"
  p:sqlSessionFactory-ref="sqlSessionFactory" />
As it needs sqlSessionFactory I declare it also. SqlSessionFactory needs a datasource to fetch connections from it, so i declare a datasource like this:
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource"
   p:username="${jdbc.username}" 
   p:password="${jdbc.password}" 
   p:url="${jdbc.url}"
   p:driverClassName="${jdbc.driverclass}" p:validationQuery="SELECT sysdate FROM dual" />
Ofcourse I need some property-placeholder to resolve references to jdbc stuff and I declare it:
<context:property-placeholder location="classpath:props/datasource.properties" />
It seemed to me that it's enough, but when I try to run the test I got next error:
org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driverclass}'
It means that placeholder hasn't been resolved. but why?

Monday, July 1, 2013

Spring Caching Abstraction + Guava Cache

Intro

   Caches are tremendously useful in a wide variety of use cases. For example, you should consider using caches when a value is expensive to compute or retrieve, and you will need its value on a certain input more than once.
   A Cache is similar to ConcurrentMap, but not quite the same. The most fundamental difference is that a ConcurrentMap persists all elements that are added to it until they are explicitly removed. A Cache on the other hand is generally configured to evict entries automatically, in order to constrain its memory footprint.
   Since version 3.1, Spring Framework provides support for transparently adding caching into an existing
Spring application. Similar to the transaction support, the caching abstraction allows consistent use of
various caching solutions with minimal impact on the code.
   To use the cache abstraction, the developer needs to take care of two aspects:
  • caching declaration - identify the methods that need to be cached and their policy
  • cache configuration - the backing cache where the data is stored and read from

Note that just like other services in Spring Framework, the caching service is an abstraction (not a cache implementation) and requires the use of an actual storage to store the cache data - that is, the abstraction frees the developer from having to write the caching logic but does not provide the actual stores. There are two integrations available out of the box, for JDK java.util.concurrent.ConcurrentMap and Ehcache.

Declarative caching declaration

Threre are a few annotations in Spring which help us to configure our cache:
  • @Cacheable is used to demarcate methods that are cacheable - that is, methods for whom the result is stored into the cache so on subsequent invocations (with the same arguments), the value in the cache is returned without having to actually execute the method. It's useful to note that default cache key generation occurs depending on method arguments. So, 
  1. if method has no arguments, than 0 is used.
  2. if only one param is given, that instance is used as a key.
  3. if more than one afrgument is given, a key computed from hashes of all params is used
More info you can find in javavadoc of DefaultKeyGenerator class. There is an option to provide own implementation of key generator.
  • @CachePut as opposed to @Cacheable annotation this annotation doesn't cause the method to be skipped - rather it always causes the method to be invoked and its result to be placed into the cache.
  • @CacheEvict is useful to remove stale data from cache
But just  annotations are not enough to configure our cache. Also we have to enable annotation by specifying <cache:annotation-driven/> in the applicationContext.xml


Method visibility and caching annotations

   When using proxies, you should apply caching annotations only to public methods. If you put an annotation on private, protected or package visible method no error is raised, but caching simply will not apply.
   Also note that buy default Spring uses JDK proxying mechanism, so implemenation of a service has to be accessed through the service interface. If you access a service directly(without interface) Spring will generate the proxy class(at startup time) but in that case CGLIB 2 should be on classpath(NOTE: Spring 3.2 already has CGLIB2, so if you are the user of that version of Spring, you shouldn't additionally include this library). There is an option to change proxy mode, but be very careful, if you specify proxy-target-class="true on <cache:annotation-driven/>
Because(from Spring reference):
Multiple <aop:config/> sections are collapsed into a single unified auto-proxy creator at runtime, which applies the strongestproxy settings that any of the <aop:config/> sections (typically from different XML bean definition files) specified. This also applies to the <tx:annotation-driven/> and <aop:aspectj-autoproxy/> elements.
To be clear: using 'proxy-target-class="true"' on <tx:annotation-driven/><aop:aspectj-autoproxy/>, <cache:annotation-driven> or <aop:config/>elements will force the use of CGLIB proxies for all three of them.

 Configuring Guava Cache as Storage

    Out of the box, Spring provides integration with two storages - one on top of the JDK ConcurrentMap and one for ehcache library. To use them, one needs to simply declare an appropriate CacheManager - an entity that controls and manages Caches and can be used to retrieve these for storage. 
    In project I decided to use Guava's LoadingCache. For that purpose I've created GuavaCacheFactoryBean which helps to configure and create LoadingCache instance. Actually, I used Spring's SimpleCacheManger which uses ConcurrentMap. So, GuavaCacheFactoryBean also converts LoadingCache to ConcurrentMapCache through the Guava's  Cache#asMap() method.
 Xml configuration:

<cache:annotation-driven cache-manager="cacheManager">
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
 <property name="caches">
     <set>
         <bean parent="parentCacheFactoryBean" p:name="attributes"/>
         <bean parent="parentCacheFactoryBean" p:name="history"/>
         <bean parent="parentCacheFactoryBean" p:name="actions" p:maxSize="100"/>
            </set>
 </property>
    </bean>
<bean id="parentCacheFactoryBean" abstract="true" class="com.example.GuavaCacheFactoryBean"
      p:expirationAccessTime="120" 
      p:maxSize="200" />

NOTE: cache-manager="cacheManager" is a default attribute in <cache:annotation-driven/>
And the GuavaCacheFactoryBean code(getters and setters are omitted):
public class GuavaCacheFactoryBean implements FactoryBean<ConcurrentMapCache> {

    private String name;
    private int maxSize;
    private int expirationAccessTime;

    private ConcurrentMap<Object, Object> store;
    private ConcurrentMapCache cache;

    @Override
    public ConcurrentMapCache getObject() throws Exception {
        return cache;
    }

    @Override
    public Class<?> getObjectType() {
        return ConcurrentMapCache.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @PostConstruct
    public void init() {
        this.store = CacheBuilder.newBuilder()
                .expireAfterAccess(expirationAccessTime, TimeUnit.MINUTES)
                .maximumSize(getMaxSize())
                .build().asMap();
        this.cache = new ConcurrentMapCache(this.getName(), this.store, true);
    }
   ...
}

There are many other options to configure LoadingCache via CacheBuilder, but for the purpose of the project I only need expireAfterAccess and maximumSize.

Here you can see examples of using caching annotations:

 @Caching(evict = {
            @CacheEvict(value = "attributes", key = CACHE_KEY_EXPR),
            @CacheEvict(value = "history", key = CACHE_KEY_EXPR),
            @CacheEvict(value = "actions", key = "#p0")
    })
    public void saveAction(long arg1, String arg2, long ar3) throws Exception{
              //here I make an access to db
  }

   In this example I use @Caching annotaion which is simply a grouping annotation for all cache annotations. It is used only if you have to specify a couple caching annotations on method. Also note how I access the method arguments(#p0). It's a preferred way; you can however use argument name, but it may not work since debugging info can not be included in your class files. With key attribute I specify the cache key.


Different storages

   To plug another cache back-end you have to provide CacheManager and Cache implementations. That classes tend to be simple adapters that map caching abstraction framework on top of the storage API as the ehcache classes can show.

Sunday, February 17, 2013

Maven properties

Maven properties can be used in pom.xml file or in any resource that is being processed by the Maven Resource plugin’s filtering features. A property is always surrounded by ${ and }.

Built-in properties


  • ${basedir} represents the directory containing pom.xml
  • ${version} equivalent to ${project.version} 

Project properties

All elements in the pom.xml, can be referenced with the project. prefix. This list is just an example of some commonly used elements:
  • ${project.build.directory} results in the path to your "target" directory.
  • ${project.build.outputDirectory} results in the path to your "target/classes" directory.
  • ${project.name} refers to the name of the project.
  • ${project.build.finalName} refers to the final name of the file created when the built project is packaged.
  • ${project.build.sourceDirectory} results in the path to your "src" directory.

Local user settings

Similarly, values in the user's settings.xml can be referenced using property names with settings. prefix.
${settings.localRepository} refers to the path of the user's local repository

Environment variables

Environment variables can be referenced using the env prefix,  ${env.PATH} returns the value of system's PATH variable. Any property which can be retrieved from the System.getProperty() method can be referenced as a Maven property. For example, ${java.home} specifies the path to the Java installation directory.

Parent Project variables

How can parent project variables be accessed? You can use the prefix: ${project.parent}.

Building project without running test

Next information refers to maven surfire plugin. If you want to disable tests to be run while building your project you have two options to utilize:
  • -DskipTests skips project's tests, but compiling them.
  • -Dmaven.test.skip skip all tests and even doesn't try to compile them.


Monday, January 28, 2013

Brief SpEL overview


"The Spring Expression Language (SpEL for short) is a powerful expression language that supports querying and manipulating an object graph at runtime. The language syntax is similar to Unified EL butoffers additional features, most notably method invocation and basic string templating functionality."
from Spring Framework Reference Manual 
Using SpEL we can:
  • reference bean properties, and methods;
  • reference types;
  • do math inside expression;
  • comparing values inside expression;
  • use regular expression inside SpEL;
  • access collection's members;
  • perform selection and projection operation on collections
Here are few examples that demonstrates aforecited SpEL properties:

Reference bean properties, and methods

 <bean id="carl"class="com.springinaction.springidol.Instrumentalist">
   <property name="song"value="#{kenny.song}"/>
 </bean>
Here we have a bean carl which has a property named song and the value of this property will be the same as in bean named kenny(actually at the instantiation time of bean carl kenny's bean must exist)
Also we can invoke methods inside expressions:
 <property name="song"value="#{songSelector.selectSong()}"/>
But there is a trick here: what if we want saying to upperCase the name of the song? We could simply invoke
toUppercase()
method on on resulting string object, but what if it return null? There is a solution for such cases: we can use a null-safe accessor. Here is a sample:
 <property name="song"value="#{songSelector.selectSong()?.toUpperCase()}"/>

Reference types

The key to working with class-scoped methods and constants in SpEL is to use the
T()
operator. Here is a sample:
<property name="multiplier"value="#{T(java.lang.Math).PI}"/>

Comparing values inside expressions

Here is an example:
<property name="largeCircle"
    value="#{shape.kind == 'circle' and shape.perimeter gt 10000}"/>
We can and, or not(or !) operators, as well such logical operators are legal: eq, lt, gt, le, ge. Also it is permitted to use java ternary operator.

Regular expressions

When working with text, it’s sometimes useful to check whether that text matches a cer-
tain pattern. SpEL supports pattern matching in expressions with its
matches
operator.
<property name="validEmail" 
   value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}"/>

Selecting and projecting collections' elements

Let’s say that you want to narrow the list of cities down to only those whose population is greater than 100,000. One way to do this is to wire the entire cities bean into a property and place the burden of sifting out the smaller cities on the receiving bean. But with SpEL, it’s a simple matter of using a selection operator (.?[]) when doing the wiring:
<util:list id="cities">
  <bean class="com.habuma.spel.cities.City"
      p:name="Chicago"p:state="IL"p:population="2853114"/>
  <bean class="com.habuma.spel.cities.City"
      p:name="Atlanta"p:state="GA"p:population="537958"/>
  <bean class="com.habuma.spel.cities.City"
      p:name="Dallas"p:state="TX"p:population="1279910"/>
  <bean class="com.habuma.spel.cities.City"
      p:name="Houston"p:state="TX"p:population="2242193"/>
  <bean class="com.habuma.spel.cities.City"
      p:name="Odessa"p:state="TX"p:population="90943"/>
  <bean class="com.habuma.spel.cities.City"
      p:name="ElPaso"p:state="TX"p:population="613190"/>
  <bean class="com.habuma.spel.cities.City"
      p:name="Jal"p:state="NM"p:population="1996"/>
  <bean class="com.habuma.spel.cities.City"
      p:name="LasCruces"p:state="NM"p:population="91865"/>
</util:list>

<property name="bigCities" value="#{cities.?[population gt 100000]}"/>

SpEL also offers two other selection operators, .^[] and .$[], for selecting the first and last matching items  (respectively) from a collection. For example, to select the first big city from cities:
<property name="aBigCity" value="#{cities.^[population gt 100000]}"/>
No ordering is done on the collection prior to selection, so the City representing Chicago would be wired into the aBigCity property. Likewise, the City object representing El Paso could be selected as follows:
<property name="aBigCity"value="#{cities.$[population gt 100000]}"/>

Collection projection involves collecting a particular property from each of the members of a collection into a new collection. SpEL’s projection operator (.![]) can do exactly that. For example, suppose that instead of a list of City objects, what you want is just a list of String objects containing the names of the cities and states:
<property name="cityNames"value="#{cities.![name+','+state]}"/>

Reference system and environments properties

We can also refer to system properties from spring or to those proprties that were setted with -D flag when running java process. Here are example(now I'll show how to set property of a bean directly in java code using
@Value
annotation):
public class PropertyValueTestBean {
  @Value("#{ systemProperties['user.name'] }")
   private String name;
}
Here we set name property to environment specific property user.name which refers to current user of the system.

PS. All examples are taken from "Spring in Action 3rd edition" and from "Spring framework reference manual"

Saturday, January 19, 2013

Eclipse color themes

When someone spends a lot of time writing code in his/her favourite IDE it's  rather important to correctly configure IDE's color theme to reduce eye strain. I've italicized the word 'correctly' because its meaning is a personal matter.
I like dark themes, but among many dark themes on Eclipse Color Theme I did not find any what would I like, so I decided to create own. There is a good eclipse plugin which provides themes from Eclipse Color Themes. Here is its update site.As a base for my theme I have chosen Inkpot.
So here are some examples of my work:
    java code style

    xml code style
    css code style
    After creating my theme I want it to use in any computer that i work on. Here is a solution how to transfer your color settings:

    1. go to your eclipse workspace directory
    2. then copy directory .metadata/.plugins/org.eclipse.core.runtime/.settings to your cloud drive like dropbox, google drive or whatever you use
    That directory contains color settings for all eclipse editors and also color settings of installed plugins.
    You can use standard eclipse functionality to copy preferences(Import/Export Preferences), but there is some pitfall: it doesn't copy color settings, only code formatting, hot keys, compiler settings etc.

    Here you can download my color theme

    Hello Blogger

    This is my first article in Blogger service. 

    All articles in this blog will be written mostly in English, but it's not my native language, so some mistakes may occur. If you notice a mistake in an article, you may point on it in comment (I will grateful for that)