0

I created a gradle task that deploys an unpacked WAR package to a specific directory. Tomcat is configured to use exactly that directory as web application and deploy the package including reloadable="true".

As long as I run the task manually using ./gradlew explodedWar --parallel every time something changes everything works fine. The directory is rebuilt (not cleaned but updated) and tomcat reloads the application a few seconds later.

Anyway as soon as I try to use continious build feature of Gradle using ./gradlew explodedWar -t --parallel it doesn't really work anymore. Gradle rebuilds on every change automatically but Tomcat crashes very often leading the application to return nothing but 404 anymore.

Has anybody any idea why this might happen? There is no error in the Tomcat log. Furthermore I guess the -t option should basically be the same as calling gradle manually after any change. But in the later case Tomcat does never crash.

Edit: After some further testing I got this error from Tomcat. This happens only about 1/20 times of the crashes so it might not be related but I guess Gradle rebuilds while Tomcat is loading the JAR files.

Caused by: java.lang.IllegalArgumentException: java.util.zip.ZipException: error in opening zip file
        at org.apache.catalina.webresources.JarResourceSet.initInternal(JarResourceSet.java:96)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        ... 14 more
Caused by: java.util.zip.ZipException: error in opening zip file
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:225)
        at java.util.zip.ZipFile.<init>(ZipFile.java:155)
        at java.util.jar.JarFile.<init>(JarFile.java:166)
        at java.util.jar.JarFile.<init>(JarFile.java:103)
        at org.apache.catalina.webresources.JarResourceSet.initInternal(JarResourceSet.java:88)
        ... 15 more
Werzi2001
  • 2,035
  • 1
  • 18
  • 41
  • Can you check your tomcat process to see if it has a parent? – Gerard H. Pille Feb 11 '18 at 17:07
  • @GerardH.Pille According to `/proc` it has a PPid of 1 which is `/sbin/init`. I guess this is some kind of default. Tomcat was started manually and not automatically during startup. – Werzi2001 Feb 12 '18 at 10:30
  • And you're sure that if you did the same number of deployments manually, there would be no problem? Nothing in the catalina logs about objects that could not be garbage collected on redeploying your application? – Gerard H. Pille Feb 12 '18 at 12:28
  • Yes. I work manually building for hours and nothing crashes. Doing the same using `-t` usually takes minutes till the next crash. – Werzi2001 Feb 12 '18 at 12:46
  • You'd expect Tomcat to log something. What about Gradle itself, if you try to enable debug logging? – Gerard H. Pille Feb 12 '18 at 12:52
  • I guess it's some kind of timing problem. E.g. Gradle building when Tomcat is reloading or whatever. But yes I'd expect a log entry too. Gradle outputs a lot of log in debug mode but I don't know what to do about it. Nothing seems to be an error. The result from Gradle seems to be fine anyway. After Tomcat restart it runs fine (without rebuild). – Werzi2001 Feb 12 '18 at 13:20
  • I can imagine Tomcat being unhappy if Gradle does two builds in a row. But that would be the same manually. Maybe reduce the logging somewhat and compare the log from a manual with a continuous build? – Gerard H. Pille Feb 12 '18 at 13:27
  • Now I got an error from Tomcat (extended the post). I guess when building manually there always is some kind of time deplay between builds. Using `-t` this might not be the case if I change two files after each other. Seems that Tomcat doesn't recover from that error. Is there a solution? – Werzi2001 Feb 12 '18 at 14:13
  • Well, you've got more experience with Gradle than I do (none whatsoever), but there is an option in Gradle continuous build that tells him not to restart the build if he notices a change during the first build. – Gerard H. Pille Feb 12 '18 at 16:45
  • When Tomcat complains about the zip, would that in reality be the war file? Where does Gradle put the war he built? – Gerard H. Pille Feb 12 '18 at 16:49
  • I didn't know about the option. I'll try that, thanks. I guess it's about a JAR file. The Gradle project consists of multiple sub projects all build JAR files. Tomcat doesn't see a WAR file as it is extracted to the directory that Tomcat is configured to. – Werzi2001 Feb 13 '18 at 08:11
  • What option do you mean? I don't see a Gradle parameter that does what you described. – Werzi2001 Feb 13 '18 at 08:51
  • You are looking for trouble with "it is extracted to the directory that Tomcat is configured to". Tomcat will start working on your application before you finished writing, can even happen with a war. What you need to do is, put the archive in a folder that Tomcat doesn't know about, when you finished, put a context.xml file (called eg. myapp.xml) in /conf/Catalina/localhost/, containing the location of the war (docBase?). This way, Tomcat will never start working on the war before you' ve finished. My Tomcat runs 40 odd applications, without restarting for months. – Gerard H. Pille Feb 13 '18 at 10:06
  • I'm looking for the option. In the mean time, are you sure this is meant to be used with Tomcat? I read the following: "It depends on the nature of your Spring Boot application. If you app typically runs and then exits then continuous build will work. However if your app typically stays alive indefinitely, for example because it's a web app that handles HTTP requests, then it won't work. ..." (https://stackoverflow.com/questions/31512195/does-gradle-continuous-build-support-springboot) – Gerard H. Pille Feb 13 '18 at 10:27
  • Wasn't an option, this is what I read: https://discuss.gradle.org/t/war-plugin-causes-continuous-to-run-continuously/18074 – Gerard H. Pille Feb 13 '18 at 10:40
  • Thanks for your help but I don't see how the e.g. myapp.xml could solve my problem. As a build occurs on every change this would lead to hundreds of XMLs with different build directories? Maybe continious build is really not made for Tomcat/web apps. – Werzi2001 Feb 14 '18 at 08:35
  • Not at all. Each time you would overwrite the previous war. Tomcat wouldn't budge. Then you overwrite the myapp.xml - with exactly the same information. Now Tomcat will notice a change of modification date and start redeploying. We don't overwrite the wars, because we add a version number. I do have to remove the old wars now and then. Advantage: we can fall back on the previous version if needed. – Gerard H. Pille Feb 14 '18 at 21:06
  • Now I get it. I'll try that. – Werzi2001 Feb 15 '18 at 08:49
  • Any problem, add a comment here. – Gerard H. Pille Feb 15 '18 at 09:14

0 Answers0