0

I call a Java compiler, jar and other Java tools from my code. However the code stopped working in JDK 16 and up with the following error:

Unable to make public static void sun.tools.jar.Main.main(java.lang.String[]) accessible: module jdk.jartool does not "exports sun.tools.jar" to unnamed module @46d21ee0

How to make my code working again for JDK 16 and up?

Edit: Unfortunately, there is no straight example of the problem, but some points:

Calling a tool: https://github.com/drogatkin/TJWS2/blob/02f4489ceddf325649eb2ac08cb98d51884f15fb/1.x/bee.xml#L513

Implementation: https://github.com/drogatkin/7Bee/blob/1a4443f3315ed39c38190bc128573b4329a49538/src/java/org/bee/processor/Task.java#L161

user2305886
  • 784
  • 8
  • 18
  • @BasilBourque I don't think there's a suitable answer on that other question. Would you consider re-opening this? – Dawood ibn Kareem Oct 24 '21 at 01:03
  • 1
    @DawoodibnKareem The [accepted Answer](https://stackoverflow.com/a/55207956/642706) on the original explains that `sun.tools.jar` was [removed as of Java 9](https://openjdk.java.net/jeps/220). The solution is to either (a) fall back to Java 8 or (b) update your libraries to newer versions that do not expect that particular JAR. Seems quite straight-forward to me. I do not see any benefit to having more Answers here rehashing the same points. – Basil Bourque Oct 24 '21 at 01:41
  • @DawoodibnKareem I edited that [other Answer](https://stackoverflow.com/a/55207956/642706) to be even more obvious. This includes a heading to sum it up: *`tools.jar` removed from Java 9+*. I added more links for even more background info. – Basil Bourque Oct 24 '21 at 01:59
  • The question is "How to make my code working again for JDK 16 and up?", not "Why did this happen?" or "What other JDK can I use?". – Dawood ibn Kareem Oct 24 '21 at 02:31
  • @Basil Unlike in the duplicate you linked, the OP appears to have control over the code and so they have another, probably more appropriate option: Use the `ToolProvider` SPI, [as explained in the Javadoc](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.jartool/module-summary.html) (link is for the `jar` tool, but also works for `javac` and others). – Slaw Oct 24 '21 at 03:15
  • @Slaw & DawoodibnKareem Very well, I re-opened the question. – Basil Bourque Oct 24 '21 at 03:18
  • It will help a lot if you can create a small example that works with an older version of Java but breaks with JDK 16. See [mcve] for tips on creating an example. – Code-Apprentice Oct 24 '21 at 04:21

1 Answers1

0

If I understand correctly, it's your own code that invokes various tools programmatically (without forking a process). The tools.jar file was removed in Java 9, but it was refactored into modules. For example, the jar tool now resides in the jdk.jartool module. These modules may or may not export the packages you were using before. However, there is an SPI you can use to invoke the tools. Here's the documentation from the jdk.jartool module:

Defines tools for manipulating Java Archive (JAR) files, including the jar and jarsigner tools. This module also defines APIs for signing JAR files. This module provides the equivalent of command-line access to jar via the ToolProvider SPI. Instances of the tool can be obtained by calling ToolProvider.findFirst or the service loader with the name "jar".

So if you wanted to programmatically invoke the jar tool, you'd do:

ToolProvider jar = ToolProvider.findFirst("jar").orElseThrow();
// you can replace 'System.out' and 'System.err' as appropriate
int result = jar.run(System.out, System.err, /* the arguments */);

The "arguments" are the same as you'd pass to the tool when invoking it from the terminal.

And you can similarly do this for the other tools (e.g. javac, javadoc, etc.). Note there's also JavaCompiler and DocumentationTool. Those APIs are more feature-rich, but only exist for the compiler and documentation tools.

Slaw
  • 37,820
  • 8
  • 53
  • 80