Tag Archives: Tomcat

Log4j config: Use Tomcat context params

I wanted to use parameters defined in context.xml on Tomcat 8 in configuration of Log4j2. My context was defined like:

<?xml version="1.0" encoding="UTF-8"?>

<Context>
    <Parameter name="instanceName" value="testInstance" override="false"/>

    <Resource .../>
</Context>

Now I would like to use parameter instanceName in log filename. I spent many hours trying various approaches and googling. I wonder why is this not better documented – Using Log4j 2 in Web Applications does not really help. In the end it is easy – just use web: prefix like this:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
    <Properties>
        <Property name="log-path">${sys:catalina.base}/logs/${web:instanceName}</Property>
    </Properties>

    <Appenders>
        <RollingFile name="file" fileName="${log-path}/test.log" filePattern="${log-path}/test-%d{yyyy-MM-dd}.log">
            ...
            ...
        </RollingFile>

    ...
    ...
</Configuration>

That’s it folks!

AspectJ LTW + Tomcat 8 + Eclipse + OpenJDK 8

Recently I was trying to get working AspectJ on Tomcat 8 using OpenJDK 8. I had selected LTW (Load-Time Waving) approach. Waving is modification of bytecode so that aspect methods may be called.

My intention was to create simple logging aspect that will log traces of all method in certain package. I spent terrible, hot day on it. Coding was simple:

package com.myutils;

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 MyLogger {

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

 @Before("execution(* com.mypackage..*(..))")
 public void log(JoinPoint point) {
 logger.trace("Autotrace {}.{}({})", point.getSignature().getDeclaringTypeName(), point.getSignature().getName(),
 point.getArgs());
 }

}

Here goes some memo which will maybe help you:

Dependencies

We use Gradle:

compile("org.aspectj:aspectjrt:1.8.6")
compile("org.aspectj:aspectjweaver:1.8.6")

Tomcat 8

Tomcat must be launched with -javaagent property. This agent is responsible for on-the-fly waving.

-javaagent:/home/my/path/aspectjweaver-1.8.6.jar

Best is to put it into “JAVA_TOOL_OPTIONS” before starting Tomcat. In Eclipse you can set this variable into Run configuration->Environment.

Configuration

It is absolutely crucial to have aop.xml on classpath. The path must be exactly “META-INF/aop.xml“. So for my .war project it was not enough to put it into /src/webapp/META-INF/aop.xml because that is not on classpath. I have put it into /src/resources/META-INF/aop.xml and Voila! If this file is not presented, no exception or warning is shown.

Scope of Waving

It is crucial to have Aspect classes as part of Waving. Otherwise error “java.lang.NoSuchMethodError: com.myutils.MyLogger.aspectOf()” is generated.

<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>

 <!-- -verbose -debug -->
 <weaver options="-showWeaveInfo">
 <include within="com.mypackage.*" />
 <include within="com.myutils.*" />
 </weaver>
 <aspects>
 <aspect name="com.myutils.MyLogger" />
 </aspects>
</aspectj>

Compilation

Code must be compiled with debug symbols (javac -g) otherwise LTW won’t work. In Eclipse that means to run it in debug mode.

Conclusion

For beginner in AspectJ it was terribly hard to get working solution. One of path I tried was through Spring AOC, but it does not helped because Spring AOC is basically just wrapper of AspectJ waving tooling.

Please note this post is based on 1 day experience with AspectJ 😉 I hope this helps you not to waste time on same pitfalls as I did!