0

Here's MVCE https://github.com/yami12376/AspectJ

  1. Add VM arguments to Run/Debug configuration of Junit test, in my case:

    -javaagent:C:\aspectjWeaver\spring-instrument-3.0.4.jar

    -javaagent:C:\aspectjWeaver\aspectjweaver-1.6.11.jar

  2. In my case i added this in JAVA build path: \target\classes\META-INF from src/main/resources

  3. Run Junit test

If you delete aop.xml it's still weaving type org.*

but on the other hand aop.xml should not weave it beacuse it has: <include within="com.*"/> Why does it weave something other than com.* ?

Finally i want that MyAspect will be called when running Junit test based on @Around("execution(* *(..))")

As you can see now it is not getting called.

I've made my example based on https://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-aj-ltw-first-example

When running JUnit test i see this error:

http://wklej.org/id/3066582/

 [AppClassLoader@18b4aac2] warning parse definitions failed -- (NullPointerException) null
null
java.lang.NullPointerException
    at org.aspectj.weaver.loadtime.definition.DocumentParser.resolveEntity(DocumentParser.java:177)
    at org.apache.xerces.util.EntityResolverWrapper.resolveEntity(Unknown Source)
    at org.apache.xerces.impl.XMLEntityManager.resolveEntity(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentScannerImpl$DTDDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.aspectj.weaver.loadtime.definition.DocumentParser.saxParsing(DocumentParser.java:158)
    at org.aspectj.weaver.loadtime.definition.DocumentParser.parse(DocumentParser.java:123)
    at org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions(ClassLoaderWeavingAdaptor.java:272)
    at org.aspectj.weaver.loadtime.DefaultWeavingContext.getDefinitions(DefaultWeavingContext.java:130)
    at org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.initialize(ClassLoaderWeavingAdaptor.java:156)
    at org.aspectj.weaver.loadtime.Aj$ExplicitlyInitializedClassLoaderWeavingAdaptor.initialize(Aj.java:340)
    at org.aspectj.weaver.loadtime.Aj$ExplicitlyInitializedClassLoaderWeavingAdaptor.getWeavingAdaptor(Aj.java:345)
    at org.aspectj.weaver.loadtime.Aj$WeaverContainer.getWeaver(Aj.java:319)
    at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:113)
    at org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter.transform(ClassPreProcessorAgentAdapter.java:54)
    at sun.instrument.TransformerManager.transform(Unknown Source)
    at sun.instrument.InstrumentationImpl.transform(Unknown Source)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

I want to fix this error

Community
  • 1
  • 1
Kamil Witkowski
  • 1,978
  • 1
  • 19
  • 33
  • Why do you think you need spring-aspects library? It is not a Spring application, but pure Java. And why do you want to use load-time weaving? What is your reason to do so? It would be much easier to use AspectJ Maven plugin for compile-time weaving. Sorry for asking these questions, but before answering I want to understand. – kriegaex Mar 20 '17 at 15:56
  • One more thing: Your Maven build runs the JUnit test without load-time weaving, so why do you want to run it with LTW from the IDE? Then you are testing two different things depending on where you run the tests from, which is just bad test design. It does not make much sense. – kriegaex Mar 20 '17 at 15:58
  • " Then you are testing two different things depending where you run the tests from, which is just bad test design. It does not make much sense. " You are right - but this is the method i want to show you (check for myself) if my `aspect` gets called or not - nothing more. Still my `Junit test` have only `1 purpose` in general. "Why do you think you need spring-aspects library?" You are right as for this MVCE - i could delete it here. Still the `error` occurs. It does not matter if this dependency is here or not. – Kamil Witkowski Mar 20 '17 at 16:05
  • @kriegaex " And why do you want to use load-time weaving? What is your reason to do so? It would be much easier to use AspectJ Maven plugin for compile-time weaving." If i'm correct this gives me opportunity to check if my aspect works by `debbuging` using my `junit` test - and it is very comfortable for me. I do not want to compile my whole app to see if it's works. This is faster way. – Kamil Witkowski Mar 20 '17 at 16:06
  • 1
    This is illogical. No matter if you weave the code curing compile or load time, the result is the same. It has absolutely no influence on debuggability. Probably you do not fully understand what AOP means and specifically how to use AspectJ. If you want to check if aspects are being applied correctly, write unit or integration tests checking it automatically as part of your test suite, don't do it manually. Because then you have just the problem you describe: You never know how/if they are applied at all. Your build/test management approach is plain wrong and I will not support it. – kriegaex Mar 20 '17 at 16:16
  • If you want my support, let me help you fix your Maven build. If it works from Maven, the IDE (e.g. Eclipse or IntelliJ IDEA) will pick up the correct settings automatically when importing the Maven project. Do it the right way, won't you? – kriegaex Mar 20 '17 at 16:17
  • @kriegaex i just freshly downloaded project - imported it as `maven project` to `Eclipse` - and this error occured when running the `Junit test`. I am not sure what you want me to do. " Probably you do not fully understand what AOP means and specifically how to use AspectJ." Maybe you right - can you show me better solution? If "no matter if you weave the code curing compile or load time, the result is the same." Then i don't mind using one method or another. – Kamil Witkowski Mar 20 '17 at 16:24

1 Answers1

1

Well, you have several strange issues and errors in your project:

  1. Obviously your POJO application does not use Spring. So you can get rid of Spring dependencies and also of spring-instrument.jar on your command line. You also do not need core-context.xml.
  2. Xerces is also not needed as far as I can see.
  3. If you use aspectjweaver.jar as a dependency, aspectjrt.jar is superfluous because the former is a superset and thus contains the latter.
  4. In aop.xml there is a package name typo: Please use com.mkyong in the aspect name, not com.mykong. Otherwise the aspect will never be found.
  5. In your include within tag you should use .. syntax in order to in-/exclude also subpackages.
  6. Your aspect class is a total mess:

    • You use nested classes for no apparent reason.
    • You use @Around, but JoinPoint instead of ProceedingJoinPoint in the advice signature.
    • You use @Around, but never call proceed().

So how about this?

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mkyong</groupId>
  <artifactId>NumberGenerator</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>NumberGenerator</name>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.10</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.0</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

aop.xml:

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
  <aspects>
    <aspect name="com.mkyong.MyAspect"/>
  </aspects>
  <weaver options="-verbose -showWeaveInfo">
    <include within="com.mkyong..*"/>
    <exclude within="org.jibx*..*"/>
  </weaver>
</aspectj>

Aspect:

package com.mkyong;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class MyAspect {
  @Around("execution(!static * *(..))")
  public Object dontLogDuplicates(ProceedingJoinPoint thisJoinPoint) throws Throwable {
    System.out.println(thisJoinPoint);
    return thisJoinPoint.proceed();
  }
}

Console log:

I see the following when adding -javaagent:/path/to/aspectjweaver.jar to my JUnit run configuration in IntelliJ IDEA:

[AppClassLoader@18b4aac2] info AspectJ Weaver Version 1.8.10 built on Monday Dec 12, 2016 at 19:07:48 GMT
[AppClassLoader@18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader@18b4aac2
[AppClassLoader@18b4aac2] info using configuration /C:/Users/Alexander/Documents/java-src/yami12376-AspectJ/target/classes/META-INF/aop.xml
[AppClassLoader@18b4aac2] info register aspect com.mkyong.MyAspect
[AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(void com.mkyong.AppTest.testLengthOfTheUniqueKey())' in Type 'com.mkyong.AppTest' (AppTest.java:9) advised by around advice from 'com.mkyong.MyAspect' (MyAspect.java)
execution(void com.mkyong.AppTest.testLengthOfTheUniqueKey())
[AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(java.lang.String com.mkyong.App.generateUniqueKey())' in Type 'com.mkyong.App' (App.java:12) advised by around advice from 'com.mkyong.MyAspect' (MyAspect.java)
execution(String com.mkyong.App.generateUniqueKey())

But really, you should fix your POM and make sure that aspect weaving is done from there and not manually. It is really ugly like this.

Update: After all the criticism, let me also say one positive thing: You provided a MCVE, thanks for that. With code fragments, questions and answers we would never have found the many bugs in your files. So it was a smart and prudent decision to create the GitHub project. I could easily spot the problems. :-) If everyone did that, I would save a lot of time here.

kriegaex
  • 63,017
  • 15
  • 111
  • 202