чт, 7 окт. 2021 г. в 18:46, Mark Thomas <ma...@apache.org>:
>
> Hi,
>
> As you will have seen from the 8.5.72 release vote and/or bug 65599
> there is an issue with 8.5.x, Java 17 and ECJ.
>
> In short:
> - the Java EE 7 spec requires that Tomcat 8.5.x runs on Java 7
> - Tomcat 8.5.x ships with ECJ 4.6.3, the newest version that runs on
>    Java 7
> - ECJ 4.63 fails on Java 17 onwards
>
> I was wondering about shipping two versions of ECJ. Using 4.6.3 if
> running on Java 7 and 4.20 (or whatever Tomcat 9 onwards is using at the
> time) if running on Java 8.
>
> The implementation could go in ClassLoaderFactory.validateFile(). The
> idea is that it would skip adding the ECJ version that wasn't required
> to the class path. It would be a bit of a hack and it would almost
> certainly need to be hard-coded rather than configurable in anyway.
>
> This isn't the only way I can think of to do this but it is the one that
> requires the least user input (none) and is the least 'hacky'.
>
> Thoughts?
>
> Is this a problem worth solving? If it is, is there a better way?

Hi!

Last few days I was thinking of the following approaches:
(Let's count your approach of changing
"org.apache.catalina.startup.ClassLoaderFactory#validateFile()" as a))

Approach b)
Ship both ecj-4.6.3.jar and ecj-4.20.jar (or later) in separate
directories in ${catalina.home}, and let an a admin to choose one with
common.loader setting in the ${catalina.base}/conf/catalina.properties
file.

This is:
1. Create two subdirectories in "${catalina.home}/lib/": "ecj" and "ecj-legacy".
2. Move ecj-4.6.3.jar from ${catalina.home}/lib/ into
${catalina.home}/lib/ecj-legacy/
3. Add ecj-4.20.jar (or later) into ${catalina.home}/lib/ecj/
4. Add "${catalina.home}/lib/ecj-legacy/*.jar" to the default value of
common.loader setting in catalina.properties file.

Expectations:
- If one wants to run this version of Tomcat 8.5 on Java 17, they can
edit the ${catalina.base}/conf/catalina.properties file and change the
path to "${catalina.home}/lib/ecj/*.jar".

Advantage:
- It allows one to explicitly select the version of the library.
- I have personal experience with this approach. (In my dev
environment I have several database drivers in such distinct
directories in my ${catalina.home}". When I configure an instance of
Tomcat in Eclipse IDE to test my apps, I update configuration to
choose the one that I need.)

Disadvantage:
- If somebody already has a configured instance of Tomcat 8.5,
upgrading to this version will require editing the existing
catalina.properties file due to the changed defaults.
- This approach targets standalone installations of Tomcat. I have not
thought of what to do when Tomcat is launched with Tomcat class
instead of Bootstrap. I have not thought about how to update Tomcat
tests.


Approach c)
The same as b), but invent additional syntax for the "common.loader"
setting to allow excluding libraries from the class path.

This is:
- The ecj-4.6.3.jar file is not moved and stays in ${catalina.home}/lib/
- The Java 17 version of the common.loader setting looks like the following:
xxx,!"${catalina.base}/lib/ecj-4.6.3.jar","${catalina.base}/lib/ecj/*.jar",xxx
where !"foo" is the new syntax to exclude a library.

Approach d)
The same as c) but instead of the new syntax we have some magic to
remove duplicates.
- The Java 17 version of the common.loader setting looks like the following:
"${catalina.base}/lib/ecj/*.jar",xxx
- Both ecj-4.20.jar and ecj-4.6.3.jar are present in the classpath,
but some magic (a regexp? a helper class?) removes the latter as a
duplicate.

Approach e)
Combine ecj-4.6.3.jar and ecj-4.20.jar (or later) into a single
multi-release jar, "ecj-4.3.6_and_4.20.jar".
See
https://openjdk.java.net/jeps/238

I mean that
- The META-INF/MANIFEST.MF file is replaced with one that has the
attribute "Multi-Release: true", and all other attributes except
Main-Class are removed. (I think that "Export-Package", "Bundle-Name",
"Bundle-Version", "Bundle-ClassPath" are to be removed. The
ecj-4.20.jar is signed. Those signatures are to be removed as well).
- The ecj-4.6.3.jar classes stay where they are.
- The ecj-4.20.jar classes go into META-INF/versions/9/

I do not quite like this approach, but I tested it and it works.


Best regards,
Konstantin Kolinko

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

Reply via email to