JEP 238: Multi-Version JAR Files
Remi Forax
forax at univ-mlv.fr
Sun Mar 1 23:37:57 UTC 2015
On 03/01/2015 07:08 PM, Peter Levart wrote:
Hi Peter,
You can see the whole thing in the opposite way which I think is less
disruptive in term of tooling.
You only maintain one module which depend on the latest version.
When you ship the module let say as a jar, you also ship the way to
downgrade it as an executable code.
At install time, when all the modules are known, before trying to create
the images,
the code that downgrades the module is executed if necessary.
This code can rewrite the whole bytecodes of all the classes the module
thus ensure backward compatibility without providing binary backward
compatibility.
It's a win-win-win strategy, your code doesn't live in the past, the
bytecode rewriter can fail saying there is a problem before runtime (if
by example a method is missing), you can break the binary backward
compatibility if this is necessary and still being compatible.
You can see this mechanism as a kind of annotation processor that will
be executed at install time instead of at compile time.
cheers,
Rémi
> On 03/01/2015 12:53 PM, Remi Forax wrote:
>> Currently, there are two ways to solve the Base64 issue:
>> - by loading at runtime either the class that use java.util.Base64 or
>> the class sun.misc.BASE64Decoder and use it through an interface
>
> And this, I think, is also the cleanest way to approach a problem that
> multi-version JAR wants to solve. The only argument against it is that
> it perhaps requires more work and planing, but that doesn't mean it is
> less maintainable. In general one has to split the software into
> "modules":
>
> - base module (platform independent code) + facade interfaces to
> access platform dependent functionality
> - platform dependent module(s) that depend on base module and contain
> implementations of facade interfaces published as services through
> ServiceLoader - one module per "target platform version" / "platform
> dependent feature" combination
>
> Base module is compiled 1st (it does not depend on platform version,
> so it should be compiled with lowest version javac/rt.jar to be able
> to run on any target platform)
>
> Platform dependent module(s) are compiled against classes of base
> module and with javac/rt.jar of the desired target platform(s).
>
>
> Now if module system of JDK9 had a feature that would enable/disable
> the deployed module conditionally, then that condition could be an
> exact target platform version.
>
> But I know, multi-version JAR wants to solve similar problem for
> pre-JDK9 target platforms too which don't yet have modules. The
> approach to organizing sources and compiling can be the same as
> described, just packaging can then use multi-version JARs instead of
> "conditional" modules.
>
> One problem I see with requirering that in multi-version JARs each
> version sub-path must have same public classes with same public APIs
> is that IDEs don't like that. They don't like to see multiple versions
> of same class and they paint them red. Refactoring doesn't work
> correctly if IDEs see multiple versions of same class and can never be
> made to work correctly as it would have to keep versions always in
> sync. I always have problems with IDEA when I present it the
> unix/windows versions of classes in JDK build at the same time. This
> can be solved nicely by not requirering that and simply relying on the
> programmer that (s)he knows what (s)he is doing. With interfaces as
> services and implementations locateable via ServiceLoader, one does
> not have to use same names of classes for implementations of
> interfaces targeting different platforms and IDEs will be happy.
>
> Regards, Peter
>
More information about the core-libs-dev
mailing list