-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java 11 compatibility #135
base: master
Are you sure you want to change the base?
Conversation
* Added module-info to be able to consume ezvcard from a modular Java 11 project. * Updated dependencies required to be able to compile with Java 11. * Removed xalan and tests dependent on xalan since it imports a dependency (xml-apis) that conflict with the Java 11 module path.
Modular projects can still import non-modular libraries, no? Android compatibility is also important. |
No - or only with the workaround of "automodules", where a module is created from a jar based on its file name. This produces the uggly warning during compile:
This workaround is - especially when using Maven-Builds - extremely fragile, because the file name Maven chooses for the library depends on potential clashes with other libraries. And, what's even worse, while this auto-module thing worked for version If Android compatibility is an issue, I would vote for reconsidering proposal #131. |
I updated the PR to again use Java 8 as base version, but adopted the approach in #131 to use the moditect plugin to add a module descriptor. In contrast to #131, I let Maven auto-generate the descriptor, so that no additional information needs to be maintained in the project. Additionally, I generate a multi-release JAR to minimize the potential of producing conflicts with older target VMs. |
One difference between the two versions is that
When I try to build the project using a Java 8 JDK, I get this error:
When I try to build the project using a Java 18 JDK, several of the unit tests do not run because of problems with Mockito.
I'm very reluctant to add modular support to this project because of collateral damage it is likely to cause. |
This is very likely to cause the problem. I built the branch with Java 11, this worked fine. For Java 18, maybe more build tools need an update. But if you just update your module name hint in the manifest, this is could also be good enough. By the way, your dependency |
I updated the |
Thanks for the tip about Is there a reason why you're specifically looking for Java 11 compatibility? Is it just because that's what your project is using or is Java 11 considered baseline now? Also, in the moditect plugin configuration, why is Java 11 specifically referenced here? I thought the purpose of this plugin was to make the library compatible with the Java module system in general, no matter what version is being run. |
I consider it a good practice for a library or framework to support with its newest version the oldest not yet "very out of date" version of the JDK. Currently, this is Java 11 (EOL 30 Sep 2023), see https://endoflife.date/java. I also consider it a good practice for libraries to only care about LTS versions of the JDK. Those were Java 8, Java 11 and Java 17. This is why I choose Java 11 as baseline for supporting modular applications in the moditect plugin. Theoretically, one could use Java 9 here, but Java 9 was non LTS and EOL 20 Mar 2018. Nobody should care about this version nowadays. |
I'm happy to see that someone else brought up this issue, imo it's very important to help the ecosystem transition to the module system. Here are my considerations:
I'd go for Java 11 in the moditect plugin for maximum compatibility. It should take no more than a couple of minutes in the future to transition to Java 17 or even 21. If it were for me, I'd completely drop support for Java 8: I think that we as open source maintainers have a crucial role in pushing the ecosystem forward, yet I also understand this library is heavily used on Android(gotta love Android's JVM implementation), so i see why maintaining support for older Java versions is crucial. |
Thanks for popping into the conversation, @Auties00! I agree that it makes sense to go with Java 11 for maximum compatibility. I still don't understand why the moditect plugin requires a Java version to be specified. I thought a project either supported modules or doesn't support modules? By telling moditect to use Java 11, are we telling it to support Java 11's version of the module system in particular? Am I right to assume that the compiled class files will still be compatible with Java 8, even if the project is compiled with a Java 11+ JDK? That's the whole point of using moditect, right? Thanks for your time with this. |
This requests the plugin to create a "multi-version" JAR, where the Java 11 part is not added directly to the JAR, but encapsulated into
Yes, since the global target version is still 1.8. You should be able to verify that by adding the JAR as dependency to a Java 8 project, that still compiles with a Java 8 JDK. This is true as long as you do not start using Java API's in |
Thanks. I've tested the JAR under a non-module project (using JDK 8) and a modular project (using JDK 11) it works with both versions. It looks like there's another problem. I have been giving users the option of excluding certain dependencies if they do not need to use certain features of ez-vcard. For example, the JSON dependency (Jackson) can be excluded if the user knows they will never need to create JSON-encoded vCards. However, with this new module system, if I exclude a dependency in the POM, I get a runtime error. Any idea how to address this?
|
Notes to self: The Javadoc CSS file must be updated with whatever CSS the JDK you're using to build the project with is using: The following setting must be added to the Javadoc plugin settings in the POM to prevent a warning related to modules from spamming the screen. See: https://stackoverflow.com/a/62533664/13379
|
org.jsoup, freemarker, and com.fasterxml.jackson.core can be excluded as dependency, if the corresponding functionality is not needed from ez-vcard.
Optional dependencies have the However, the best solution to such issue would be to split the package into a core not requiring all of those optional dependencies and a set of modules adding additional functionality that actually requires the dependency. Dependency exclusion and optional dependencies are fragile and error-prone workarounds.
I added your suggested configuration option. It seems to help.
Don't know what to do here, the generated JavaDoc looks fine to me at the first glance. |
When I try to write a JSON-encoded vCard in a separate Java 11 project, I get a ClassNotFoundException. Are you saying that the Jackson dependency must be explicitly added to the project's Also, when I try to create an HTML-encoded vCard (uses the freemarker library), an exception is thrown about it not being able to find the template file on the classpath. The template file is located on the classpath here: public class HCardPage {
public HCardPage() {
Configuration cfg = ...
cfg.setClassForTemplateLoading(HCardPage.class, ""); //the template file is in the same package as HCardPage
Template template = cfg.getTemplate("hcard-template.html"); //exception thrown here
}
} |
I'm pretty sure I got the optional dependencies to work in my PR, you just needed to add the maven dependency explicitly as it always was. |
Hyphens are not allowed in module names #135 (comment)
Hyphens are not allowed in module names #135 (comment)
Java 8 is now really out of date and consuming the ez-vcard dependency is not possible from a modular Java 11 project.
opens
statements are just enough to make the tests run.