We encountered a case where a jtreg test would successfully build but fail at runtime with ClassNotFoundException.
If you look at test/jdk/java/net/httpclient/whitebox/Driver.java
it's not obvious that the test classes are being compiled as system module patches. Looking at http://openjdk.java.net/jtreg/tag-spec.html it seems like there should be an @compile with /module=jdk.incubator.httpclient
Perhaps the @run with an existing module spec is implicitly asking for the given classes to be compiled and patched into the system module?
Anyways, on to the real bug ... If you apply this demo patch:
diff --git a/test/jdk/java/net/httpclient/whitebox/Driver.java b/test/jdk/java/net/httpclient/whitebox/Driver.java
--- a/test/jdk/java/net/httpclient/whitebox/Driver.java
+++ b/test/jdk/java/net/httpclient/whitebox/Driver.java
@@ -24,6 +24,8 @@
/*
* @test
* @bug 8151299 8164704 8187044
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.ProcessTools
* @modules jdk.incubator.httpclient java.management
* @run testng jdk.incubator.httpclient/jdk.incubator.http.SelectorTest
* @run testng jdk.incubator.httpclient/jdk.incubator.http.RawChannelTest
diff --git a/test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/RawChannelTest.java b/test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/RawChannelTest.java
--- a/test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/RawChannelTest.java
+++ b/test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/RawChannelTest.java
@@ -78,6 +78,7 @@
@Test
public void test() throws Exception {
+ Class k = jdk.testlibrary.ProcessTools.class;
try (ServerSocket server = new ServerSocket(0)) {
int port = server.getLocalPort();
new TestServer(server).start();
you will see that it builds, but then can't find the library class ProcessTools at runtime.
What seems to be happening is that the test classes are compiled with a classpath containing the @library classes, but at runtime they are patched into a system module, therefore get the platform classloader, and so do not find classes on the classpath. Which should never happen, because jtreg takes control of the compile and runtime environments.
If you look at test/jdk/java/net/httpclient/whitebox/Driver.java
it's not obvious that the test classes are being compiled as system module patches. Looking at http://openjdk.java.net/jtreg/tag-spec.html it seems like there should be an @compile with /module=jdk.incubator.httpclient
Perhaps the @run with an existing module spec is implicitly asking for the given classes to be compiled and patched into the system module?
Anyways, on to the real bug ... If you apply this demo patch:
diff --git a/test/jdk/java/net/httpclient/whitebox/Driver.java b/test/jdk/java/net/httpclient/whitebox/Driver.java
--- a/test/jdk/java/net/httpclient/whitebox/Driver.java
+++ b/test/jdk/java/net/httpclient/whitebox/Driver.java
@@ -24,6 +24,8 @@
/*
* @test
* @bug 8151299 8164704 8187044
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.ProcessTools
* @modules jdk.incubator.httpclient java.management
* @run testng jdk.incubator.httpclient/jdk.incubator.http.SelectorTest
* @run testng jdk.incubator.httpclient/jdk.incubator.http.RawChannelTest
diff --git a/test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/RawChannelTest.java b/test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/RawChannelTest.java
--- a/test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/RawChannelTest.java
+++ b/test/jdk/java/net/httpclient/whitebox/jdk.incubator.httpclient/jdk/incubator/http/RawChannelTest.java
@@ -78,6 +78,7 @@
@Test
public void test() throws Exception {
+ Class k = jdk.testlibrary.ProcessTools.class;
try (ServerSocket server = new ServerSocket(0)) {
int port = server.getLocalPort();
new TestServer(server).start();
you will see that it builds, but then can't find the library class ProcessTools at runtime.
What seems to be happening is that the test classes are compiled with a classpath containing the @library classes, but at runtime they are patched into a system module, therefore get the platform classloader, and so do not find classes on the classpath. Which should never happen, because jtreg takes control of the compile and runtime environments.