Maven - Deploy Large Military Files

This question is somewhat similar to this Best way to deploy a large * .war on tomcat so that it reads well at first, but keep reading my qs, these are different at the end ...

Using maven 2, my war files are terribly large (60M). I put them on a set of tomcat servers, and just copying the files takes too much time (this is about 1 m to the war).

In addition, I added an RPM level that packs war in an RPM file (using the maven rpm plugin). When the RPM is launched on the target machine, it will clear, β€œinstall” the war (just copy it), stop and start tomcat (what we do here, without hot deployments) and configure the proper context file in place. All of this works great.
The problem, however, is that the RPM files are too large and slow to copy. That occupies almost all of the space, of course, is a military file.

I have not seen any ready-made solution, so I'm going to implement it myself, so I will describe it below, and this description, we hope, will help explain the problem area. I will be glad to hear your thoughts on the planned solution, and even better to point out other existing solutions and random advice.

War files contain:

  • Applied banks
  • Third Party Banks
  • resources (properties files and other resources)
  • WEB-INF files such as JSP, web.xml, struts.xml, etc.

Most of the space is occupied by # 2, third-party banks.
Third-party banks are also installed on the internal server for communication that we have in the company, so I can take advantage of this.

You probably guessed that at the moment the plan is to create subtle wars that will include only application banks (created by my company), WEB-INF resources and materials, and adding the ability to install an RPM script that will copy third-party banks if necessary.
RPM allows you to run arbitrary scripts before or after installation, so the plan should use mvn to write a list of third-party dependencies when creating a war and adding it as a resource in RPM, and then when installing the RPM installation, the RPM script will work on the list of necessary third-party banks and load new banks from nexus only if they do not already exist.
RPM will have to remove banks if not in use.
RPM will also have to either rebuild the war for tomcat to detonate it, or add third-party banks to common / lib or something like that, although we have several web applications for one cat, so in this sense this will complicate the situation. Perhaps explode the jar yourself, and then copy the third-party jars to WEB-INF / lib

Your input is welcome :)

+4
source share
2 answers

We have a catalog on target machines with all the third-party banks that we use (about 110 MB). Banks use a naming convention that includes their version number (asm-3.2.jar, asm-2.2.3.jar ...). When you add a new version of a third party, we do not delete the older version.

When deployed, our jar files contain only the classes and business logic resources that we compile in the assembly (without a third party). The class path is defined in the jar manifest , where we choose which third party it should use at runtime. We do this with ant, maven is not involved, and we have more than 25 types of services in our system (very "soa", although I don’t like it in a buzzing word). This ATM of business logic is the only bank in the jvm class path when the process starts, as well as the code version of our code repo code number. If you go back to an older version (rollback) of our code that an older third-party ATM can use, it will still work, since we are not deleting old banks. New third-party banks must extend to production machines before the business code that uses them. But once they are there, they will not be redirected to each deployment.

In general, we tend to be simple (i.e. not OSGi), and we do not use Maven.

+1
source

I would advise you to propose your plan. This sounds like a lot of moving parts that are probably hard to test and / or diagnose problems when they arise.

We have no problem with the "large" WARs, but we have a problem that most of our WARs need the same 3-party libraries of third-party classes. The solution we came across (worked very well) was to use OSGi to modularly build our application. We use Felix as our OSGi container that runs inside Tomcat. Then we deploy all of our dependencies / libraries to Felix once . Then we deploy the β€œthin” WARs that simply reference OSGi dependencies, importing the packages he needs from the packages he cares about.

This has several other advantages:

  • Deploying new versions of OSGi packages when starting older ones is not a problem that does not require downtime (similar to a hot deployment).
  • If you need to update one of your dependencies (for example, Spring 2.5 β†’ 3.0), you need to update the Spring package running on OSGi; there is no need to deliver (or pack) new WARs if the API has not changed. This can be all (once again) done in the actual launch of the OSGi container, you do not need to disconnect anything from it.
  • OSGI ensures that your packages will not be separated by classes. This helps keep your code cleaner because each WAR only needs to know what it needs.

Configuring WAR for "OSGi ready" is not trivial, but it is well documented. Try checking out How to get started with OSGi or just Google for third-party tutorials. Believe me, the initial investment will save you a lot of time and a lot of headaches in the future.

It might be better not to reinvent the modular wheel if possible.

+1
source

All Articles