📜 ⬆️ ⬇️

Ant + Tomcat: a little routine automation

Good day to all. I decided to write a note about small automation tools that arose in the course of my work with a bunch of Ant + Tomcat. I work as a java-developer, recently I had to plunge into web development in Java (I must say, not without pleasure). I have never come across serious projects for web on java, played a couple of times with examples in java books from the series “about everything for a bit”, but nothing serious. And here is a project from a full-fledged portal with backend `for content responsible, large amounts of data in the database. Well collided and collided. The work has gone, a new area of ​​knowledge is interesting, little things are missing. But over time, the process of assembling and deploying the application began to get very bad, because on the hottest days you had to perform this operation 40 times each to see the result of the work and click it. Here the question arose whether it is impossible to automate it.

For those who, just like me before, do not particularly represent the process of building and deploying web applications in Java, I will write a bit more in detail.

1. So, the application must be assembled. This can be done through the IDE, but on large projects, where several developers and everyone can have their own IDE, it is better to use ANT - universally and conveniently. So we do the assembly, like this: ant jar. I build one jar module in our project on average takes 15-20 seconds. The web application itself is a war file (similar to the jar file in Java SE). But the final war file can have (and usually has) several dependencies on jar-files of other modules. Accordingly, if the code of the module on which the final war-file depends, then we first reassemble the module, then build the application itself. We have such modules 2, as a rule, in the process of work, changes go within one module, although it sometimes happens that both modules need to be rebuilt or nothing needs to be reassembled (except for the final war, in the code of which something has changed). In general, as a rule, 1 module is rebuilt. Therefore, the sequence of commands will be as follows:

 cd { } ant jar cd {  } ant war 

As a result, we get the war file of the application. On the assembly, taking into account switching between directories takes 50-60 seconds. I’ll say right away that there are two final project files in the project: the public part and the closed part, and for the general assembly there is itself its own command, but its inconvenience is that the “unnecessary” war is being built now, which is also a time.
')
2. In order to see the application itself in action, the resulting war file must be deployed on the server. To do this, we go through the browser to the Tomcat control panel, delete the old version of the application (if it was), specify the location of the new war-file and wait some time (40-60 seconds), after that we can start “feeling” the created application.

I do not write about the approximate time of the assembly and deployment of the application - in the sum, these two seemingly simple steps take 2-3 minutes. It seems a little, but with frequent changes or finding a solution to some bug, you have to rebuild the project again and again, do undeploy (delete) the old version of the application from the server, and then deploy (deploy) the new version of the application. It happens that in a day you repeat this operation a few times, and sometimes, as I wrote above, this operation is repeated dozens of times. As a result, the question of optimizing this process arose by itself, since repeating this operation 10-20 times leads to costs in 30-60 minutes. Well, if at this time one could be distracted from the computer, it turns out that the dense participation of a person is necessary.

At first, the idea arose in ant to add one command to perform step # 1 (separately for each war), but then the question “can I automate step # 2?”, That is, teach ant to manage the deployment of the application on tomcat. A little search in Google, I found several solutions of which I collected my own, taking some moments from each.

I will omit the process of building an application in ant, as it is described in any reference material for this utility, and it is also specific for each individual project. Immediately proceed to the solution of step number 2.

First of all, you need to know if there is a tomcat in the system so that it has something to work with:

 <target name="if-has-tomcat"> <property environment="env"/> <condition property="has.tomcat"> <available file="${env.CATALINA_HOME}"/> </condition> </target> 

We create the task “if-has-tomcat”, the essence of which is to check the availability of the directory specified in the CATALINA_HOME system variable and present the result of this check as a variable “has.tomcat”. The expression property environment="env" just allows you to access system variables.

Now that we know that tomcat is in the system, we can connect its libraries, which will allow tomcat to be managed from ant. At the same time here we will check if there is an old version of the war-file on the server.

 <target name="check-if-deployed" depends="if-has-tomcat" if="has.tomcat"> <property name="tomcat.home.dir" location="${env.CATALINA_HOME}" /> <property name="tomcat.base.url" value="http://localhost:8080" /> <property name="tomcat.manager.url" value="${tomcat.base.url}/manager/text" /> <property name="tomcat.user.name" value="login" /> <property name="tomcat.user.password" value="password" /> <condition property="is.webapp.deployed"> <http url="${tomcat.base.url}/${ant.project.name}" /> </condition> <path id="tomcat.classpath"> <!-- We need the Catalina jars for Tomcat --> <fileset dir="${tomcat.home.dir}/lib"> <include name="catalina-ant.jar"/> <include name="tomcat-coyote.jar"/> <include name="tomcat-util.jar"/> </fileset> <fileset dir="${tomcat.home.dir}/bin"> <include name="tomcat-juli.jar"/> </fileset> </path> <!-- Configure the custom Ant tasks for the Manager application --> <taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask" classpathref="tomcat.classpath"/> <taskdef name="list" classname="org.apache.catalina.ant.ListTask" classpathref="tomcat.classpath"/> <taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask" classpathref="tomcat.classpath"/> <taskdef name="findleaks" classname="org.apache.catalina.ant.FindLeaksTask" classpathref="tomcat.classpath"/> <taskdef name="resources" classname="org.apache.catalina.ant.ResourcesTask" classpathref="tomcat.classpath"/> <taskdef name="start" classname="org.apache.catalina.ant.StartTask" classpathref="tomcat.classpath"/> <taskdef name="stop" classname="org.apache.catalina.ant.StopTask" classpathref="tomcat.classpath"/> <taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask" classpathref="tomcat.classpath"/> </target> 

First, we declare the necessary variables for working with tomcat: home folder tomcat, URL tomcat, URL manager, login and password. Then we create a condition that checks whether the application is already hosted (that is, before deploying a new version of the application, you will need to delete the old one). Here $ {ant.project.name} contains the name of the application that is declared above (I declared in the header of the ant script, because this variable is involved in the project build task). The next step is to connect the libraries that allow you to manage the server via ant. Well and the last - we declare tasks for ant for control of tomcat.

Now that we know all the source data, you can delete the old version of the war file (if it exists) - the undeploy command and deploy the new war file - the deploy command.

 <target name="undeploy" depends="if-has-tomcat, check-if-deployed" if="is.webapp.deployed"> <!-- TOMCAT undeploy--> <undeploy url="${tomcat.manager.url}" username="${tomcat.user.name}" password="${tomcat.user.password}" path="/${ant.project.name}" /> </target> <target name="deploy" depends="clean, war, if-has-tomcat, undeploy" if="has.tomcat"> <!-- TOMCAT deploy--> <deploy url="${tomcat.manager.url}" username="${tomcat.user.name}" password="${tomcat.user.password}" path="/${ant.project.name}" war="${dist.dir}/${ant.project.name}.war" /> </target> 

Here, by and large, nothing complicated. The ant deploy command is always used, which cleans all folders with class files (clean), then builds the war file (war), then checks for tomcat (if-has-tomcat), then with a positive outcome of the previous check, executes undeploy which checks for the presence of the old version of the war file on the server and, if necessary, deletes it, well, and last of all, the application is directly deployed to the server. The war property in the deployment case just indicates where the new war file is located.

The undeploy task, as seen in the same way as in deploy, checks for the presence of tomcat in the system. This is done so that you can safely execute ant undeploy command.

As a result, it turned out that everything is performed by one command - ant deploy. Then you can take a break for 1-2 minutes - ant will do everything himself. Pure assembly and deployment time remains the same, but the savings in this project on "manual" clicking and driving in several commands amounted to 1-1.5 minutes from each deploy. What a day comes in 20-30 extra minutes and most importantly: deploy is performed using one command and does not require attention, that is, during assembly and deployment, you can distract a little and relax.

Source: https://habr.com/ru/post/134568/


All Articles