Package: plm
Version: 2.9.2-1.1
Severity: important
X-Debbugs-Cc: [email protected]

Dear Maintainer,

On a current Debian system (default-jdk is now OpenJDK 26), running a *Java*
exercise in PLM fails: the embedded compilation aborts and the exercise cannot
run. The Scala, Python and C language modes are unaffected; this is specific to
the Java mode.

Root cause
----------
What I gathered investigatig this: for a Java exercise, PLM recompiles a set of
its own framework sources together
with the student code, in-process, via javax.tools.JavaCompiler
(plm.core.lang.LangJava / CompilerJava). One of those framework sources,
src/plm/core/model/LessonRunner.java, calls the deprecated-for-removal
java.lang.Thread.stop():

/** Stop all the threads that were already started. Harmful but who cares? */
@SuppressWarnings("deprecation")
public void stopAll() {
while (runners.size()>0) {
Thread t = runners.remove(runners.size() - 1);
t.stop(); // harmful but who cares ?
}
}

On the JDK shipped in current Debian this recompilation fails, e.g.:

/usr/share/java/plm.jar(/plm/core/model/LessonRunner.java):110: cannot find
symbol
symbol: method stop()
location: variable t of type java.lang.Thread

(Two further framework sources only emit deprecation-for-removal warnings, not
yet fatal, but should be modernized at the same time:
- src/plm/universe/World.java -- java.lang.ThreadDeath
- src/plm/core/lang/LangJava.java -- java.security.AccessController)

Thread.stop(), Thread.suspend()/resume(), ThreadDeath and AccessController are
all deprecated for removal; relying on them in code that is recompiled at run
time is fragile across JDKs and will only get worse.

To reproduce:
1. Install plm on a system whose default-jdk is OpenJDK 21 or newer.
2. Launch plm, open any Java exercise, type e.g. System.out.println("hi");
3. Run it -> the exercise aborts with the compilation error above.

The proposed fix:

Stop using Thread.stop(). The straightforward replacement is cooperative
cancellation via Thread.interrupt() in stopAll().
Caveat: interrupt() is cooperative, so a student program
stuck in a tight non-cooperative loop would not be force-killed the way 
Thread.stop() did.
Another robust solution would run the student code in a separate JVM/process 
that can be hard-killed.

I believe that the cooperative approach is the modern practice and
restores Java exercises on current JDKs.

I will forward a proposed patch upstream (https://github.com/oster/PLM) and
attach/track it here.

Thanks,
Juan
  • Bug#1139926: plm: Java exercises fail on JDK 21+ (Thr... Juan M . Méndez Rey

Reply via email to