简体   繁体   中英

Load time weaving in sample aspectJ project is not working

I am new to aspectJ. I am trying to implement load time weaving sample in aspectJ based on aop.xml but getting below error while building the project. I understand the problem is with aop.xml but could not solve it. Please help.

Error:

[URLClassLoader@132c2ad] warning parse definitions failed -- (SAXException) Unknown element while parsing <aspectj> element: pointcut
Unknown element while parsing <aspectj> element: pointcut
org.xml.sax.SAXException: Unknown element while parsing <aspectj> element: pointcut
at org.aspectj.weaver.loadtime.definition.DocumentParser.startElement(DocumentParser.java:224)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)

Project structure:

在此处输入图片说明

VM argument sent for load time weaving:

-javaagent:{JAR PATH}\aspectj-weaver.jar
Specification-Version: 1.6.8

Main.java

package main.java.aop.main;
import main.java.aop.sample.HelloWorld;
public class Main {
    public static void main(String[] args) {
        System.out.println("<---------- HELLO WORLD example ---------->");
        HelloWorld.say("hi");
        HelloWorld.sayToPerson("hello", "joe");
  }
 }

HelloWorld.java

package main.java.aop.sample;
 public class HelloWorld {
    public static void say(String message) {
        System.out.println("HelloWorld - message: " + message);
}
    public static void sayToPerson(String message, String name) {
        System.out.println("HelloWorld - name: " + name + ", message: " + message);
}
}

HelloWorldAspect:

 package main.java.aop.sample;
 public aspect HelloWorldAspect {
    protected pointcut helloWorld();
    before() : helloWorld() {
        System.out.println("Applying HelloWorldAspect - executing callBefore() - Good day!");
}
    after() : helloWorld() {
        System.out.println("Applying HelloWorldAspect - executing callAfter() - Thankyou!");
}
}

aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <aspect name="main.java.aop.sample.HelloWorldAspect">           
            <pointcut name="helloWorld" expression="execution(public static void HelloWorld.say*(..))"/>
        </aspect>
    </aspects>
</aspectj>

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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>TestAspectJXml</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>TestAspectJXml</name>
<dependencies>                            
<dependency>                    
<groupId>org.aspectj</groupId>    
<artifactId>aspectjrt</artifactId>
<version>1.8.2</version>          
</dependency>                         
</dependencies> 
<build>     
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>            
<artifactId>aspectj-maven-plugin</artifactId>        
<configuration>
<complianceLevel>1.6</complianceLevel>
<source>1.6</source>
<target>1.6</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>   
</plugin>
<plugin> 
<groupId>org.codehaus.mojo</groupId>         
<artifactId>exec-maven-plugin</artifactId>           
<executions>                                         
<execution>                                      
<goals>                                      
<goal>java</goal>                        
</goals>                                     
</execution>                                     
</executions>                                        
<configuration>                                      
<mainClass>main.java.aop.main.Main</mainClass>
</configuration>                                  
</plugin>
</plugins>

I'm ignoring the maven piece for now, there are some other issues we need to sort with the code. If we fix those, maybe the maven thing will work too.

XML is (typically) used to fill in pointcuts for abstract pointcuts in abstract aspects by defining a concrete aspect. You don't have an abstract aspect or abstract pointcut at the moment. An abstract pointcut is an indication to AspectJ that someone is going to 'fill it in later' (so similar to an abstract method - you can use it but your system will only work if someone provides an implementation). So we change the aspect to:

package main.java.aop.sample;
public abstract aspect HelloWorldAspect {
    protected abstract pointcut helloWorld();
    before() : helloWorld() {
        System.out.println("Applying HelloWorldAspect - executing callBefore() - Good day!");
    }
    after() : helloWorld() {
        System.out.println("Applying HelloWorldAspect - executing callAfter() - Thankyou!");
}
}

Notice that the pointcut is abstract and so the type declaration is also abstract (just like it would be if you had abstract methods).

Now we provide a concrete sub aspect in the XML, which needs to read like this:

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <concrete-aspect name="Foo" extends="main.java.aop.sample.HelloWorldAspect">
            <pointcut name="helloWorld" expression="execution(public static void *..HelloWorld.say*(..))"/>
        </concrete-aspect>
    </aspects>
</aspectj>

So instead of <aspect> I'm using <concrete-aspect> . <aspect> is for listing already 'complete' aspects that don't need further customization (like a pointcut filling in). The <aspect> tag does not support the <pointcut> sub-element but <concrete-aspect> does.

We could define the concrete aspect in code, like this:

aspect Foo extends HelloWorldAspect {
  pointcut helloWorld(): execution(public static void *..HelloWorld.say*(..));
}

But you want to take advantage of defining it in XML, that's fine too - I just provided it for comparison. So the XML is saying "This aspect is a concrete version of the HelloWorldAspect and the pointcut to be used is my execution pointcut".

Note also that I changed the execution pointcut. It previously read HelloWorld.say* - I changed it to *..HelloWorld.say* because HelloWorld is in a package.

With those changes, when I now run it:

<---------- HELLO WORLD example ---------->
Applying HelloWorldAspect - executing callBefore() - Good day!
HelloWorld - message: hi
Applying HelloWorldAspect - executing callAfter() - Thankyou!
Applying HelloWorldAspect - executing callBefore() - Good day!
HelloWorld - name: joe, message: hello
Applying HelloWorldAspect - executing callAfter() - Thankyou!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM