Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Load time weaving with maven and surefire fails

Hi all,

I figured it out. But got a different error when running 'mvn site' :-(

Using 'mvn -X test' reveiled where the 'null' came from. It came from '${debug}' in the surefire argline configuration. Removing it from the configuration made my test work again.

However running 'mvn site' to see the results in coverage reports resulted in the following output:

    ...
    [INFO] [aspectj:test-compile {execution: default}]
    [ERROR] ABORT
    12-feb-2011 22:41:00 org.aspectj.weaver.tools.Jdk14Trace info
    INFO: Dumping to <my project>\.\ajcore.20110212.224100.428.txt
[INFO] ------------------------------------------------------------------------
    [ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
    [INFO] Compiler errors:
abort ABORT -- (RuntimeException) Problem processing attributes in <my project\aspects\RequestProcessorMonitor.class Problem processing attributes in <my project>\aspects\RequestProcessorMonitor.class java.lang.RuntimeException: Problem processing attributes in <my project>\aspects\RequestProcessorMonitor.class at org.aspectj.weaver.bcel.BcelObjectType.ensureAspectJAttributesUnpacked(BcelObjectType.java:383) at org.aspectj.weaver.bcel.BcelObjectType.<init>(BcelObjectType.java:160) at org.aspectj.weaver.bcel.BcelWorld.buildBcelDelegate(BcelWorld.java:394)
            ...
Caused by: java.lang.ClassCastException: org.aspectj.apache.bcel.classfile.ConstantString cannot be cast to org.aspectj.apache.bcel.classfile.ConstantUtf8 at org.aspectj.apache.bcel.classfile.ConstantPool.getConstantUtf8(ConstantPool.java:223) at org.aspectj.weaver.bcel.BcelConstantPoolReader.readUtf8(BcelConstantPoolReader.java:31) at org.aspectj.weaver.VersionedDataInputStream.readUtf8(VersionedDataInputStream.java:61) at org.aspectj.weaver.VersionedDataInputStream.readSignatureAsUnresolvedType(VersionedDataInputStream.java:81)
            ...

The strange thing this is that the error happens on a completely different aspect and it does not show up when using 'mvn clean install'.

Any ideas what is causing this?

Regards,

misl

BTW, I am an AOP newby. So any improvements are welcome.


Op 12-2-2011 22:33, Minto van der sluis schreef:
Hi folks,

Following the guidelines from the link below, I am using load time weaving in for my unit test.

[1] http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg09286.html

Unfortunately this results in the following error message :-(

[INFO] Surefire report directory: <source-path>\target\surefire-reports
java.lang.NoClassDefFoundError: null
Caused by: java.lang.ClassNotFoundException: null
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: null.  Program will exit.
Exception in thread "main"

Anyone a clue?

Let me explain what I am trying to achieve. I want to increase code overage for my utility classes (private constructor). See also:

http://stackoverflow.com/questions/4520216/how-to-add-test-coverage-to-a-private-constructor

There are 2 straight forward ways to achieve this:
1) Add a testcase and use reflection instantiate the private constructor (described in previouse link). 2) Add a static section to my utility class and instantiate the class there, like:
        static {
            new MyClass();
        }

The first is rejected because I need to do this for every utility class and the test is just for the sake of increasing coverage, not for testing functionality. The second one I reject because it polutes my code for the sake of code coverage.

I came up

I came up with a solution which is more appealing to me. Creating an Aspect to achieve the same thing as solution 2. However I do not like this Aspect to be part of my actual code. So I decided to use load time weaving during unit testing. This way the additional coverage only shows up on test utility classes.

How did I do this. First of all, here's the actual aspect:

        package <my aspect package>.aspects;

        import java.lang.reflect.Constructor;
        import java.lang.reflect.Modifier;

        /**
* Special aspect to increase code coverage on classes with private
         * constructors.
         *
         * @author Minto van der Sluis
         */
        public aspect PrivateConstructorCoverage {

// Joinpoint for static initialization blocks of all classes in the
            // populators package.
pointcut staticInit() : staticinitialization(<my utility class package>.populators..*);

            before(): staticInit() {
// Determine the class on which this advice is currently working. Class<?> clazz = thisJoinPoint.getSignature().getDeclaringType();
                Constructor<?> constructor = null;
                try {
                    // Use reflection to get to the default constructor.
                    constructor = clazz.getDeclaredConstructor();
                } catch( NoSuchMethodException e ) {
System.out.println( "Missing default constructor for: " + clazz.getName() );
                }

// Only instantiate the class if a private default constructor exists. if ( constructor != null && Modifier.isPrivate( constructor.getModifiers() )) {
                    constructor.setAccessible(true);
                    try {
System.out.println( "Increasing coverage by calling: new " + clazz.getSimpleName() + "()" );
                        constructor.newInstance();
                    } catch (Exception e) {
                        // Instantiating failed
System.out.println( "Instantiation failed due to: " + e.getMessage() );
                    }
                }
            }
        }

This aspect is included in 'src/test/java'. For the sake of load time weaving I added the following aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE aspectj PUBLIC "//AspectJ/" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd";>
<aspectj>
<weaver options="-verbose">
<include within="<my package>.populators..*"/>
<exclude within="<my package>.populators..*Test"/>
</weaver>

<aspects>
<aspect name="<my aspect package>.PrivateConstructorCoverage"/>
</aspects>
</aspectj>

I also made a small change to the surefire configuration (see [1]). Instead of pointing to a locally installed version of the aspectjweaver (${basedir}/../lib/). I changed the surefire configuration to point to the one in my local maven repository. To make sure aspectjweaver is actually in my local repository, I added a dependency to it in my pom file with scope provided.

<argLine>-javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar ${debug}</argLine>

Unfortunately due to non disclosure I had to erease a few references to my currect project. In these places I used the following placeholders:
<my package>
<my aspect package>

Does anyone know why surefire won't start?

Regards,

misl



--
ir. ing. Minto van der Sluis
Xup BV

Mobiel: +31 (0) 626 014541



Back to the top