Aspect trace logging in Java (Spring Framework)

An easy way to enable tracing of methods and parameter values in Java Spring is by using AspectJ. A simplified example of my Aspect class to make tracing easy, without any ‘logger.trace’ code in the classes itself:

package com.markvandenbergh.test.util;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Aspect
public class LoggerAspect {

    private final Logger logger = LoggerFactory.getLogger(LoggerAspect.class);

    // before the execution of any method with any number and type of parameters
    // in package 'test' and any sub-package execute the following code...
    @Before("execution(* com.markvandenbergh.test..*.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        if(logger.isTraceEnabled()) {
            // constructing a string of the method signature, method and parameters
            String traceString = joinPoint.getSignature().getDeclaringTypeName() +
                "." + joinPoint.getSignature().getName() + "(";
            Object[] args = joinPoint.getArgs();
            for(int i = 0; i < args.length; i++) {
                if(args[i] != null) {
                    traceString += args[i];
                } else {
                    traceString += "null";
                }
                if(i < (args.length -1)) {
                    traceString += ", ";
                }
            }
            traceString += ")";
            logger.trace(traceString);
        }
    }
}

If tracing is enabled this will log the entry of any method with it’s parameters within the com.markvandenbergh.test package (sub-packages included, because of the double dot between ‘test’ and ‘*.*’). Example of the output:

2012-01-26 15:51:55,942 TRACE http-bio-8080-exec-4 com.markvandenbergh.test.service.TestService.methodNumberOne(parameterValue)
2012-01-26 15:51:55,942 TRACE http-bio-8080-exec-4 com.markvandenbergh.test.service.TestRepository.methodInRepository(parameterValue)

Do note that only Spring beans will be picked up by the Aspect. If you have regular Java classes that are not instantiated using Spring they will not be logged using this code.
You also need some minor Spring configuration for this.

<aop:aspectj-autoproxy />
<bean class="com.markvandenbergh.test.util.LoggerAspect" />

The Maven dependencies for this are:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

All of this is nothing new or fancy, but I found it quite useful in reducing the amount of work and boilerplate code in my classes. Some other useful ‘advice’ types (that’s what the ‘before’ is called) are: ‘after’ and ‘around’. ‘After’ works about the same as the ‘before’ in my example, for an example of the ‘around’ advice go to the Spring framework reference documentation.

Posted in Coding, General, Java, Spring | Tagged , , , , , | Leave a comment

Autowiring Spring bean in IntelliJ

Having one of the following errors in IntelliJ?

Could not autowire. No beans of 'yourType' type found

or

Could not autowire. There is more than one bean of 'yourType' type.

If you’re sure you have your Spring bean definitions correct (for me, the application works fine, it just displays an annoying error in the IDE), check your project ‘iml’ file if you have a Spring facet defined.

<facet type="Spring" name="Spring">
  <configuration>
    <fileset id="web: application context" name="MVC application context" removed="false">
      <file>file://$MODULE_DIR$/src/main/resources/spring/applicationContext-interface.xml</file>
    </fileset>
  </configuration>
</facet>

After removing this facet everything works fine for me.

Posted in Coding, IntelliJ, Java, Spring | Tagged , , , , | Leave a comment

ExtJS – Local combobox keeps loading

Had a problem with ‘local store comboboxes’ on screens that I reused in several places. I’m mentioning ‘local store’ because when using a local store the combobox doesn’t have any reason to show a loading box. Due to some strange bug the comboboxes on those screens would suddenly go into a mode where they don’t allow any mouse interaction and show a loading box all the time.

ExtJS - Combobox issue

ExtJS – Combobox issue

This would happen when the screen containing the combobox was created, the value was changed, the screen was destroyed (closed) and after that the screen was reopened (created again).

I found out it was due to the way I defined the stores in the comboboxes.

Ext.define('mynamespace.something.HourSelector', {
    extend: 'Ext.form.field.ComboBox',
    alias: 'widget.hourselector',
    xtype: 'combobox',
    mode: 'local',
    valueField: 'value',
    store: Ext.create('Ext.data.Store', {
        fields: [
            'value',
            'text'
        ],
        data: [
            {value: 0, text: '0 hours'},
            {value: 1, text: '1 hour'},
            {value: 2, text: '2 hours'}
            // etc
        ]
    })
});

Removed some code to keep it short and easily readable. By changing this to the following, the problem disappeared.

Ext.define('mynamespace.something.HourSelector', {
    extend: 'Ext.form.field.ComboBox',
    alias: 'widget.hourselector',
    xtype: 'combobox',
    mode: 'local',
    valueField: 'value',
    initComponent: function(){
        this.store = Ext.create('Ext.data.Store', {
            fields: [
                'value',
                'text'
            ],
            data: [
                {value: 0, text: '0 hours'},
                {value: 1, text: '1 hour'},
                {value: 2, text: '2 hours'}
                // etc
            ]
        });
        this.callParent(arguments);
    }
});
Posted in Coding, ExtJS, Javascript | Tagged , , , | Leave a comment