possible bug in jdeps as ToolProvider

Mandy Chung mandy.chung at oracle.com
Mon Dec 20 18:19:20 UTC 2021


Yes this bug is known and tracked by JDK-8277681.  The proper solution 
should make each JdepsTask to maintain its own map of multi-versioned 
entries rather than a global nameToVersion map for the running VM as 
described in
JDK-8277681.

Mandy

On 12/18/21 7:47 PM, Raymond Augé wrote:
> Hello everyone,
>
> At Alan's request [3] I'm posting this here. Alan mentions this is likely a
> manifestation of JDK-8277681 [4]. From the description I would agree.
>
> Here is a copy of the original message for posterity.
> -------------------
> I believe I have found a small bug in jdeps tool when used as ToolProvider.
>
> I am invoking the jdeps impl via the ToolProvider API as follows (this code
> is also available here [2]):
>
>    try (final StringWriter stdout = new StringWriter();
>        final StringWriter stderr = new StringWriter();
>        final PrintWriter pwout = new PrintWriter(stdout);
>        final PrintWriter pwerr = new PrintWriter(stderr)) {
>
>      return (ToolProvider.findFirst("jdeps").orElseThrow().run(pwout, pwerr,
> args) == 0) ?
>        stdout.toString() :
>        "Error: ".concat(stderr.toString());
>    }
>    catch (Throwable t) {
>      t.printStackTrace();
>      return "Error: " + t.getMessage();
>    }
>
> However repeat invocations result in the following exception:
>
> java.lang.Error: java.util.concurrent.ExecutionException:
> com.sun.tools.jdeps.MultiReleaseException
> at
> jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.waitForTasksCompleted(DependencyFinder.java:271)
> at
> jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.parse(DependencyFinder.java:133)
> at jdk.jdeps/com.sun.tools.jdeps.DepsAnalyzer.run(DepsAnalyzer.java:129)
> at
> jdk.jdeps/com.sun.tools.jdeps.ModuleExportsAnalyzer.run(ModuleExportsAnalyzer.java:74)
> at
> jdk.jdeps/com.sun.tools.jdeps.JdepsTask$ListModuleDeps.run(JdepsTask.java:1047)
> at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:574)
> at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
> at jdk.jdeps/com.sun.tools.jdeps.Main.run(Main.java:64)
> at jdk.jdeps/com.sun.tools.jdeps.Main$JDepsToolProvider.run(Main.java:73)
>    [snip]
> Caused by: java.util.concurrent.ExecutionException:
> com.sun.tools.jdeps.MultiReleaseException
> at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
> at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
> at
> jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.waitForTasksCompleted(DependencyFinder.java:267)
> ... 24 more
> Caused by: com.sun.tools.jdeps.MultiReleaseException
> at jdk.jdeps/com.sun.tools.jdeps.VersionHelper.add(VersionHelper.java:62)
> at
> jdk.jdeps/com.sun.tools.jdeps.ClassFileReader$JarFileReader.readClassFile(ClassFileReader.java:360)
> at
> jdk.jdeps/com.sun.tools.jdeps.ClassFileReader$JarFileIterator.hasNext(ClassFileReader.java:402)
> at
> jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.lambda$parse$5(DependencyFinder.java:179)
> at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
> at
> java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
> at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
> at
> java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
> at
> java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
> at java.base/java.lang.Thread.run(Thread.java:829)
>
> In order to get around the error I do the following:
>
> public static final Field field;
> public static final Map<?,?> map;
>
> static {
>    try {
>      Class<?> clazz = Class.forName("com.sun.tools.jdeps.VersionHelper");
>      field = clazz.getDeclaredField("nameToVersion");
>      field.setAccessible(true);
>      map = (Map<?,?>)field.get(null);
>    }
>    catch (ReflectiveOperationException e) {
>      throw new RuntimeException(e);
>    }
> }
>
> and tack a finally to the end of the try above:
>
> finally {
>    map.clear();
> }
>
> Now, additionally to be able to do that, I need to add an `--add-opens`:
>
> --add-opens jdk.jdeps/com.sun.tools.jdeps=ALL-UNNAMED
>
> I believe the solution is to clear the map in [1] when jdeps finishes.
>
> Finally, I would send a PR myself except I do not (yet) have an OCA and the
> solution seems simple enough if someone can confirm that this is indeed a
> bug.
>
> Ray
>
> [1]
> https://github.com/openjdk/jdk/blob/master/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/VersionHelper.java
> [2]https://gist.github.com/rotty3000/d9feec79a66f14c2360fee9b9a1b2852
> [3]
> https://mail.openjdk.java.net/pipermail/jdk-dev/2021-December/006291.html
> [4]https://bugs.openjdk.java.net/browse/JDK-8277681


More information about the core-libs-dev mailing list