Open abulka opened 1 year ago
1.2024.7 has a strange maven-module.class (javap'd below). Eclipse can't open it. It is not found in the source tree. It broke my build. 1.2024.6 also broke my build due to some conflict with flexmark. So, I have to stay on 1.2024.5. Maybe you are building a fat jar and this module info got into your fat jar from one of dependencies?
javap module-info.class
Compiled from "module-info.java"
module org.checkerframework.checker.qual {
requires java.base;
requires static java.compiler;
requires static java.desktop;
requires static jdk.compiler;
exports org.checkerframework.checker.builder.qual;
exports org.checkerframework.checker.calledmethods.qual;
exports org.checkerframework.checker.compilermsgs.qual;
exports org.checkerframework.checker.fenum.qual;
exports org.checkerframework.checker.formatter.qual;
exports org.checkerframework.checker.guieffect.qual;
exports org.checkerframework.checker.i18n.qual;
exports org.checkerframework.checker.i18nformatter.qual;
exports org.checkerframework.checker.index.qual;
exports org.checkerframework.checker.initialization.qual;
exports org.checkerframework.checker.interning.qual;
exports org.checkerframework.checker.lock.qual;
exports org.checkerframework.checker.mustcall.qual;
exports org.checkerframework.checker.nullness.qual;
exports org.checkerframework.checker.optional.qual;
exports org.checkerframework.checker.propkey.qual;
exports org.checkerframework.checker.regex.qual;
exports org.checkerframework.checker.signature.qual;
exports org.checkerframework.checker.signedness.qual;
exports org.checkerframework.checker.tainting.qual;
exports org.checkerframework.checker.units.qual;
exports org.checkerframework.common.aliasing.qual;
exports org.checkerframework.common.initializedfields.qual;
exports org.checkerframework.common.reflection.qual;
exports org.checkerframework.common.returnsreceiver.qual;
exports org.checkerframework.common.subtyping.qual;
exports org.checkerframework.common.util.count.report.qual;
exports org.checkerframework.common.value.qual;
exports org.checkerframework.dataflow.qual;
exports org.checkerframework.framework.qual;
}
It is probably related to ELK (see https://plantuml.com/en/elk )
Now that the JRE is no longer included with the JDK and the only way to generate a JRE runtime is with
jlink
- which rejects automatic modules and needs real modules. I believe PlantUML jars need to be modernised to keep pace with Java.I believe adding
module-info.java
won't affect older normal, non-modular use cases. It just provides the necessary info for cases where you are using a modular Java project.
I am really not familiar with module-info.java
so your help is highly requested here :-)
Is it something you could contribute on? That would be very nice.
The only constraint we have is that we still target Java 8 in our build, because some people are still there.
Compilation problem solved - remove all module-info.class
files from the jar and add a proper module-info.class
to the root of the jar! I did not try to run it. Also I did not try with Java 8. I hope it would just ignore module-info.class
in the jar root.
Initially I thought that what was needed was a multi-release jar with module-info.class
under META-INF/versions/9
folder.
In the plantuml-epl-1.2024.7 jar
there is module-info.class
in this folder:
open module com.google.errorprone.annotations@2.28.0 {
requires java.base;
requires java.compiler;
exports com.google.errorprone.annotations;
exports com.google.errorprone.annotations.concurrent;
}
And there is also module-info.class
in the root of the jar - see my first comment.
This is what I did:
module-info.java
as shown below and a placeholder classmodule-info.class
from 1.2024.7 jarMETA-INF/versions/9/module-info.class
with module-info.class
produced by my projectMETA-INF/versions/9/module-info.class
- compilation failed due to package conflicts (see below)module-info.class
to the root of my project and it worked!I used https://github.com/Nasdanika/plantuml-diagram-generator/releases/tag/maven-2023.12.1 to test compilation.
module net.sourceforge.plantuml {
exports net.sourceforge.plantuml;
}
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.common.command from both net.sourceforge.plantuml and org.eclipse.emf.common
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.common.archive from both net.sourceforge.plantuml and org.eclipse.emf.common
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.plugin from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.resource from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.resource.impl from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.impl from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.xml.namespace from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.xml.namespace.util from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.xml.namespace.impl from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.xml.type from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.xml.type.util from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.xml.type.internal from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.xml.type.impl from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.eclipse.emf.common reads package org.eclipse.emf.ecore.util from both net.sourceforge.plantuml and org.eclipse.emf.ecore
[ERROR] module org.json reads package org.eclipse.emf.common from both net.sourceforge.plantuml and org.eclipse.emf.common
[ERROR] module org.json reads package org.eclipse.emf.common.util from both net.sourceforge.plantuml and org.eclipse.emf.common
So, you need to modify your build process to do something like this. I added just one export to the module info file because this is the only package I used. You would likely have to add more and maybe also add opens
for reflection.
IMO in the modular world you should stay away from fat jars. If any of your API's use classes from co-packaged dependencies you'd have to add exports for those dependencies as well or remove dependencies from the jar. The second is preferred because no two modules can export the same package and as such if you export, say, com.google.errorprone.annotations
projects that use that dependency directly or transitively would not compile for the best of my knowledge.
You already have multiple artifacts in Maven Central, maybe create another one - plantuml-epl-modular
(I use your EPL artifact, so this is why EPL), don't package dependencies like eclipse.emf - add requires
to the module definition instead.
I can't ship a Javafx app which uses Plantuml jar because the official
jlink
tool rejectsplantuml-v1-2023-8.jar
as not being modular.There are other situations where I cannot deploy plantuml because plantuml is not a modern 'modular' jar, and thus jlink refuses to deal with it. Yes you can use plantuml jars in modular projects and plantuml becomes a 'automatic module' in those projects just fine. But jlink rejects automatic modules too.
Describe the solution you'd like Provide the necessary
module-info.java
for PlantUML jar - make it modular.Describe alternatives you've considered I've tried 'injecting' a
module-info.java
into the jar. Its not clear if the dependencies generated by my hack are good enough, and I worry thatjlink
will generate a custom JRE uneccessarily big (jlink seemed to generate a 400Mb JRE just because my hacked PlantUML.jar was included, up from 40Mb), unless someone who knows plantuml generates the propermodule-info.java
.I've also tried injecting
module-info.java
into the generated grammar jars - however this caused JavaThe hierarchy of the type is inconsistentJava(16777543)
problems - which have stopped all progress. See https://github.com/antlr/grammars-v4/issues/3505Additional context Now that the JRE is no longer included with the JDK and the only way to generate a JRE runtime is with
jlink
- which rejects automatic modules and needs real modules. I believe PlantUML jars need to be modernised to keep pace with Java.I believe adding
module-info.java
won't affect older normal, non-modular use cases. It just provides the necessary info for cases where you are using a modular Java project.See also Forum Post re this https://forum.plantuml.net/13598/using-plantuml-jar-with-javafx?show=17924#a17924