Environment:
- Java 17
- Tomcat 9.x
- Maven 3.8.4 (with Codehaus Cargo plugin)
- Gitlab CI/CD
I'm looking for input from anyone that has separated all of their 3rd party libraries into catalina lib (or a custom directory specified via extending catalina.properties 'common-loader') so that the application's war file can be considerably smaller.
Background: We have five webapps which share about 100 3rd party libraries that combined are about 100MB in size. While the applications may have a few unique dependencies the overlap in 3rd dependencies is over 90%.
Our code itself is only 5-15MB and te dependencies don't change frequently compared to our own code. So there's a lot of unnecessary file transfer and unpacking each day/week in our CI/CD.
I'm wanting to improve both deploy startup times as well as remote deploy times (via cargo) as deploying ~115MB remotely to a cluster seems unnecessarily time-consuming given < 15% of the code changes on a typical sprint.
My plan would be to:
- Create a new git project and move all the dependencies that are currently in a parent pom to the new project
- Update the parent pom to reference the new project as a dependency but set scope as provided so those jars aren't included in the war file.
- Write a maven script to package all the 3rd party jars into a fat jar (not a shaded jar)
- Write a sftp/shell script (or use a Maven ssh plugin) to publish the fat jar to the production and staging servers into $(catalina)/lib or a custom directory (added to the common-loader attribute) whenever libraries have version or bug updates which require publishing.
- The existing maven cargo task should run much faster; needing to only transfer 10-15MB. And I suspect that Tomcat should deploy the updated war files faster too since there is so much less to unpack.
Anyone have experience doing this or have any tips/gotchas to be concerned with?
I have a similar situation, which requires common libraries to be on Tomcat classpath. While, there are potentially many approaches, we follow the below process.
We kind of 'build' the Tomcat, not from source code perspective but create directories and put the JARs in specific folders (within catalina.base directory). We have a profile in pom which packages the dependencies of the libraries during building the library.
The dependency in the WAR for the libraries is 'provided'. The WAR does not pack the library JARs or their dependencies.
We then use a script to copy the generated library JARs and their dependencies in the specific folders in the Tomcat. The process is a bit long to explain, below is the script that we use, it is self-explanatory:
Currently we run the above script manually but it can also be dome with Jenkins other CI/CD.
Please not, we don't make an uber-jar