Hi,

Following up on this because I have been looking at a multi-release JAR
approach for bug 61597 [1] and the current JreCompat implementation.

On 23/09/17 19:02, Rainer Jung wrote:
> Forgot the reference: http://openjdk.java.net/jeps/238
> 
> Am 23.09.2017 um 20:01 schrieb Rainer Jung:
>> Am 23.09.2017 um 17:22 schrieb Mark Thomas:
>>> On 23/09/17 16:10, Rainer Jung wrote:
>>>> Thanks Mark!
>>>>
>>>> You might also want to look at r1809434 as a candidate and check
>>>> whether
>>>> that workaround looks OK for you.
>>>
>>> Looks good to me. I've added to the list of J9 back-port candidates. It
>>> does beg the question whether or not we want to look at switching to
>>> multi-release JARs for all of the compatibility code. WDYT?
>>
>> Indeed, I ran my first multi-release Jar experiment (successfully)
>> today. For those who haven't yet seen it: starting with Java 9 one can
>> include instances of a class in a jar file that will only get used
>> when a specific JVM (major) version is detected at runtime. You can
>> e.g. have a default one as usual plus additional ones for specific
>> Java runtime versions. For Java 9 one would add a class at
>> META-INF/versions/9/org/apache/juli/... which would then be picked
>> when the runtime Java version is 9.
>>
>> The enable the feature, one simply has to add the attribute
>>
>> Multi-Release: true
>>
>> to the Manifest file of the jar.
>>
>> Thinks that come to my mind:
>>
>> - you can have multiple versions of the same class. If we would use it
>> like that, we would have to slightly reorganize our svn layout to
>> reflect that, e.g. java/org/... plus new java9/org/....

Having looked at a couple of options I settled on that one too.

I haven't yet found an IDE with a GA release that handles this. Support
in the tools is fairly embryonic as well.

>> - accordingly we would need e.g. a directory output/classes9 or similar.

I went for classes/META-INF/versions/9 so it mirrored the JAR structure
but that probably isn't essential. One advantage was that - with my
other build.xml changes - supporting additional versions was minimal
effort.

>> - If we need Java 9 for compilation of the Java 9 classes, we would
>> mimic the Java 7 lines from the TC 7 build.xml.

For the JreCompat code, we would need this. This is where most of the
complexity was added for this approach.

>> - To add the Java 9 classes to one of our jars it would suffice in
>> build.xml to do something like
>>
>> <jar jarfile="${somefile.jar}" update="true">
>>    <manifest>
>>      <attribute name="Multi-Release" value="true"/>
>>    </manifest>
>>    <zipfileset prefix="META-INF/versions/9/" dir="${tomcat.classes}9"/>
>> </jar>

I took a slightly different approach. I extended the existing jarIt
macro and provided a default.mr.manifest. We'd also need to decide how
to handle the source JARs in this case. I didn't implement it but my
conclusion was we should mirror the structure of the binary JARs.

>> - to reduce redundant maintenance it would be good to factor out JVM
>> dependent code, so that the classes we have to maintain multiply
>> mostly contain the code that's really version-dependent.

Big +1. I looked at removing JreCompat entirely but that would have
required a lot of duplication. We have some large classes that only need
one or two lines of Java 9 code.

>> For instance when using the feature for my Java 9 change in Juli
>> http://svn.apache.org/viewvc?rev=1809434&view=rev one could use e.g. a
>> small but version dependent Constants.java which would provide the
>> correct directory name ("lib" versus "conf"). Or more easily a one
>> line properties file available in two versions providing the directory
>> name.
>>
>> I have not made any check on performance implications for the slightly
>> more complex class loading. What I did see, is that -verbose:class
>> does not indicate, which of the versions was chosen.

I haven't checked performance either. My working assumption is that if
it is an issue, the JVM vendors will have to address it somehow.

>> I currently do not have a real insight on how our most important JVM
>> version dependencies look. I guess how useful multi-release is, might
>> depend on the type of code dependencies we have.

With the fix for bug 61597 applied the MR JAR approach looks to use
slightly less code (maybe ~20 lines overall including comments).

So, comparing the MR approach vs continuing with the reflection approach:

MR uses less code but requires more complexity in the build script.
Overall, MR requires slightly less code.

MR means release builds will required Java 8 and Java 9 (or just Java 9
with a risk we add a hard Java 9 dependency without realising).

MR is not handled well by IDEs requiring manual inclusion / exclusion of
source files (or multiple projects) to switch between the different
versions.

I do like the reduction in code and the build script complexity doesn't
concern me overly - it is mostly adding volume rather than an complex
logic. The IDE issues are more annoying.

Overall, I'm torn. I guess I'm +0 on switching at this point. What does
everyone else think?

Mark


[1] https://bz.apache.org/bugzilla/show_bug.cgi?id=61597


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to