False positives when using java.util.Random with JDK 17-ea17
See original GitHub issueRunning the forbidden-apis Maven plugin with JDK 17-ea17 leads to false positives.
Apparently, uses of allowed classes are mistaken for uses of their (forbidden) inner classes, leading to
For example, I created a reproducer using java.util.Random
, with forbiddenapis configured to forbid the bundled signatures jdk-internal-1.8
.
Everything should work fine, but when running with Maven 3.6.3 and JDK 17-ea17, we get an error stating “Forbidden class use: jdk.internal.util.random.RandomSupport$AbstractSpliteratorGenerator”, even though that class is never used in the source code.
Full output:
$ mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] --< org.hibernate.playground.forbiddenapis:forbiddenapis-playground >---
[INFO] Building forbiddenapis-playground 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ forbiddenapis-playground ---
[INFO] Deleting /home/yrodiere/workspaces/testcases/forbiddenapis-playground/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ forbiddenapis-playground ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ forbiddenapis-playground ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /home/yrodiere/workspaces/testcases/forbiddenapis-playground/target/classes
[INFO]
[INFO] --- forbiddenapis:2.6:check (verify-forbidden-apis) @ forbiddenapis-playground ---
[INFO] Scanning for classes to check...
[INFO] Reading bundled API signatures: jdk-internal-1.8
[INFO] Loading classes to check...
[INFO] Scanning classes for violations...
[ERROR] Forbidden class use: jdk.internal.util.random.RandomSupport$AbstractSpliteratorGenerator [non-public internal runtime class in Java 1.8]
[ERROR] in org.hibernate.playground.forbiddenapis.RandomGenerator (RandomGenerator.java, field declaration of 'r')
[ERROR] Scanned 1 class file(s) for forbidden API invocations (in 0.02s), 1 error(s).
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.665 s
[INFO] Finished at: 2021-04-12T16:34:33+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal de.thetaphi:forbiddenapis:2.6:check (verify-forbidden-apis) on project forbiddenapis-playground: Check for forbidden API calls failed, see log. -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
For reference, it used to work with JDK 17-ea13:
$ mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] --< org.hibernate.playground.forbiddenapis:forbiddenapis-playground >---
[INFO] Building forbiddenapis-playground 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ forbiddenapis-playground ---
[INFO] Deleting /home/yrodiere/workspaces/testcases/forbiddenapis-playground/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ forbiddenapis-playground ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ forbiddenapis-playground ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /home/yrodiere/workspaces/testcases/forbiddenapis-playground/target/classes
[INFO]
[INFO] --- forbiddenapis:2.6:check (verify-forbidden-apis) @ forbiddenapis-playground ---
[INFO] Scanning for classes to check...
[INFO] Reading bundled API signatures: jdk-internal-1.8
[INFO] Loading classes to check...
[INFO] Scanning classes for violations...
[INFO] Scanned 1 class file(s) for forbidden API invocations (in 0.02s), 0 error(s).
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ forbiddenapis-playground ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /home/yrodiere/workspaces/testcases/forbiddenapis-playground/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ forbiddenapis-playground ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ forbiddenapis-playground ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ forbiddenapis-playground ---
[INFO] Building jar: /home/yrodiere/workspaces/testcases/forbiddenapis-playground/target/forbiddenapis-playground-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ forbiddenapis-playground ---
[INFO] Installing /home/yrodiere/workspaces/testcases/forbiddenapis-playground/target/forbiddenapis-playground-1.0-SNAPSHOT.jar to /home/yrodiere/.m2/repository/org/hibernate/playground/forbiddenapis/forbiddenapis-playground/1.0-SNAPSHOT/forbiddenapis-playground-1.0-SNAPSHOT.jar
[INFO] Installing /home/yrodiere/workspaces/testcases/forbiddenapis-playground/pom.xml to /home/yrodiere/.m2/repository/org/hibernate/playground/forbiddenapis/forbiddenapis-playground/1.0-SNAPSHOT/forbiddenapis-playground-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.847 s
I suspected that JDK17 might have introduced some cutting edge magic that inlines constructors somehow, but apparently not: decompiling the class files with CFR yields the original source code.
So I suspect forbiddenapis may be doing something that doesn’t work with JDK17-ea17 anymore. Decompiling the file that triggers the error shows that it’s not some cutting edge JDK17 magic
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (9 by maintainers)
Hi, I have not yet pushed the PR, but will do soon, as this special case may happen more often in the future.
In the meantime, the APIs of Random were revised, as the JDK developers figured out that having some hidden base class in the class hierarchy is a bad idea, as it suddenly changes pblic API of Random, ThreadLocalRandom and others.
Therefor they moved the internal implementations to a private class with static utility methods:
Once this is part of JDK, the problem should automatically disappear.
Nevertheless, I’d like to push the changes in the PR, but it is hard to find a good test case (you cannot mock or synthesize one, as it relies on classes be inside the JDK runtime - which may change all the time (like in the fixes coming to OpenJDK 17 soon).
I will think about it a few more days and then decide how to handle that.
There is now a PR: #178
I need to add a test. It consists of 2 commits: first is to rewrite the whole logic behind the class hierarchy to use a “visitor” pattern. In a second commit just a few checks are added: https://github.com/policeman-tools/forbidden-apis/pull/178/commits/accce12fea9d24aa09ee4be54106870a58191587
Basically: If some code from inside the runtime extends/implements some non-portable class/interface, this is ignored and neither method calls nor field accesses are recognized. This is still a hack, but looks useable.