Commits
Tarun Sukhani authored 61d5593e042
feat(bundle): carry the precompiled classes as one jar in a bundle or dist
A deployed application carried its precompiled classes as a tree of
files, two thousand of them for a large application, and Play looked
each one up on disk at every start.
play bundle and play dist now pack that tree into
precompiled/classes.jar as they build the artifact. play precompile and
an application started from its working copy are unchanged: they keep
the precompiled/java tree, and nothing is written into the working
copy's precompiled/. A .distignore entry below precompiled/java/ keeps
its classes out of the jar.
The framework reads the jar where the application has one and the tree
otherwise (play.classloading.PrecompiledJar). The jar is not on the JVM
classpath: Play's class loader still defines the classes, so the class
registry and conf/ lookups through application classes are as before.
A tree found beside a jar, the leftover of an older install, is ignored.
The jar is packed inside the packaging task's action, so a build step
that rewrites precompiled/java before packaging (a ProGuard strip, for
one) keeps working unchanged and ends up in the jar. For processing on
one jar there is a playPrecompiledJar task
(build/play/precompiled/classes.jar) and a precompiledJar property on
both packaging tasks that ships a supplied jar as it is. Entries are
sorted, stored and stamped with one fixed time, so the jar is
reproducible.
Measured on jclaw's bundle (2,022 classes, production JVM options,
JDK 25.0.2, medians of ten starts, same bundle with the jar and with
the tree):
tree jar
classes, no cache 158 ms 82 ms
classes, AOT cache 106 ms 43 ms
Started in, no cache 3,128 ms 3,005 ms
Started in, AOT cache 1,917 ms 1,899 ms
Upgrade note: anything that looks into precompiled/java of an installed
bundle or dist has to look into precompiled/classes.jar instead.
Docs: "The classes in a bundle or dist" in deployment.textile, with
both ProGuard routes; AGENTS.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDUoh3KhBpfjXn4rV6H356