Month: June 2009

Maven, Eclipse, Glassfish, and a Webapp

Update: As of Eclipse Juno, the m2e plugin is much more reasonable and usable. I would suggest using m2e and m2e-wtp rather than following the instructions below.

Original Post:

At work we are using Maven and Glassfish for our webapp build and hosting. I have been using Eclipse since the 2.0 days and wanted to continue to use Eclipse. As I’ve said before, I’ve not had a lot of luck with the Maven plugins for eclipse. Since my project was created with the maven eclipse:eclipse plugin, it’s not marked in eclipse as a web project, so I can’t just hit run and have it go. I finally have my project setup in a way that I feel is the most productive. This is how I did it.

After running

mvn eclipse:eclipse

Import the project into eclipse. Now we will modify some of the properties of the project so we can build and deploy without restarting eclipse and without having to hit the command line.

  1. First open up the project properties.  In the Java Build Path in the Source tab, change the Default Output Folder: to /target/mavenartifact-version/WEB-INF/classes.  This will cause eclipse to build the classes into the webapp classes directory directly whenever it builds.  The drawback of this approach is that whenever the version changes, you will have to come and reconfigure this value again.  While you are working, if you find that your java changes are being reflected in the webapp when you test, you will want to check this value first.
  2. Next, we need to configure Glassfish to point to your directory deployed webapp.  This step assumes you have previously built your webapp module using maven and the target directory exists.  In the glassfish admin ui, under Web Applications deploy a webapp of type Web Application (.war) with a Location of Local packaged file or directory that is accessible from the Application Server.  The browse to your /target/- directory using the Browse Folders button.  Set the other properties appropriately, and ensure that it is deployed to the correct Virtual Server and hit OK.  Again, when the project or module version changes maven will build the war into a new directory and you will need to change the directory that glassfish is pointing at.  You can do this in /domains/domain1/config/domain.xml.  In that file, you will search for the web-module that you just deployed, and change the location attribute to match your new version.
  3. Now you should be able to start glassfish and view your webapp.  Changes made to (x)html, jsp, etc. files in the target directory should take effect immediately in glassfish, but we don’t want to be working in there all the time, so the next step is to setup a couple of custom builders in Eclipse to push changes to the target directory when we build.  To do this, go into the project properties again and select the Builders item.  You will add two builders, one to repackage everything when you touch an (x)html or jsp file, and another to tell glassfish to reload the webapp when you touch a java file.
    • First we will create the builder to repackage everything.  This will be a new builder that should come immediately AFTER the default Java Builder.  The Location of the builder should be your maven executable.  On my windows box, this is mvn.bat.  The Working Directory for the builder should be ${workspace_loc:/your-project-name} using your project name in place of your-project-name.  The Arguments: should be -o war:exploded which will tell maven to copy everything over to the target directory, but not necessarily create the .war file.  In the Build Options tab, you should specify that builder run During manual builds and then you will want to Specify a working set of relevant resources.  I’ve talked about the working set in a previous post.  The set you are going to want for this builder is /src/main/webapp. This will make sure that this custom builder only runs when the webapp resources change.
    • Next, we need to setup a custom builder to reload the webapp in glassfish when java resources change.  Glassfish has a nifty function where if you touch a .reload file within the webapp root directory, then glassfish will reload the webapp, including all libraries and classes. This way, you can basically redeploy your directory deployed webapp without having to restart the server or anything. To do this, you will create an empty /src/main/webapp/.reload file. With that location, it should be copied over to the webapp root the first time you run mvn clean install. Now, we need a custom builder that will modify the date on that file. Create a new custom builder, which should be AFTER your new maven builder. If you are on windows, you don’t have the ‘touch’ command. The Location for the new builder should be C:\windows\system32\cmd.exe and the working directory should be the root of your deployed webapp, i.e. ${workspace_loc:/your-project-name/target/your-project-name-version}. The Arguments should be /c echo reload > .reload. This will write a new .reload file. Make sure you set the working set to src/main/java. Again, since we have the version in the working directory for this builder, it’s ANOTHER place you’ll have to update it when your module changes versions. If anyone has a better workaround for this, I would love to hear it.

With those steps done, you should be able to make changes to (x)html, jsp, or java files, hit ctrl+b to build your webapp, and have the changes reflected in your deployed webapp within a few seconds. For larger webapps, the mvn war exploded command may take a few more seconds, but it’s still faster than going to the command line, and safer than working directly within the target directory.