[ 
https://issues.apache.org/jira/browse/FELIX-5592?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15931956#comment-15931956
 ] 

Mark Raynsford commented on FELIX-5592:
---------------------------------------

I don't want to be seen as strongly suggesting you should or shouldn't do 
anything: I don't know enough about your particular case. Some projects want to 
use multi-release jars to deliver code that is present on both (Java < 9) and 
(Java >= 9). Other projects want to use multi-release jars to deliver code that 
has extra functionality on (Java >= 9). An example of the latter is the LWJGL 
project: They use the new stack-walking API for performance reasons if it's 
available, but if it isn't, the code works but more slowly.

If I was dealing with situations like the above, I think I'd do the following:

1. Work out what kind of API my optional code needed. This is the "provider" 
API; the API that the main module uses to communicate with its own optional 
functionality. I'd define it as a set of interfaces and publish them in an API 
jar (call it "api.jar"). I'd write an OSGi manifest that exported the API, and 
a Java 9 module descriptor that exported the API in the same manner.

2. Write a (Java < 9) implementation of that API and publish it in its own jar 
(call it "jdk8.jar"). I'd write an OSGi manifest that publishes my 
implementation as providing the services declared in "api.jar" and declare it 
as requiring a runtime environment of (Java < 9). I'd add META-INF/service/* 
files that publish the implementation as normal Java services.

3. Write a (Java >= 9) implementation of that API and publish it in its own jar 
(call it "jdk9.jar"). I'd write an OSGi manifest that publishes my 
implementation as providing the services declared in "api.jar" and declare it 
as requiring a runtime environment of (Java >= 9). I'd add a Java 9 module 
descriptor that states that it provides the services defined in the API jar.

I believe with this arrangement that an OSGi container would then automatically 
pick up the right implementation based on the current Java environment and the 
information in the manifest.

Outside of an OSGi container, with a (Java < 9) environment and all of the jars 
placed on the class path, only the implementation in "jdk8.jar" will be picked 
up (because the "jdk9.jar" only declares services via the module descriptor).

Outside of an OSGi container, with a (Java >= 9) environment and all of the 
jars placed on the *module* path, I believe only the "jdk9.jar" implementation 
will be picked up. I'm not exactly certain on this as there may be some 
interaction with Java 9's "automodules" system. Best case, only the (Java > 9) 
service implementation will be picked up. Worst case, they'll both be picked up 
and it'll be the responsibility of the service consumer to pick the "better" 
implementation. You'd need a method defined on the API to allow implementations 
to be ranked in some manner.

It's certainly more work than multi-release jars but, in my opinion it's a more 
disciplined approach. It makes optional and possibly platform-specific 
dependencies explicit and uses a well-understood API (ServiceLoader) to work 
with the code instead of, for example, resorting to class path and reflection 
hacks. This is the standard way to represent optional functionality (or 
multiple implementations) in OSGi and I would guess that it'll become the 
recommended way to do things in Java 9 as it appears to be heavily influenced 
by the methodologies people have arrived at on the OSGi side. Java 9's module 
system appears to be a simpler and far less dynamic clone of OSGi in most 
aspects, so the same techniques tend to apply.

> Maven bundle plugin does not support Java 9 Multi-Release jars
> --------------------------------------------------------------
>
>                 Key: FELIX-5592
>                 URL: https://issues.apache.org/jira/browse/FELIX-5592
>             Project: Felix
>          Issue Type: Bug
>          Components: Maven Bundle Plugin
>    Affects Versions: maven-bundle-plugin-3.2.0
>            Reporter: Ralph Goers
>
> Log4j 2 currently packages its jars with the maven-bundle-plugin. To support 
> Java 9 we are moving towards using Multi-Release jars to pick up the Java 9 
> features.  However, when the Maven bundle plugin encouters classes in 
> META-INF/versions/9 it emits an error message saying "Classes found in the 
> wrong directory:", which is incorrect for a Multi-Release jar in Java 9.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to