20

Suppose I have some library lib.jar for which I do not have the source code (or it is written in some non-Java language which is unaware of modules yet). lib.jar does not have module-info.class and I do not want to use it as an automatic module, so I would like to inject module-info.class into it.

I first generate module-info.java with the following command:

jdeps --generate-module-info . lib.jar

Suppose this generated something like that:

module lib {
    exports package1;
    exports package2;
}

Then I try to compile it but javac fails because the packages package1 and package2 do not exist:

> javac module-info.java
module-info.java:4: error: package is empty or does not exist: package1

Of course, I can create directories package1 and package2 with dummy classes in them, but is there some better approach?

ZhekaKozlov
  • 32,979
  • 19
  • 111
  • 146

2 Answers2

20

Yes, this is possible with the --patch-module option. This option is most often used at runtime, but it also works at compile time:

javac --patch-module <module name>=<path to jar> module-info.java
ZhekaKozlov
  • 32,979
  • 19
  • 111
  • 146
  • when I use this command, I still get the error: > javac module-info.java module-info.java:4: error: package is empty or does not exist: package1 Any ideia why it might not working for me? – Tiago Santos Nov 22 '17 at 08:52
  • @TiagoSantos Does the package exist in the JAR? – ZhekaKozlov Nov 22 '17 at 10:33
  • yes, everything seems fine, I managed to have it working using the solution above from nullpointer, I do agree that your solution is more elegant, the only problem is that isn't working with my .jars :/ tried in 2 different ones – Tiago Santos Nov 22 '17 at 10:36
  • @TiagoSantos Have you replaced `lib` with the actual module name? – ZhekaKozlov Nov 22 '17 at 11:39
  • @TiagoSantos I modified my answer because that was indeed unobvious that `lib` should be substituted with the module name. – ZhekaKozlov Nov 22 '17 at 11:47
  • ahhh! indeed was not obvious :D thanks for the update – Tiago Santos Nov 23 '17 at 14:21
  • 23
    For anyone attempting to update a legacy JAR with a generated module-info, this sequence of commands is what I got to work: `jdeps --generate-module-info . ` `javac --patch-module = /module-info.java` `jar uf -C module-info.class` – Philip Guin Dec 23 '17 at 09:57
  • 1
    The addition by Philip is important, as the command in the answer does not inject anything but only compiles module-info.java into module-info.class for a jar. The class is then added to the jar using jar command. – Андрей Вахрушев Nov 12 '21 at 16:11
7

Alternatively, to compile the module-info.java generated you need to also extract the contents of the JAR to a directory.

Then compile the module-info.java with the output directory (-d) set to the directory where you extracted the contents.

Credits :- Alan

Naman
  • 21,685
  • 24
  • 196
  • 332
  • 1
    I accepted my own answer because I think my way is slightly more elegant. Extracting files is an extra step which is a bit inconvenient (especially for tools). – ZhekaKozlov Nov 15 '17 at 07:23