In a project I’m working on for my book, I need to share classes between two applications.
One, an Android project, requires Java 8. The other, a desktop JavaFX application, needs to
run under Java 9, complete with module support. The problem with this is that the Maven tooling
isn’t quite ready for Java 9, so it’s not as simple as I would like. I have, however, found
a solution that seems to work.
In this setup, I have three projects: the shared module, the Android project, and the
JavaFX project. The shared module looks roughly like this:
We accomplish our goal by configuring the Maven compiler plugin with two different executions.
In the first, we compile everything using a source and target of 1.8. For this pass, though,
we exclude module-info.java. For the next pass, we compile with a source and target
of 9. We also exclude everything so that our Java 8-compatible .class files aren’t
overwritten, but we also explicitly include our module-info.java source file. Once this
build runs, we’ll have mostly Java 8 .class files in our output directory, with a single
Java 9-specific file, module-info.class. The normal Maven process than jars everything up
and installs it in our local repository.
Over in our Android application, we can then declare the dependency on this jar:
And we can successfully build and run our JavaFX application. Both Android and Java 9
are, as they say, fat, dumb and happy, and we have our shared code in a single project
that can be used by both. It’s a bit more XML than we’d probably like, but, as Maven users,
we’re probably used to that by now. :)