Le lun. 20 juil. 2020 à 17:41, Filip Hanik <fi...@hanik.com> a écrit :
> Thanks for chiming in: > On 7/16/20 6:46 AM, Romain Manni-Bucau wrote: > > Hi everyone, > > I think the generation is the sanest option since code stay clean but it > shouldn't be done in tomcat IMHO but in user code and with a nice wrapper > (mvn tomcat:dump/gradle tomcatDump etc, or whatever name you like ;)). > > That's always an option, but it would become an external artifact and > easily end up out of sync. > Was thinking to keep the dumper in tomcat code base and the plugin to consume it so it would stay in sync, but agree it is a small risk. > This build phase would dump the descriptors in plain java and would load > them with an unique - ie single for the whole webapp - plain SPI - > ServiceLoader - maybe? > > The goal of this artifact was to reduce the size and classes from a full > tomcat (already available in tomcat-embed-core), down to a code base where > XML/digester/descriptors aren't used, hence tomcat-embed-programmatic > > This kind of build tool assumes you have all the runtime state in the > build - which is typically the case for graalvm - so you can completely > dump StandardContext state after start phase there and just reload it from > the precomputed model. > Only trick is about file paths which must either be recomputed or be > configurable to another base but it does not sound crazy. > > The less tool-ed option would be to extract all "reflectionfull" code in > methods and use graalvm substitutions to drop them and use plain java > instead (with a good naming convention, it can be generated as well). > Keeps the duplication but at least the main code stays clean and > optimizations stays together. > > That's pretty much what we're doing right now. Many of these feel like > hacks simply to mitigate how GraalVM/AOT does code initialization (all code > loaded initialized at startup) > Reviewing the hacks, all can be done cleanly if extracted in methods. Pushing the logic next step - I don't know if worth it but trying to use this picture to explain: 1. A noxml module can be done with protected methods/extension-points for XML loading - even usable in java standalone mode 2. Current tomcat can extend noxml module 3. Graal can be based on 1 This would benefit both jvm and graal users at the end. Today 1 is possible with some hacks on tomcat embedded but it is highly not natural so this can be an opportunity to make it a feature maybe? > Filip > > > > Romain Manni-Bucau > @rmannibucau <https://twitter.com/rmannibucau> | Blog > <https://rmannibucau.metawerx.net/> | Old Blog > <http://rmannibucau.wordpress.com> | Github > <https://github.com/rmannibucau> | LinkedIn > <https://www.linkedin.com/in/rmannibucau> | Book > <https://www.packtpub.com/application-development/java-ee-8-high-performance> > > > Le jeu. 16 juil. 2020 à 14:31, Rémy Maucherat <r...@apache.org> a écrit : > >> On Mon, Jul 13, 2020 at 11:59 PM Filip Hanik <fha...@vmware.com> wrote: >> >>> for discussion, all feedback and questions welcome: >>> >>> >>> I've created a concept of having Apache Tomcat, embedded, run without >>> reflection in a native image. >>> This concept creates a jar, tomcat-embedded-programmatic.jar, that can >>> be fine tuned to only include what is needed in a default configuration >>> when an embedded tomcat instance is used and configured programatically. >>> >>> Steps to run Apache Tomcat using Java 8 without reflection >>> >>> 1. Make sure you have native-image (from the graal installation) on >>> your path >>> 2. git clone -b feature/embed-minimal-programmatic-jar-file-master >>> g...@github.com:fhanik/tomcat.git >>> 3. cd tomcat/res/graal/ >>> 4. ./build-tomcat-native-image.sh && ./graal-measure.sh >>> >>> Should yield an output similar to (Graal 20.1): >>> SUCCESS: the servlet is working >>> RSS memory: 20.7M >>> Image size: 20.5M >>> >>> >>> or using an older graal, 19.2 >>> SUCCESS: the servlet is working >>> RSS memory: 18.0M >>> Image size: 16.7M >>> >>> >>> This also leaves a file named ${java.io.tmpdir}/ >>> XReflectionIntrospectionUtils.java so that you can review the solution >>> to IntrospectionUtils.java >>> >>> Goals of this concept >>> >>> 1. Do not break anything >>> 2. Create a new and optimized for size artifact, >>> tomcat-embedded-programmatic >>> 3. Remove reflection by introspecting classes that are currently >>> passed into IntrospectionUtils.set/getProperty by generating >>> setters/getters at build time >>> >>> How it's done >>> >>> 1. I've build out a small introspection tool in the package >>> org.apache.tomcat.util.xreflect >>> 2. During build time, it analyses a set of known classes that are >>> used with IntrospectionUtils.java, and generates >>> XReflectionIntrospectionUtils.java >>> 3. When it packages tomcat-embed-programmatic.jar it uses the >>> generated code when calling setProperty and getProperty >>> >>> A PR would look like this: >>> >>> https://github.com/apache/tomcat/compare/master...fhanik:feature/embed-minimal-programmatic-jar-file-master?expand=1 >>> >>> >> Well, this is a bit complex and hard to maintain (like, for example, >> storeconfig), so that's a downside. >> >> So starting with Tomcat and its initial server.xml, the process would be: >> server.xml -> equivalent Tomcat embedded code -> equivalent Tomcat >> embedded code with custom IntrospectionUtils code >> The concrete benefits may be limited though. >> >> I looked at more code generation for web.xml since the digester is nice >> for that, but the benefit becomes even more questionable. It is harder to >> manage, and the generated classes have to be loaded dynamically [unless >> even more code is generated]. If there are tons of fragments, there is a >> good intuitive reason why it becomes useless. so I didn't want to do it. I >> prefer if things remain a bit EE-ish, ultimately. >> >> Rémy >> >>