1. Short answer first
Use a combination of:
- maven, to drive the whole construction and deployment process (profiles and resource filtering will be very valuable features for you)
- shell scripts that use the asadmin command (an alternative to one of the glassfish maven plugins
- jenkins to trigger maven builds, either on a periodic basis or as a result of new code being pushed to your version management system.
- Netbeans has excellent integration both with Glassfish and maven and is my favorite Java EE IDE:
2. Now, some background...
To answer this question, it is useful to take a broader perspective and to consider the whole development/deployment life-cycle. The actual deployment of a .war or .ear archive in Glassfish is only one step of the cycle.
If you want to be really effective, you need to consider a combination of tools and practices for automating the construction and the deployment of your software applications. This is especially true if you work in a "real-world" environment with developer machines, continuous integration machines, QA machines and production machines.
I will elaborate a bit on these items in the following paragraphs. In particular, I will explain why I think that today, custom shell scripts driven by maven are better than the glassfish maven plugins available in the community.
3. Build management with maven
For many people doing java development, maven is a well-known tool. For the others, here is a very brief introduction. The goal of maven is to automate the construction of software artifacts. It is a framework (in the same sense as an object-oriented framework), which means that:
- it defines a standard way to build, package and test software
- it provides you with extension points to attach custom behavior around this standard way
In essence, when you use maven, you describe what kind of software artifact you are building (is it a .jar, is it a .war, is it an android app, etc.). By default, maven expects to find source files, test files and resources in specific locations. By default, maven knows that building the software requires to go through different phases: compilation, unit testing, packaging, deployment, integration testing, documentation generation, etc.
Another thing that maven does for you (and which is often the first reason for using the tool) is dependency management. Maven specifies a way to identify libraries (with a name and a version), which are made available through repositories (there are both public, global repositories and private repositories). With maven, you specify things like "I depend on magiglib version 1.2.2". When you ask maven to do the build, it will automatically fetch the lib, store it in a local repository and use it for the construction and the packaging. No need to deal with manual transfers of .jar files, no risk to introduce bugs because different version of the same lib are used by different developers or at different stages.
Last but not least, maven offers the ability to customize the construction of your software, depending on the target deployment machine. Think about the following use cases:
During development, think that every developer may have a different installation (mysql may not listen on the same TCP port, glassfish may not be installed in the same directory, passwords will be different, etc.).
A development machine is obviously different from a continuous integration environment, which is itself different from a QA or a production environment (again, just think about networking, file system, credentials).
Maven supports these use cases with the combination of variables, profiles and resource filtering:
- A variable is, well, a variable just like in any kind of programming environment. When you use maven, you write an XML configuration file (pom.xml) and you can use variables in it. That makes your build system configurable and dynamic. The port on which mysql listens or the directory in which glassfish is installed can be defined as variables.
- A profile is a way to give values to a set of maven variables. Typically, every developer will have a profile, every environment (from continuous integration to production) will have a profile, etc.
- Resource filtering allows you to reference maven variables in your source files, resource files and configuration files. For instance, in a java file, you can have the following string ${myvar} embedded. If you configure maven to do resource filtering, then it will replace ${myvar} with the value of the maven myvar variable (which may be defined in the current profile).
Maven is an extremely powerful tool, and as such has a learning curve. If you use Netbeans, you can actually create a maven-driven project with a couple of clicks and benefit from the basic features (e.g. dependency management). For advanced topics, there is very good documentation available. I will not go into further details here.
4. glassfish plugin... or not?
Once you have understood the value of maven and decided to use it, the next question is how you can use it to do the actual deployment of the .war or .ear archive into Glassfish (locally or remotely). This is where you have a number of options and where we have learned quite a few things over the years (we have been using maven with glassfish for several years now).
The first thing that you can do is to use one of the glassfish maven plug-in. There are different plug-ins available. They have quite different capabilities and different levels of support. It turns out that the most powerful plug-in is actually not supported anymore and does not work with Glassfish 3 out of the box. The plugin was interesting, because it made it possible not only to deploy archives into Glassfish, but also to create resources (jdbc pools, jms queues, etc.). It also made it possible to create glassfish domains on the fly (very useful to run integration tests and make sure that a fresh domain was used for that). Anyways, the new plugins (that are described in the product documentation) are not that powerful and purely focus on the deployment task.
In the build system that we created and made evolve over the years, we were able to achieve a lot of control and flexibility by combining the glassfish maven plugin with profiles and resource filtering. The solution works, is solid, yet is quite complex (our pom.xml and settings.xml has grown a lot and has become heavy).
So, if I was setting up a new build system from scratch, I would probably do things a bit differently. If you look at the code of the glassfish maven plugins, you will see that they are pretty much wrappers around the asadmin command line tool provided by Glassfish (and it is because the parameters and behavior of asadmin has changed from one glassfish version to the other that the maven plug-ins have been broken).
5. The way forward
What I would do is:
write a set of shell scripts to create glassfish domains, create resources (jdbc, jms, etc.), deploy .war and .ear. The scripts would use asadmin to interact with glassfish (it is possible to use asadmin both locally and remotely);
embed maven variables in these scripts and use resource filtering to dynamically create environment-specific versions of the scripts;
use the maven exec plug-in to run the scripts at different stages of the maven build cycle (integration test, run, custom goals, etc.).