I'm using grails 2.4.4 to develop a web application and Grails (using jetty plugin) is taking around 20 seconds to initialize and make the app available.
I would be okay with this fairly long time but it turns to 3 minutes for older hardware to start up the whole thing and I need it to be faster because once the server has started performance is good and not a concern.
Googling around found out in SO that jar scanning for servlet annotations could be the issue and disabled it for the classes in WEB-INF/lib and added this to the app context xml:
<Call name="setAttribute">
<Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg>
<Arg>nothing.jar$</Arg>
</Call>
This helped cut down the time from 16s to 13s. Also tried building with servlet 2.5 configured instead of 3.0 (And moving to jetty 7) to try to further improve this since annotation scanning is a servlet 3.0 feature but the speed up was minimal (around 1s).
My objective is to bring this time down to 6s since in the oldest hardware I have tested it took around 3 minutes so it is around 10 times slower and a 1 minute startup time would be somewhat tolerable.
Im a little lost on how to achieve this. Looking through the logs saw that context initialization is taking around 2000ms
2017-02-08 02:15:08,318 [main] INFO context.ContextLoader - Root WebApplicatio nContext: initialization completed in 2001 ms
Is there any posibility to speed this up?
If you are using Jetty 9.x then know that the classpath/bytecode scanning is a requirement due its implementation of Servlet 3.1 (which requires it).
Using org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern
only skips those jars in WEB-INF/lib
, but your container classpath is still scanned (meaning everything in your active grails environment).
Note: you should never have a production server kicked from a build tool (maven, grails, etc) as that is a huge performance and security risk.
It is not possible to change the scanning behavior by swapping out the servlet support jar (in fact, you cannot use Servlet 2.5 jar with Jetty, it will fail outright). What you are actually doing with that Servlet 2.5 jar swap is changing your Application's support level, not the behavior in Jetty.
But all is not lost, you can "precalculate" the scanning requirement and use the quickstart
features of Jetty 9 to start your application by feeding it what it needs, avoiding the repeated scans on each start.
The quickstart technique is used heavily by cloud providers to have near instantaneous startup of web applications (sub 500ms usually).
Note: if you are using hibernate, spring, cdi, or other libraries that have their own Annotations, then there is very often another bytecode scanning step performed by that library, not Jetty.