- 
                Notifications
    You must be signed in to change notification settings 
- Fork 41.6k
Description
I am working on graal native-image compilation for tomcat based Spring-Boot applications (as part of my work on https://github.com/spring-projects-experimental/spring-graal-feature ). Base tomcat has made some tweaks to recognize when it is in graal environment and behave slightly differently. Where boot extends tomcat it is currently not including similar tweaks but I think still needs them.
With these changes locally applied in a patch I have an embedded tomcat Spring Boot example working.
There are three tweaks required, all in TomcatEmbeddedWebappClassLoader:
1 - Guard the call to ClassLoader.registerAsParallelCapable()from the static initializer:
if (!JreCompat.isGraalAvailable()) {
	ClassLoader.registerAsParallelCapable();
}
Although... given the parent class static initializer makes the call, do we really need to make that call at all in our subclass?
2 - Guard the call to getClassLoadingLock(name) in loadClass:
	synchronized (JreCompat.isGraalAvailable() ? this : getClassLoadingLock(name)) {
3 - Guard the call to findLoadedClass(name) in findExistingLoadedClass:
resultClass = (resultClass != null || JreCompat.isGraalAvailable()) ? resultClass : findLoadedClass(name);
Without these changes a native image compiled boot app will fail at runtime because graal doesn't implement those methods, with errors like this:
com.oracle.svm.core.jdk.UnsupportedFeatureError: Unsupported method java.lang.ClassLoader.findLoadedClass(String) is reachable: The declaring class of this element has been substituted, but this element is not present in the substitution class
        at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:102)
        at java.lang.ClassLoader.findLoadedClass(Target_java_lang_ClassLoader.java:1036)
The above changes are all using the tomcat support class JreCompat.  I'll submit a PR shortly.