I'm trying to make a simple app with Maven and AspectJ using LoadTime-Weaving.
I have an aspect which targets an annotation and calculates if the method's execution time was longer than expected. But when it gets to call getSLAAnnotation() to get the joinpoint method, it throws NullPointerException. It does return the joinpoint signature though. I beleive it might be related to the maven output I'm getting. \
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[ERROR] [AppClassLoader@18b4aac2] info AspectJ Weaver Version 1.9.7 built on Thursday Jun 24, 2021 at 16:14:45 PDT
[ERROR] [AppClassLoader@18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader@18b4aac2
[ERROR] [AppClassLoader@18b4aac2] info using configuration /D:/RFS/prueba-aspectj/target/classes/META-INF/aop-ajc.xml
[ERROR] [AppClassLoader@18b4aac2] info using configuration file:/C:/Users/MT27745023/.m2/repository/io/qameta/allure/allure-testng/2.17.2/allure-testng-2.17.2.jar!/META-INF/aop-ajc.xml
[ERROR] [AppClassLoader@18b4aac2] info register aspect aspectPackage.SLAAspect
[ERROR] [AppClassLoader@18b4aac2] info register aspect io.qameta.allure.aspects.StepsAspects
[ERROR] [AppClassLoader@18b4aac2] info register aspect io.qameta.allure.aspects.AttachmentsAspects
[INFO] Running TestSuite
[ERROR] [AppClassLoader@18b4aac2] info processing reweavable type page.StepTestPage: page\StepTestPage.java
[ERROR] [AppClassLoader@18b4aac2] info successfully verified type aspectPackage.SLAAspect exists. Originates from aspectPackage\SLAAspect.java
[ERROR] [AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(void page.StepTestPage.pruebaStepAspect())' in Type 'page.StepTestPage' (StepTestPage.java:11) advised by before advice from 'aspectPackage.SLAAspect' (SLAAspect.java)
[ERROR] [AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(void page.StepTestPage.pruebaStepAspect())' in Type 'page.StepTestPage' (StepTestPage.java:11) advised by after advice from 'aspectPackage.SLAAspect' (SLAAspect.java)
[ERROR] [AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(void page.StepTestPage.pruebaStepAspect())' in Type 'page.StepTestPage' (StepTestPage.java:11) advised by before advice from 'io.qameta.allure.aspects.StepsAspects' (StepsAspects.java)
[ERROR] [AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(void page.StepTestPage.pruebaStepAspect())' in Type 'page.StepTestPage' (StepTestPage.java:11) advised by afterThrowing advice from 'io.qameta.allure.aspects.StepsAspects' (StepsAspects.java)
[ERROR] [AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(void page.StepTestPage.pruebaStepAspect())' in Type 'page.StepTestPage' (StepTestPage.java:11) advised by afterReturning advice from 'io.qameta.allure.aspects.StepsAspects' (StepsAspects.java)
[ERROR] [AppClassLoader@18b4aac2] info processing reweavable type aspectPackage.SLAAspect: aspectPackage\SLAAspect.java
[ERROR] [AppClassLoader@18b4aac2] info successfully verified type aspectPackage.SLAAspect exists. Originates from aspectPackage\SLAAspect.java
The aspect:
package aspectPackage;
import java.lang.reflect.Method;
import env.EnvironmentConsumer;
import io.github.cdimascio.dotenv.Dotenv;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import java.time.LocalTime;
import java.time.temporal.Temporal;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@Aspect
public class SLAAspect{
private DateTimeFormatter ISODateTimeFormatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
private DateTimeFormatter DurationFormatter = java.time.format.DateTimeFormatter.ofPattern("HH:mm:ss");
ZonedDateTime dtFechaInicial;
SLA ca;
@Before("execution(* *(..)) && @annotation(aspectPackage.SLA)")
public void beforeTiempos(JoinPoint jp) {
System.out.println("BEFORE SLAASPECT");
ca = getSLAAnnotation(jp);
String fechaI = ZonedDateTime.now().format(ISODateTimeFormatter);
dtFechaInicial = ZonedDateTime.parse(fechaI, ISODateTimeFormatter);
}
@After("execution(* *(..)) && @annotation(aspectPackage.SLA)")
public void afterLogger(JoinPoint jp) throws Exception{
String fechaF = ZonedDateTime.now().format(ISODateTimeFormatter);
System.out.println("AFTER SLAASPECT");
ZonedDateTime dtFechaFinal = ZonedDateTime.parse(fechaF,ISODateTimeFormatter);
Duration tiempoTotal = calcularTiempoEntreFechas(dtFechaInicial,dtFechaFinal);
System.out.println(ca.toString());
System.out.println(ca.tiempoEsperado());
Duration sla = Duration.ofSeconds(ca.tiempoEsperado());
int resultSla = calcularSla (tiempoTotal, sla);
String resultadoFormateado = LocalTime.MIDNIGHT.plus(tiempoTotal).format(DurationFormatter);
Dotenv settings = null;
Duration timeout = null;
try{
settings = EnvironmentConsumer.getInstance("settings");
timeout = Duration.ofSeconds(Long.parseLong(settings.get("Timeout")));
}catch(Exception e){
System.out.println("\n\n\n\nERROR CON EL ENVIRONMENT\n\n\n\n");
throw e;
}
if(resultSla != 1 && tiempoTotal.compareTo(timeout) != 0){
throw new Exception("SLA Exception: Se excedió del tiempo esperado, el step duró: " resultadoFormateado " segundos");
}else{
throw new Exception("Step timeout");
}
}
private Duration calcularTiempoEntreFechas(Temporal fechaInicial, Temporal fechaFinal) {
// Calcula el tiempo final de ejecucion
return Duration.between(fechaInicial, fechaFinal);
}
private int calcularSla(Duration tiempoT, Duration tiempoE) {
// Calcula si tarda mas del tiempo esperados
// System.out.println(tiempoE.compareTo(tiempoT));
return tiempoE.compareTo(tiempoT);
}
private SLA getSLAAnnotation(JoinPoint joinPoint) {
SLA ca = null;
try {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Object target = joinPoint.getTarget();
Method method = target.getClass().
getMethod(signature.getMethod().getName(), signature.getMethod().getParameterTypes());
if (method.isAnnotationPresent(SLA.class)){
ca = method.getAnnotation(SLA.class);
}else if (joinPoint.getTarget().getClass().isAnnotationPresent(SLA.class)){
ca = joinPoint.getTarget().getClass().getAnnotation(SLA.class);
}
return ca;
}catch(Exception e) {
return ca;
}
}
}
This is the pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>ar.com.samsistemas</groupId>
<artifactId>aspectSLADemo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<aspectj.version>1.9.7</aspectj.version>
<allure-testng.version>2.17.2</allure-testng.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
</argLine>
<suiteXmlFiles>
<suiteXmlFile>./testng.xml</suiteXmlFile>
</suiteXmlFiles>
<useSystemClassLoader>true</useSystemClassLoader>
<forkMode>always</forkMode>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>${allure-testng.version}</version>
</dependency>
<dependency>
<groupId>ar.com.samsistemas</groupId>
<artifactId>web-utils</artifactId>
<version>0.0.1m</version>
</dependency>
<!-- Environment properties consumer from personal utils-->
<dependency>
<groupId>ar.com.samsistemas</groupId>
<artifactId>environment-utils</artifactId>
<version>0.0.1b</version>
</dependency>
</dependencies>
</project>
and the aop.xml
<aspectj>
<aspects>
<aspect name="aspectPackage.SLAAspect"/>
<weaver options="-verbose -showWeaveInfo">
<include within="*"/>
</weaver>
</aspects>
</aspectj>
CodePudding user response:
Preface
Sorry, this is going to be a lengthy answer, because there is so much wrong or problematic with your own aspect code, I could not resist to suggest how to fix it. But we are going to do that step by step.
How to ask good questions
Two dependencies in your POM are not publicly available, others like io.github.cdimascio:dotenv-java
are missing completely, or you are relying on them to be transitive dependencies of the non-public ones, which is a Maven anti-pattern. I fixed that locally, created missing classes like the SLA
annotation and EnvironmentConsumer
, added a .env
file containing a Timeout
variable and also a TestNG test. Now I can compile and run the project. All of this would have been your job. Because you are a newbie and I needed a puzzle with my morning tea, I did it for you this time. This was your free shot. Next time, please do that by yourself. Thank you.