Modules with platform specific parts

Kevin Rushforth kevin.rushforth at oracle.com
Thu Sep 16 00:10:03 UTC 2021


If we do eventually have to go with multiple, differently-named modules, 
this would seem a sensible approach. I think it's roughly what Johan was 
alluding to when he spoke of extending option 2 to use an SPI. In this 
case, we would refactor the platform-specific code into different named 
modules (that would be a fair bit of work, but let's ignore that for 
now), and the existing javafx.graphics module would become the API module.

Somewhat related to this: Of the four options, I think option 3 is a 
non-starter. The application developer should never have to "requires", 
or even know about the existence of, platform-specific modules. This 
means that we either need to stick with different physical modules all 
of which are named the same, or else platform-specific modules that are 
loaded using some sort of SPI, so that they don't have to be known at 
compile / link time.

-- Kevin


On 9/15/2021 2:15 AM, Michał Kłeczek wrote:
> Hi,
>
> Hi,
>
> There is another option:
>
> API module and multiple platform specific modules (different names like javafx.graphics.linux.aarch64) that require API module and provide services.
>
> API module does not “require” any platform specific module but uses ServiceLoader to find a proper implementation at runtime.
>
> Thanks,
> Michal
>
>
>> On 15 Sep 2021, at 10:45, Johan Vos <johan.vos at gluonhq.com> wrote:
>>
>> Hi,
>>
>> There have been discussions in the past about how to deal with
>> platform-specific parts (java code, native code, resources) in modules.
>> There is no standard for this, and afaik no recommendation. In the OpenJFX
>> project, we upload jars with module info to maven central, and we have
>> plugins for maven and gradle to deal with them at compiletime and at
>> runtime.
>>
>> However, the lack of a standard recommendation forces us to change the
>> internal behavior every now and then. The latest change we made (removing
>> automatic module names from empty modules [1]) caused issues in the 17
>> release, when developers compile JavaFX modular apps [2]
>>
>> Before we make many other changes, I would like to have a better view on
>> what would be the recommended approach, so here is my summary. Suggestions
>> are highly appreciated.
>>
>> Let's assume we have a component that contains some
>> platform-independent Java code, some platform-dependent Java code, and
>> some platform-dependent native code. To make the example concrete,
>> let's use the javafx.graphics "module" from the OpenJFX project, which
>> contains exactly that.
>>
>> There are a number of options, and before thinking about the best way
>> for tools do deal with this situation, it would be good to have a
>> recommended approach for those "hybrid" modules.
>>
>> 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.
>>
>> 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.
>>
>> 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.
>>
>> 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.
>>
>> We currently use option 4, but in my opinion, option 2 would be the
>> better approach.
>>
>> Thanks,
>>
>> - Johan
>>
>> [1] https://bugs.openjdk.java.net/browse/JDK-8264998
>> [2]
>> https://mail.openjdk.java.net/pipermail/openjfx-dev/2021-September/031934.html



More information about the jigsaw-dev mailing list