Is it possible to mix Java 8 and Java 9 source code in the same project without using compiler flags?
Asked Answered
G

2

11

In Java 9, you can optionally package a source directory as a module by adding a module-info.java, which defines the things packages that it exports, and which other modules it depends on.

Once you do that, however, you must list ALL dependencies in the module descriptor - and the dependencies must all themselves be modules. Therefore, by extension, if you modularize a single source directory, you must modularize every single source directory company wide.

Furthermore, you cannot define modules in Java 8 or earlier, meaning that in addition to modularizing every single Java source directory, you must convert everything to Java 9. At the same time.

This seems catastrophic if you work in a company with a large base of code that is shared by many different projects.

For now, I can work around the problem by just setting a bunch of compiler flags to avoid defining modules, but that seems like a very poor solution.

I hope that I am understanding this incorrectly?

Gosselin answered 17/11, 2017 at 20:48 Comment(0)
A
10

Once you do that, however, you must list ALL dependencies in the module descriptor

True.

and the dependencies must all themselves be modules.

Technically true, but it doesn't imply what you think it does.

Therefore, by extension, if you modularize a single source directory, you must modularize every single source directory company wide.

No, because you can let the module system turn regular old JARs into automatic modules, which will get a name based on a manifest entry or their file name - you can find that out with:

# jar command from Java 9
jar --describe-module --file $JAR_FILE

Furthermore, you cannot define modules in Java 8 or earlier, meaning that in addition to modularizing every single Java source directory, you must convert everything to Java 9. At the same time.

Again, fortunately that's not quite right. You can add a module-info.class to a JAR built for Java 8 and it will work on both Java 8 (which ignores that file) and Java 9 (which can of course execute Java 8 bytecode).

Appertain answered 17/11, 2017 at 20:58 Comment(0)
P
5

if you modularize a single source directory, you must modularize every single source directory company-wide.

No, that does not hold true, for the fact, that is what automatic modules are designed for and

(to favor the impulse) Yes, eventually that shall be the goal of modularisation.


Reiterating the need of introducing the automatic modules from The State of the Module System:

Bottom-up migration is straightforward, but it is not always possible. Even if the maintainer of org-baz-qux.jar has not yet converted it into a proper module—or perhaps never will—we might still want to modularize our com-foo-app.jar and com-foo-bar.jar components.


When you actually say :

you can optionally package a source directory as a module by adding a module-info.java

you tend to migrate that artifact into a module(with module description) and place such modules in the module-path of the libraries using this artifact further.

On the other hand, a .jar of your library without the module-info.class is considered to be present at the class-path when included as a dependency in downstream projects.


Edit from comments:-

it's possible to mix Java 9 source with Java 8 compiled jars, but you can't compile a single project containing Java 9 source and Java 8 source?

Yes, its possible to mix Java9 source with Java8 compile jar and you can still compile them into a single project as well.

Example:- take a look at how Maven does this using maven-compiler-plugin for Java8 projects with module-info.java included.

Protuberate answered 17/11, 2017 at 20:52 Comment(11)
Does the automatic module provision work for compiling source code, or do we need to generate compiled jars for all of our shared code?Gosselin
the automatic module works provisioning the artifacts onto the classpath of your downstream projects. Its not mandatory(if you are under this assumption) to generate a module-info for any jar to be included in as a dependency of a project that you're migrating to java9. That being a point of treating such dependencies as automatic modules in such case.Protuberate
So to summarize, it's possible to mix Java 9 source with Java 8 compiled jars, but you can't compile a single project containing Java 9 source and Java 8 source?Gosselin
it's possible to mix Java 9 source with Java 8 compiled jars... Yes. .. you can't compile a single project containing Java 9 source and Java 8 source? ..No you can compile a project with both Java versions classes in it.Protuberate
Thank you for the explanation, although that is really, really disappointing. Our shared code libraries are all currently in Java 8, and the prospect of needing to work with compiled jars for the Java 8 code instead of directly just modifying the source code and building the entire project is a huge step backwards in terms of productivity.Gosselin
@JesseBarnum You can use the existing Java8 based libs as automatic modules in such cases and target to make use to multi-release jars as supported in Java9 which would be useful to compile your code for both Java versions as and when required.Protuberate
thanks for your patience. I think we're talking past each other a little bit here - I feel like what you're saying is that I can compile java8libraryA.jar, java8libraryB.jar, then put them on the classpath and use that to compile java9application.jar. But what I want to do is to just be able to modify all of my java 8 and java 9 source code directly, then compile into a single java8and9application.jar.Gosselin
@JesseBarnum what I want to do is to just be able to modify all of my java 8 and java 9 source code directly, then compile into a single java8and9application.jar ..that leaves me a bit puzzled...do you mean to put all the libraries into a single jar? Considering java9application, java8libraryA and java8libraryB are all different source code that you manage. What actually are you trying to achieve there?Protuberate
"Do you mean to put all the libraries into a single jar?" Yes, that would be my final output. It is a barrier to rapid development to need to compile source code to a jar file before incorporating it into the project. I don't look at these as static libraries, they are all being modified rapidly in the course of development.Gosselin
Let us continue this discussion in chat.Protuberate
@JesseBarnum The original question doesn't really state "what I want to do is modify java 8 and java 9 code directly and compile into a single java8and9application.jar". IMHO, the original question isn't clear at all.Exemplificative

© 2022 - 2024 — McMap. All rights reserved.