possible bug in jdeps as ToolProvider

Raymond Augé raymond.auge at liferay.com
Sat Dec 18 16:04:10 UTC 2021


Hello everyone,

This is my first post here so if I have posted in the wrong place or have
broken procedure be kind and clarify/refer me to the correct information.

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


More information about the jdk-dev mailing list