I am doing junit testing for my project that involves javafx and I encountered this issue:
Exception in thread "main" java.lang.IllegalAccessError: class org.junit.platform.engine.UniqueId (in unnamed module #0x67424e82) cannot access class org.junit.platform.commons.util.Preconditions (in module org.junit.platform.commons) because module org.junit.platform.commons does not export org.junit.platform.commons.util to unnamed module #0x67424e82
at org.junit.platform.engine.UniqueId.forEngine(UniqueId.java:67)
at com.intellij.junit5.JUnit5IdeaTestRunner.<clinit>(JUnit5IdeaTestRunner.java:86)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:375)
at com.intellij.rt.junit.JUnitStarter.getAgentClass(JUnitStarter.java:244)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:225)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Process finished with exit code 1
I keep searching up on StackOverflow and found something similar to the issue I'm having but it only deals with illegal access to main methods instead of junit testing: Two java files. Getting IllegalAccessError when running class with main method trying to access a method from the other file.
This is my pom.xml file
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>proj4</artifactId>
<version>1.0-SNAPSHOT</version>
<name>proj4</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.7.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17-ea+11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17-ea+11</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.example.proj4/application.proj4.PizzeriaApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
This is my test class
package application.proj4;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.*;
class PizzaTest {
#Test
void price()
{
ArrayList<Topping> n1 = new ArrayList<Topping>();
Deluxe d1 = new Deluxe(Size.Small,n1);
assertEquals(12.99, d1);
} }
Related
JUnit 5 does not invoke my method in a test class that is annotated with the #BeforeEach annotation, where I initialize some fields of the test object that are needed in the tests. When trying to access these fields inside a test method (method annotated with #Test) I obviously get a NullpointerException. So I added some output messages to the methods.
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class TestClass {
private String s;
public TestClass() {
}
#BeforeEach
public void init() {
System.out.println("before");
s = "not null";
}
#Test
public void test0() {
System.out.println("testing");
assertEquals("not null", s.toString());
}
}
In the output of the tests when running mvn clean test I get the "testing" message from the test0() method annotated with #Test annotation, but the "before" message is not printed.
Running de.dk.spielwiese.TestClass
!!!testing!!!
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0 sec <<< FAILURE!
de.dk.spielwiese.TestClass.test0() Time elapsed: 0 sec <<< FAILURE!
java.lang.NullPointerException
at de.dk.spielwiese.TestClass.test0(TestClass.java:24)
The very obvious and only reason that I can think of is that the init() method is not invoked. The documentation of #BeforeEach says
#BeforeEach is used to signal that the annotated method should be
executed before each #Test, #RepeatedTest, #ParameterizedTest,
#TestFactory, and #TestTemplate method in the current test class.
I also tried running the tests in eclipse and there they always pass without any errors.
I am using maven 3.5.3.
I declared JUnit Jupiter 5.1.0 as dependency in my 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>de.dk</groupId>
<artifactId>spielwiese</artifactId>
<version>0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spielwiese</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>de.dk.spielwiese.Spielwiese</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<finalName>Spielwiese</finalName>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>de.dk</groupId>
<artifactId>util</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Why is my init() method not invoked?
In my case the problem was that the #Test annotation was taken from wrong import.
Originally it was imported from org.junit.Test.
Once I have switched it to org.junit.jupiter.api.Test the problem was resolved.
Wrong original code:
import org.junit.Test;
#BeforeEach
...some code
#Test
...some code
Correct fixed code:
import org.junit.jupiter.api.Test;
#BeforeEach
...some code
#Test
...some code
Your init() method is not invoked because you have not instructed Maven Surefire to use the JUnit Platform Surefire Provider.
Thus, surprisingly your test is not even being run with JUnit. Instead, it is being run with Maven Surefire's support for what they call POJO Tests.
Adding the following to your pom.xml should solve the problem.
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Nowadays it is not necessary to add provider to plugin. Just add junit-jupiter-engine to your dependencies (as written in official documentation https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit-platform.html).
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
I Faced the same issue for my gradle project.
Noticed that, #Test annotation using wrong package (org.junit.Test) and the issue fixed after using correct package (org.junit.jupiter.api.Test)
There is junit-jupiter-api dependency missing
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
</plugins>
In my case the problem was that I overwrote a method annotated with #BeforeEach in a subclass of the test, so the super methode was not called.
In order for Maven to execute tests properly with #BeforeEach you have to have your project correctly configured via pom.xml
Your project's pom.xml must contain these parts:
dependencyManagement with Junit BOM
dependency with Junit Jupiter
plugin with Maven Surefire Plugin
This is documented officially here and the official project examples are here.
Here is a link to the example project's pom.xml.
Here is the example project's pom.xml for your convenience:
<?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>com.example</groupId>
<artifactId>junit5-jupiter-starter-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.7.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
</project>
Sam Brannen's answer worked for me, but it seems that it doesn't work with the 2.22.0 version of maven-surefire-plugin unless you upgrade the junit-platform-surefire-provider to 1.2.0. Be aware!
I'm trying to use google text to speech but there is a problem with the imports:
import com.google.cloud.texttospeech.v1beta1.AudioConfig;
import com.google.cloud.texttospeech.v1beta1.AudioEncoding;
import com.google.cloud.texttospeech.v1beta1.SsmlVoiceGender;
import com.google.cloud.texttospeech.v1beta1.SynthesisInput;
import com.google.cloud.texttospeech.v1beta1.SynthesizeSpeechResponse;
import com.google.cloud.texttospeech.v1beta1.TextToSpeechClient;
import com.google.cloud.texttospeech.v1beta1.VoiceSelectionParams;
It shows various errors where it's using the same modules from different packages:
java: module google.cloud.texttospeech reads package com.google.cloud.texttospeech.v1beta1 from both google.cloud.texttospeech and proto.google.cloud.texttospeech.v1beta1
I have these requirements in my module-info file:
requires proto.google.cloud.texttospeech.v1beta1;
requires google.cloud.texttospeech;
I also get a yellow warning with these requirements:
Name of automatic module 'proto.google.cloud.texttospeech.v1beta1' is unstable, it is derived from the module's file name.
pom.xml is as follows (removed project tag for clarity):
<modelVersion>4.0.0</modelVersion>
<groupId>com.cloze</groupId>
<artifactId>cloze</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>26.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>18.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>18.0.1</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-texttospeech</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<!-- Default configuration for running -->
<!-- Usage: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.cloze.App</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Contact the maintainers of the google-cloud-texttospeech library and ask them to provide documentation (and perhaps an updated implementation) for using their library from a modular Java app.
In the meantime go to openjfx.io and review documentation on non-modular JavaFX apps and try following it.
Asker writes:
If I remove the module-info file to make it non modular that does indeed solve this problem.
I am developing a project with Maven for the first time. I have an external package that I have converted into a .jar file and installed into maven in order to use its classes. However, even tho the package is already in the .m2 folder maven still says that it cannot find the package(util):
[ERROR]/home/luis/Desktop/git/sifu/Challenges/Java/java_0002_SN/stringNorm/src/main/java/stringNorm/MyDetector.java:[14,27] cannot find symbol
symbol: class report
location: class stringNorm.MyDetector
[ERROR]/home/luis/Desktop/git/sifu/Challenges/Java/java_0002_SN/stringNorm/src/main/java/stringNorm/MyDetector.java:[9,1] package util does not exist
[ERROR]/home/luis/Desktop/git/sifu/Challenges/Java/java_0002_SN/stringNorm/src/main/java/stringNorm/MyDetector.java:[19,23] cannot find symbol
symbol: class report
location: class stringNorm.MyDetector
I have already tried to add this new dependency(util) to the pom file and so far it looks like this:
<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.sifu</groupId>
<artifactId>stringNorm</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spotBugsVersion>4.0.0</spotBugsVersion>
</properties>
<description>My SpotBugs plugin project</description>
<dependencies>
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs</artifactId>
<version>${spotBugsVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>util</groupId>
<artifactId>util</artifactId>
<version>1.0.0</version>
<scope>system</scope>
</dependency>
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>test-harness</artifactId>
<version>${spotBugsVersion}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0.2</version>
<executions>
<execution>
<id>validate-spotbugs-configuration</id>
<goals>
<goal>validate</goal>
</goals>
<configuration>
<validationSets>
<validationSet>
<dir>src/main/resources</dir>
<includes>
<include>findbugs.xml</include>
</includes>
<systemId>findbugsplugin.xsd</systemId>
</validationSet>
<validationSet>
<dir>src/main/resources</dir>
<includes>
<include>messages.xml</include>
</includes>
<systemId>messagecollection.xsd</systemId>
</validationSet>
</validationSets>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs</artifactId>
<version>${spotBugsVersion}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
I am using spotbugs to perform analysis on my code, as you can see from the snipet.
The class within the unit package I want to use, is the report one, my import statement looks like this `import util.*;
I installed my jar file to maven using this command: mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>
and after doing it I added it into the pom file.
My util package is composed of 3 classes, I did jar cfv util.jar * inside the util folder and gave me a jar file.
I am trying to create custom loadtime annotations with AspectJ, Open JDK11 without Spring Context. It works fine within a module and annotations are weaving at class load time and aspects are executing at runtime. No issues, But when aspectJ implemented module added as a dependency on another module. AspectJ and annotations are not processing. Am I missing any configuration?
module-a
#Documented
#Inherited
#Target(METHOD)
#Retention(RUNTIME)
public #interface Counter {
String name() default "";
}
#Aspect
public class CounterAspect {
#Around("execution(* *.*(..)) && #annotation(counter)")
public void myBeforeLogger(ProceedingJoinPoint joinPoint, Counter counter) {
System.out.println("Okay - we're in the before handler...");
System.out.println("The test annotation value is: " + counter.name().toString());
}
resources/META-INF/aop.xml
<aspectj>
<aspects>
<aspect name="CounterAspect"/>
</aspects>
<weaver options="-verbose">
<!-- weave anything -->
<include within="*" />
</weaver>
</aspectj>
pom.xml
<properties>
<aspectj.version>1.9.4</aspectj.version>
</properties>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.11</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
module-b
pom.xml
<dependency>
<groupId>org.mymodule</groupId>
<artifactId>module-a</artifactId>
<version>1.0.0</version>
</dependency>
public class MyCounter {
#Counter(name="call_count")
public void count() {}
}
public class MyCounterTest {
#Test
public void testCount() {
MyCounter counter = new MyCounter();
counter.count();
//NOTE: I expect CounterAspect from module-a should be intercepted. It is not working!!!! There is no aspectJ class loading verbose in console.
}
}
I suggest you create a parent POM with some predefined properties, dependency versions and plugin configurations. Your two sub-modules (one for application + test, one for aspect) can use these definitions, which leads to shorter sub-module POMs:
<?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>de.scrum-master</groupId>
<artifactId>aspectj-ltw-test-multi-module</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.source-target.version>11</java.source-target.version>
<aspectj.version>1.9.4</aspectj.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${java.source-target.version}</source>
<target>${java.source-target.version}</target>
<!-- IMPORTANT -->
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
<plugin>
<groupId>com.nickwongdev</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.12.1</version>
<configuration>
<!--<showWeaveInfo>true</showWeaveInfo>-->
<source>${java.source-target.version}</source>
<target>${java.source-target.version}</target>
<Xlint>ignore</Xlint>
<complianceLevel>${java.source-target.version}</complianceLevel>
<encoding>${project.build.sourceEncoding}</encoding>
<!--<verbose>true</verbose>-->
<!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn>-->
</configuration>
<executions>
<execution>
<!-- IMPORTANT -->
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>de.scrum-master</groupId>
<artifactId>aspect</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>aspect</module>
<module>application</module>
</modules>
</project>
Please note that I am not using the original AspectJ Maven plugin but a fork which supports Java 11. The original still lags behind. As you said you want to use Java 11, you have to do that. With Java 8 you can use the original plugin.
Aspect module:
<?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>
<parent>
<groupId>de.scrum-master</groupId>
<artifactId>aspectj-ltw-test-multi-module</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>de.scrum-master</groupId>
<artifactId>aspect</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>com.nickwongdev</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
</dependencies>
</project>
<aspectj>
<aspects>
<aspect name="de.scrum_master.aspect.CounterAspect"/>
</aspects>
<weaver options="-verbose">
<!-- weave anything -->
<include within="*"/>
</weaver>
</aspectj>
package de.scrum_master.aspect;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
#Documented
#Inherited
#Target(METHOD)
#Retention(RUNTIME)
public #interface Counter {
String name() default "";
}
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
#Aspect
public class CounterAspect {
#Around("execution(* *.*(..)) && #annotation(counter)")
public void myBeforeLogger(ProceedingJoinPoint joinPoint, Counter counter) {
System.out.println(joinPoint + " -> " + counter.name());
}
}
Application module:
<?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>
<parent>
<groupId>de.scrum-master</groupId>
<artifactId>aspectj-ltw-test-multi-module</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>de.scrum-master</groupId>
<artifactId>application</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>de.scrum-master</groupId>
<artifactId>aspect</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>
package de.scrum_master.app;
import de.scrum_master.aspect.Counter;
public class MyCounter {
#Counter(name = "call_count")
public void count() {}
}
package de.scrum_master.app;
import org.junit.Test;
public class MyCounterTest {
#Test
public void testCount() {
new MyCounter().count();
}
}
Now if you run mvn clean verify or just mvn clean test you will get the following console log for the application module test:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
[AppClassLoader#2aae9190] info AspectJ Weaver Version 1.9.4 built on Friday May 10, 2019 at 08:43:10 PDT
[AppClassLoader#2aae9190] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader#2aae9190
[AppClassLoader#2aae9190] info using configuration (...)/SO_AJ_LTWTestMultiModule_56397605/aspect/target/classes/META-INF/aop.xml
[AppClassLoader#2aae9190] info register aspect de.scrum_master.aspect.CounterAspect
[IsolatedClassLoader#74e52ef6] info AspectJ Weaver Version 1.9.4 built on Friday May 10, 2019 at 08:43:10 PDT
[IsolatedClassLoader#74e52ef6] info register classloader org.apache.maven.surefire.booter.IsolatedClassLoader#74e52ef6
[IsolatedClassLoader#74e52ef6] info using configuration (...)/SO_AJ_LTWTestMultiModule_56397605/aspect/target/classes/META-INF/aop.xml
[IsolatedClassLoader#74e52ef6] info register aspect de.scrum_master.aspect.CounterAspect
Running de.scrum_master.app.MyCounterTest
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access using Lookup on org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor (file:/(...)/.m2/repository/org/aspectj/aspectjweaver/1.9.4/aspectjweaver-1.9.4.jar) to class java.lang.ClassLoader
WARNING: Please consider reporting this to the maintainers of org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[AppClassLoader#2aae9190] info processing reweavable type de.scrum_master.aspect.CounterAspect: de\scrum_master\aspect\CounterAspect.aj
[AppClassLoader#2aae9190] info successfully verified type de.scrum_master.aspect.CounterAspect exists. Originates from de\scrum_master\aspect\CounterAspect.aj
execution(void de.scrum_master.app.MyCounter.count()) -> call_count
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.885 sec
Please especially note
execution(void de.scrum_master.app.MyCounter.count()) -> call_count
This is what you want, the load-time-woven aspect kicks in for your test.
Update: I created a GitHub repository for you. You can just clone it instead of copying all my code snippets from this answer.
JUnit 5 does not invoke my method in a test class that is annotated with the #BeforeEach annotation, where I initialize some fields of the test object that are needed in the tests. When trying to access these fields inside a test method (method annotated with #Test) I obviously get a NullpointerException. So I added some output messages to the methods.
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class TestClass {
private String s;
public TestClass() {
}
#BeforeEach
public void init() {
System.out.println("before");
s = "not null";
}
#Test
public void test0() {
System.out.println("testing");
assertEquals("not null", s.toString());
}
}
In the output of the tests when running mvn clean test I get the "testing" message from the test0() method annotated with #Test annotation, but the "before" message is not printed.
Running de.dk.spielwiese.TestClass
!!!testing!!!
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0 sec <<< FAILURE!
de.dk.spielwiese.TestClass.test0() Time elapsed: 0 sec <<< FAILURE!
java.lang.NullPointerException
at de.dk.spielwiese.TestClass.test0(TestClass.java:24)
The very obvious and only reason that I can think of is that the init() method is not invoked. The documentation of #BeforeEach says
#BeforeEach is used to signal that the annotated method should be
executed before each #Test, #RepeatedTest, #ParameterizedTest,
#TestFactory, and #TestTemplate method in the current test class.
I also tried running the tests in eclipse and there they always pass without any errors.
I am using maven 3.5.3.
I declared JUnit Jupiter 5.1.0 as dependency in my 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>de.dk</groupId>
<artifactId>spielwiese</artifactId>
<version>0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spielwiese</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>de.dk.spielwiese.Spielwiese</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<finalName>Spielwiese</finalName>
</configuration>
<executions>
<execution>
<id>assemble-all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>de.dk</groupId>
<artifactId>util</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Why is my init() method not invoked?
In my case the problem was that the #Test annotation was taken from wrong import.
Originally it was imported from org.junit.Test.
Once I have switched it to org.junit.jupiter.api.Test the problem was resolved.
Wrong original code:
import org.junit.Test;
#BeforeEach
...some code
#Test
...some code
Correct fixed code:
import org.junit.jupiter.api.Test;
#BeforeEach
...some code
#Test
...some code
Your init() method is not invoked because you have not instructed Maven Surefire to use the JUnit Platform Surefire Provider.
Thus, surprisingly your test is not even being run with JUnit. Instead, it is being run with Maven Surefire's support for what they call POJO Tests.
Adding the following to your pom.xml should solve the problem.
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Nowadays it is not necessary to add provider to plugin. Just add junit-jupiter-engine to your dependencies (as written in official documentation https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit-platform.html).
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
I Faced the same issue for my gradle project.
Noticed that, #Test annotation using wrong package (org.junit.Test) and the issue fixed after using correct package (org.junit.jupiter.api.Test)
There is junit-jupiter-api dependency missing
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
</plugins>
In my case the problem was that I overwrote a method annotated with #BeforeEach in a subclass of the test, so the super methode was not called.
In order for Maven to execute tests properly with #BeforeEach you have to have your project correctly configured via pom.xml
Your project's pom.xml must contain these parts:
dependencyManagement with Junit BOM
dependency with Junit Jupiter
plugin with Maven Surefire Plugin
This is documented officially here and the official project examples are here.
Here is a link to the example project's pom.xml.
Here is the example project's pom.xml for your convenience:
<?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>com.example</groupId>
<artifactId>junit5-jupiter-starter-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.7.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
</project>
Sam Brannen's answer worked for me, but it seems that it doesn't work with the 2.22.0 version of maven-surefire-plugin unless you upgrade the junit-platform-surefire-provider to 1.2.0. Be aware!