Wednesday, October 15, 2014

How to find which method called the current method at runtime


I’m using the following helper class to find which method called the current method (at runtime.)

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class TraceHelper {
    private volatile static Method m;
    private static Throwable t;

    public TraceHelper() {
        try {
            m = Throwable.class.getDeclaredMethod("getStackTraceElement", int.class);
            AccessController.doPrivileged(
                    new PrivilegedAction() {
                        public Object run() {
                            m.setAccessible(true);
                            return null;
                        }
                    }
            );
            t = new Throwable();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getMethodName(final int depth, boolean useNew) {
        return getMethod(depth, t != null && !useNew ? t : new Throwable());
    }

    public String getMethod(final int depth, Throwable t) {
        try {
            StackTraceElement element = (StackTraceElement) m.invoke(t, depth + 1);
            return element.getClassName() + "$" + element.getMethodName();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
Then I use the following code inside my aspect to get the name of the method which called my current (executing) method.
String previousMethodName = new TraceHelper().getMethodName(2, false);

Include/exclude sources when using aspect-maven-plugin


AspectJ mavn plugin will add all .java and .aj files in the project source directories by default. By using <include/> and <exclude/> tags, you can add filtering on top of that. 


            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.5</version>
                <configuration>
                    <complianceLevel>1.7</complianceLevel>
                    <source>1.7</source>
                    <target>1.7</target>

                    <sources>
                        <source>
                            <!--<basedir>src/main/java</basedir>-->
                            <!--<includes>-->
                                <!--<include>**/TransationAspect.java</include>-->
                            <!--</includes>-->
                            <excludes>
                                <exclude>**/DcXferHandler.java</exclude>
                                <!--<exclude>**/ChunkingSqlSerActor.java</exclude>-->
                            </excludes>
                        </source>
                    </sources>
                </configuration>
                <executions>
                    <execution>
                        <!--<phase>process-sources</phase>-->
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Tuesday, October 14, 2014

Stackmap frame errors when building the aspectj project with Java 1.7


I had a project which used aspectj and it was building fine with Java 1.6. When I updated it to Java 1.7 I saw the following error.

[INFO] Molva the Destroyer Aspects ....................... FAILURE [2.324s]
[INFO] Molva The Destroyer Client ........................ SKIPPED
[INFO] Molva The Destroyer Parent ........................ SKIPPED
[INFO] Molva The Destroyer Distribution .................. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.424s
[INFO] Finished at: Tue Oct 14 11:16:19 PDT 2014
[INFO] Final Memory: 12M/310M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.1:java (default) on project molva-the-destroyer-aspects: An exception occured while executing the Java class. Expecting a stackmap frame at branch target 30
[ERROR] Exception Details:
[ERROR] Location:
[ERROR] com/concur/puma/molva/aspects/TestTarget.main([Ljava/lang/String;)V @12: invokestatic
[ERROR] Reason:
[ERROR] Expected stackmap frame at this location.
[ERROR] Bytecode:
[ERROR] 0000000: 2a4d b200 5e01 012c b800 644e b800 c62d
[ERROR] 0000010: b600 ca2c 2db8 00bb 2db8 00bf 57b1 3a04
[ERROR] 0000020: b800 c62d 1904 b600 ce19 04bf
[ERROR] Exception Handler Table:
[ERROR] bci [12, 30] => handler: 30
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

My maven configuration looked like below.
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.5</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.perf4j</groupId>
            <artifactId>perf4j</artifactId>
            <version>0.9.16</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.concur.puma.molva.aspects.TestTarget</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

Fix 

The default compliance level for aspectj-maven-plugin is 1.4 according to http://mojo.codehaus.org/aspectj-maven-plugin/compile-mojo.html#complianceLevel. Since I did not have that tag specified, the build was using the default value. Once I inserted the tag into the configuration, the build was successful.

Compile aspectj project containing Java 1.7 Source


Following maven configuration let’s you compile a project with Java 1.7 source.
<dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <!--<version>1.6.5</version>-->
            <version>1.8.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                    <complianceLevel>1.7</complianceLevel>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
                <executions>
                    <execution>
                        <!--<phase>process-sources</phase>-->
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Tuesday, September 23, 2014

Jmeter plugins for Apache Jmeter

I came across Jmeter-plugins project today and tried it out. It has a nice set of addons to support/complement existing functionality of Jmeter.

Thursday, March 27, 2014

Installing R on Mac OS X

1) Install Homebrew in your system.

2) Download and install XQuartz (Homebrew does not package XQuartz and it is needed for step 3. Therefore install XQuartz.)

3) Install Fortran and R.
heshans@15mbp-08077:/tmp$ brew update

heshans@15mbp-08077:/tmp$ brew tap homebrew/science

heshans@15mbp-08077:/tmp$ brew install gfortran r 

4) Verify the installation by running R.
heshans@15mbp-08077:/tmp$ R

R version 3.0.3 (2014-03-06) -- "Warm Puppy"
Copyright (C) 2014 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin13.1.0 (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

Tuesday, March 25, 2014

Custom Log Formatter

Following is the source for a custom log formatter.

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

public class CustomFormatter extends Formatter {

    private static final DateFormat df = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss.SSS");

    public String format(LogRecord record) {
        StringBuilder builder = new StringBuilder(1000);
        builder.append(df.format(new Date(record.getMillis()))).append(" - ");
        builder.append("[").append(record.getSourceClassName()).append(".");
        builder.append(record.getSourceMethodName()).append("] - ");
        builder.append("").append(record.getLevel()).append(" - ");
        builder.append(formatMessage(record));
        builder.append("\n");
        return builder.toString();
    }

    public String getHead(Handler h) {
        return super.getHead(h);
    }

    public String getTail(Handler h) {
        return super.getTail(h);
    }
}

Following is the way how the log messages will turn up in your log file.

25/03/2014 08:46:17.770 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread05 compositekey set time : 5 ms
25/03/2014 08:46:17.781 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread03 compositekey set time : 11 ms
25/03/2014 08:46:17.783 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread05 compositekey set time : 12 ms
25/03/2014 08:46:17.785 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread03 compositekey set time : 4 ms
25/03/2014 08:46:17.787 - [com.company.util.memcache.EntityThreadTask.setDataToMemcache] - INFO - thread05 compositekey set time : 4 ms