Modules with platform specific parts

Johan Vos johan.vos at gluonhq.com
Thu Sep 16 07:33:11 UTC 2021


Right, I didn't even mention multi-platform builds.
That is a very valid concern, and it makes the situation a bit more complex.

We currently have different jar files for every different
platform/architecture combination. There is an exception though: we have 1
build for all iOS combinations: {32/64 bit, intel/arm}. One of the reasons
for this is that market stores often require a multi-architecture build to
be uploaded, so that the same applications work on all their supported
archs.
We currently don't do this yet for MacOS, where we have different jars for
AMD64 and AARCH64.

Maven uses the concept "classifier" for this. But that is just an
unstructured string. We might need is a more structured approach in which a
jar (or a jmod?) can declare one or more classifiers that it provides. It's
then up to the tooling to wire things together, but at the very least,
tools should be able to understand what the modules are providing (and not
only which packages).

- Johan



On Wed, Sep 15, 2021 at 6:10 PM Hervé Guillemet <hg at apteryx.fr> wrote:

> Hi,
>
> Thank you Johan for starting this discussion. The current situation
> is indeed problematic and a (de facto or not) standard should emerge.
>
> IMO, beyond being easy to use, the selected mechanism should allow to
> build multi-platform images (for instance for MacOSX on both aarch64
> and x86_64).
>
>  > 1. There is a single module (i.e. only one Module). All code, no
>  > matter on what platform or in which layer, will report the same value
>  > for class.getModule().getName(). This would lead to a single
>  > "javafx.graphics" conceptual module, but there will be a number of
>  > physical module files that are different (with different class files
>  > and native code). Those different modules should obvisouly be mutually
>  > exclusive in a runtime.
>
> This option doesn’t allow multi-platform images. Also the duplication of
> all common Java classes in each platform jars is not ideal.
>
>  > 2. There are 2 modules: the platform-independent Java code goes into
>  > one module (let's call that javafx.graphics.api) and a second module
>  > is named javafx.graphics.platform and contains the platform-dependent
>  > Java code and the native code.
>  > In this approach, developers use the javafx.graphics.api module to
>  > compile against, and at runtime the javafx.graphics.platform module is
>  > required. Again, that second module will have a number of different
>  > physical implementations. As an extension to this, we might add the
>  > Service Provider Interface approach for loading platform-specific
>  > modules/bits at runtime.
>
> This option doesn’t allow multi-platform images.
>
>  > 3. We create one module for each platform. There is no
>  > "javafx.graphics" module in this case, but there is a
>  > "javafx.graphics.linux.aarch64" module for example.
>  > Doing so, there is a tight coupling between one conceptual module and
>  >  one physical module. A clear drawback of this is that this is a real
>  > challenge at compiletime. Developers (who are only using generic
>  > API's) need to compile against a platform-specific module.
>
> Indeed. The building of the module path can be automatized with
> Maven on another build system, but the module descriptor should also
> be changed for each platform you are building for.
> Multi-platform images won’t work either since packages would be split,
> and common classes are also duplicated. I don’t see any advantage compared
> to option 1.
>
>  > 4. We use 2 artifacts: an "empty" one and then a number of
>  > implementation specific ones. The difference with option 2 is that the
>  > empty "module" exists solely for the purpose of tools, which can
>  > detect what implementation specific module(s) need to be loaded at
>  > compile/runtime.
>
> Like mentioned in your referenced links, this causes problems.
> I haven’t worked with OpenJFX 17 but with OpenJFX 11-16, and to be
> able to build JLink images I had either to use the JavaFX maven
> plugin (which takes care of empty modules but one may wish to use
> alternate plugins because of some limitations [1-4]) or explicitly
> depend directly on the implementation-specific artifact, and remove
> indirect dependency towards the empty modules with maven configurations
> like :
>
>          <dependency>
>              <groupId>org.openjfx</groupId>
>              <artifactId>javafx-controls</artifactId>
>              <classifier>${javafx.platform}</classifier>
>              <version>16</version>
>              <exclusions>
>                  <exclusion>
>                      <groupId>org.openjfx</groupId>
>                      <artifactId>*</artifactId>
>                  </exclusion>
>              </exclusions>
>          </dependency>
>
>
> I’m adding the option currently used by JavaCPP:
>
> 5. There is one main/API module (javafx.graphics or
> javafx.graphics.api), any number of platform-specific modules
> (javafx.graphics.linux.aarch64, etc…), and an empty module
> (javafx.graphics.platform) similar to the current one in OpenJFX.
> There is a 1-1 coupling between modules and artifacts.
> Users declares maven dependencies towards the empty module but the
> module descriptor "requires" the API module. The build system takes
> care or populating the module path according to the value of a
> property (javafx.platform) that could be multi-valued.
>
> Compared to option 2, it allows for multi-platform builds, but
> users must take care of the javafx.platform property and the platform
> modules must be brought into the module graph by an --add-modules
> command line argument.
> The special value ALL-MODULE-PATH can be used to benefit from the path
> calculation of the build system.
>
> Slighlty OOT, I believe that the selected mechanisms should provide a
> way to ship the native libraries pre-extracted in a JLink image. There
> is no technical reason from the user point of view to slow down the
> first run with library extraction and to silently pollute the home
> directory with a never cleaned .javacpp or .openjfx directory, when the
> library could simply come pre-extracted in the image. That means that
> the artifact with the native libraries have Maven scope “provided”, or
> that exists some stripped version of the artifact without the libraries
> if the artifact must also contain Java classes or other resources.
>
> I finally link another OOT but close issue that was faced by JavaCPP
> users trying to run their App within an OSGi framework and that shows
> how tricky it can be to enumerate the bundled native libraries and
> extract them to the file system in some not-mainstream cases, and that
> we do need some common standard solution : [5].
>
> --
> Hervé Guillemet
>
>
> [1] https://github.com/javafxports/openjdk-jfx/issues/387
> [2] https://github.com/openjfx/javafx-maven-plugin/issues/91
> [3] https://github.com/openjfx/javafx-maven-plugin/pull/92
> [4] https://github.com/openjfx/javafx-maven-plugin/pull/109
> [5] https://github.com/bytedeco/javacpp/pull/511
>
>


More information about the jigsaw-dev mailing list