The following example shows how to test multithreaded, concurrent Java with VMLens:
import com.vmlens.api.AllInterleavings;
public class TestNonVolatileField {
private int j = 0;
@Test
public void testUpdate() throws InterruptedException {
try(AllInterleavings allInterleavings = new AllInterleavings("testNonVolatileField")) {
while (allInterleavings.hasNext()) {
Thread first = new Thread() {
@Override
public void run() {
j++;
}
};
first.start();
j++;
first.join();
}
}
}
}VMLens detects the data race and generates the following report:
See test-vmlens-maven-plugin for more examples.
To use vmlens with Maven, configure a plugin tag to tell Maven that the vmlens plugin should be executed at the test phase. And include the jar com.vmlens.api as test dependency.
<project>
<!-- to include the class AllInterleavings into the test class path. -->
<dependency>
<groupId>com.vmlens</groupId>
<artifactId>api</artifactId>
<version>1.2.26</version>
<scope>test</scope>
</dependency>
<build>
<plugins>
<!-- to run the vmlens maven plugin during the maven test phase -->
<plugin>
<groupId>com.vmlens</groupId>
<artifactId>vmlens-maven-plugin</artifactId>
<version>1.2.26</version>
<executions>
<execution>
<id>test</id>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
...
</project>See pom.xml for an example.
To use VMLens with Gradle add the java agent as vm parameter for the test and process the events after the test run to create the VMLens Report:
import com.vmlens.gradle.VMLens
plugins {
...
}
repositories {
mavenCentral()
}
dependencies {
testImplementation("com.vmlens:api:1.2.26")
...
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("com.vmlens:standalone:1.2.26")
}
}
tasks.register("vmlensReport") {
doLast {
VMLens().process(layout.buildDirectory.getAsFile().get());
}
}
tasks.test {
doFirst{
jvmArgs(VMLens().setup(layout.buildDirectory.getAsFile().get()))
}
// VMLens currently does not work with jacoco
jvmArgumentProviders.removeIf { it::class.java.simpleName == "JacocoAgent" }
useJUnitPlatform()
finalizedBy("vmlensReport")
}See build.gradle.kts for an example.
To use VMLens as a standalone tool:
- Include com.vmlens.api from the Maven Repository as a test jar in your project.
- Download the jar standalone-1.2.26.jar from the Maven Repository
- Run java -jar standalone-1.2.26.jar install. This creates the agent directory and prints the vm parameter to System.out
- Add this vm parameter when you run your test
- Run java -jar standalone-1.2.26.jar report. This checks for data races and creates the report
VMLens runs with JDK 9 to 25
Read the documentation here.
Contact me at thomas.krieger@vmlens.com