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.
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)

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 <mailto:r...@apache.org>> a écrit :

    On Mon, Jul 13, 2020 at 11:59 PM Filip Hanik <fha...@vmware.com
    <mailto: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

Reply via email to