On Wed, 7 Aug 2024 08:31:35 GMT, Jaikiran Pai <j...@openjdk.org> wrote:

>> I see that the `NoClassDefFoundError` failure that you are mentioning is 
>> actually being reported even in the GitHub Actions job failures. It does 
>> look odd (although might be a pre-known jtreg issue). It will need a bit of 
>> investigation to see what's going on.
>
> I was able to reproduce this `NoClassDefFoundError` in this new test locally. 
> I will take a look to see if I can figure out what's going on.

I looked into this locally and this is a (known) bug in jtreg 
https://bugs.openjdk.org/browse/CODETOOLS-7902847.

What's happening here is that the tests are launched using make test 
TEST=test/hotspot/jtreg/:tier1_serviceability. One of those tests is the 
(pre-existing unrelated to this PR) AgentWithVThreadTest. That test has a 
`@compile AgentWithVThread.java AgentWithVThreadTest.java`. This triggers 
compilation of those classes and also any referenced classes in those 2 
classes. One such class happens to be the test library's jdk.test.lib.Utils. 
This is a test library class (used/referenced indirectly in that test). jtreg 
ends up issuing a javac command with destination directory as the 
AgentWithVThreadTest's test specific work directory:


-d 
build/macosx-aarch64/test-support/jtreg_test_hotspot_jtreg_tier1_serviceability/classes/0/serviceability/jvmti/vthread/premain/AgentWithVThreadTest.d


So the `jdk.test.lib.Utils.class` (along with other classes) file ends up being 
compiled to 
`build/macosx-aarch64/test-support/jtreg_test_hotspot_jtreg_tier1_serviceability/classes/0/serviceability/jvmti/vthread/premain/AgentWithVThreadTest.d/jdk/test/lib/Utils.class`.
 During this compilation, the `jdk.test.lib.util.JavaAgentBuilder` doesn't get 
compiled because that class isn't referenced by AgentWithVThreadTest (neither 
directly or indirectly).

Then during the same test execution, jtreg notices a `@run` statement:


@run driver jdk.test.lib.util.JavaAgentBuilder ....


And to launch that run action, it first builds and compiles the 
jdk.test.lib.util.JavaAgentBuilder and since this is a test library class, 
jtreg ends up launching `javac` with a destination directory which is 
common/shared by multiple tests:


-d 
build/macosx-aarch64/test-support/jtreg_test_hotspot_jtreg_tier1_serviceability/classes/0/test/lib


Additionally, since this is being compiled in context of the 
AgentWithVThreadTest, jtreg also passes the test specific work directory 
(`build/macosx-aarch64/test-support/jtreg_test_hotspot_jtreg_tier1_serviceability/classes/0/serviceability/jvmti/vthread/premain/AgentWithVThreadTest.d`)
 as the classpath to the javac command. So effectively, this compilation ends 
up finding the `jdk.test.lib.Utils.class` in the test specific directory and 
doesn't recompile to the shared location. Since the 
`jdk.test.lib.util.JavaAgentBuilder` hasn't yet been compiled nor is located in 
the test specific work directory, javac ends up compiling it and placing it in 
the destination directory which was passed to the javac invocation and happens 
to be a shared directory for tests 
`build/macosx-aarch64/test-support/jtreg_test_hotspot_jtreg_tier1_serviceability/classes/0/test/lib`.

Effectively we now have a test library class (the `JavaAgentBuilder`) in the 
common shared directory and some of its referenced classes (`Utils.class`) in a 
test specific directory.

At a later point in time, this new test `TestPinCaseWithCFLH` being proposed in 
this PR, gets launched and jtreg notices the `@run` statement:


@run driver jdk.test.lib.util.JavaAgentBuilder ...


Just like previously, since this is a test library class, jtreg tries to locate 
this class in the shared directory and it finds it in the shared directory 
`build/macosx-aarch64/test-support/jtreg_test_hotspot_jtreg_tier1_serviceability/classes/0/test/lib`
 (since it was compiled to that location by an unrelated test). Since it finds 
the class, jtreg then skips compilation of that test library class and thus the 
`Utils.class` (or any of the classes referenced by `JavaAgentBuilder`) isn't 
recompiled again. jtreg then launches the test with this shared directory and 
this test's specific work directory (which is different from the 
AgentWithVThreadTest's work directory) in the classpath. Since neither of these 
directories contain the `Utils.class`, we end up with this missing class error.

Like I noted, this is a known problem in jtreg. I'll see if we can do something 
in that area.

For now though, I think one workaround is to add a:


@clean jdk.test.lib.util.JavaAgentBuilder


before the `@run` tag to allow for the jdk.test.lib.util.JavaAgentBuilder and 
its referenced classes to be compiled afresh (into the shared test library 
directory). This is what the change would look like in your PR:


diff --git 
a/test/hotspot/jtreg/serviceability/jvmti/vthread/TestPinCaseWithCFLH/TestPinCaseWithCFLH.java
 
b/test/hotspot/jtreg/serviceability/jvmti/vthread/TestPinCaseWithCFLH/TestPinCaseWithCFLH.java
index 02755a0289f..60564115f51 100644
--- 
a/test/hotspot/jtreg/serviceability/jvmti/vthread/TestPinCaseWithCFLH/TestPinCaseWithCFLH.java
+++ 
b/test/hotspot/jtreg/serviceability/jvmti/vthread/TestPinCaseWithCFLH/TestPinCaseWithCFLH.java
@@ -34,7 +34,7 @@
  * @requires vm.jvmti
  * @modules java.base/java.lang:+open
  * @compile TestPinCaseWithCFLH.java
- * @build jdk.test.lib.Utils
+ * @clean jdk.test.lib.util.JavaAgentBuilder
  * @run driver jdk.test.lib.util.JavaAgentBuilder
  *             TestPinCaseWithCFLH TestPinCaseWithCFLH.jar
  * @run main/othervm/timeout=100  -Djdk.virtualThreadScheduler.maxPoolSize=1



I admit it's odd to be expecting the test to be doing this, but I think this 
should make the test stable. Can you give it a try?

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/20373#discussion_r1706894821

Reply via email to