Category: glassfish

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.

Starting and stopping glassfish within eclipse

While working in my webapp, I often need to re-deploy. Here’s the setup:
  • Using Maven for full builds of the webapp. See my previous post about web resources within eclipse
  • Glassfish is installed in some directory, and is totally independent of eclipse.*
  • Glassfish has a webapp setup that points to the exploded webapp directory within its maven build target directory.**
  • Eclipse builds its classes into the target/classes directory***. This can save time in my maven build because it’ll notice that it doesn’t have to build classes because they are built by eclipse as I go.
  • I have a program builder on my project that runs “mvn -o package” on my project. It takes care of copying all web resources and all classes from target into the exploded webapp. This builder runs when I do a manual build of the project through the menus or with ctrl-b
Of course, in webapp development, when I modify the java files and compile them, in order to see the changes within my webapp while testing, I have to bounce the webserver. I did have limited success with Netbeans performing a hot-swap of code within glassfish, but that’s another story for another day.
So, the goal was to make glassfish stop and start whenever I modified java files. In order to do this, I did a trick similar to my previous blog post on filtering web resources and deploying them to the webserver. It was actually quite simple. I created two new builders, one which runs before the eclipse java builder, and one that runs at the very end.
In order to swap out jars or classes, I have to stop the webserver so it releases its handles on the files. This is done with the first builder.
The builder simply calls the glassfish asadmin.bat file, passing in arguments to stop the server. In the build options tab you will want to ensure that the “Launch in Background” is unchecked. We need this to run in-process so that the build will wait for it. If you put it in the background, your build may fail if shutdown takes a long time because the server will still have a handle on files the build is trying to delete.
We don’t want to shut down glassfish every time we build, only when java files change. To accomplish this, we will use the working set, like we did in the previous post. This time, you will set it to src/main/java
Next, we need to start the server again after our build is complete. This is almost identical to the first builder we just created. This one will go at the end of the build cycle, but will also call asadmin.bat. The argument is start-domain domain1. This builder SHOULD be launched in the background, otherwise your build will never end. Here is the Build Options tab of that dialog:
Notice that again we are specifying the working set for this builder so that we only try to start the server when java files change. The working set should be src/main/java as with the previous one.
So finally, we have a full build operation that looks like this:
Now, while developing my webapp, if I have only changed .xhtml files and I hit ctrl-b, the server isn’t bounced at all. My web resources are copied out to the webapp directory and changes are seen immediately. If I change java files and hit ctrl-b, the classes are recompiled and the server is shutdown and restarted. I can easily alt-tab to my browser and test my changes either way.
One drawback is that when the version changes, I have to change the deployed directory within the domain.xml file to point to the new target directory. This isn’t a big deal, as it’s simply changing the webapp descriptor from blahblahblah-1.3-SNAPSHOT to blahblahblah-1.4-SNAPSHOT within domain.xml and restarting the server.
All in all, this setup has served me very well for the last few months.
* I couldn’t just setup glassfish as a server within eclipse because the project is not setup as a dynamic web project within eclipse, and I can’t apply that template or property aspect or whatever it’s called after the fact.
** The web-module node within my domain.xml file looks like this:
<web-module root=”myurl” deployed=”true” enabled=”false” location=”c:/src/project/module/target/module-1.5-SNAPSHOT” name=”module” type=”user”/>
***Why didn’t I just build into target/my-web-app/WEB-INF/classes? If I had eclipse build into that directory, they would be wiped out whenever I ran a mvn clean operation, and replaced with newly compiled files from the target/classes directory. I’m not certain, but it may also happen with the mvn package command that my build is running from within eclipse. In any case, I haven’t tried it. If you try it and have good luck with it, let me know.

Eclipse and Maven filtering

I’m working on a web application and using Maven filtering for various properties within some of my web pages and application descriptors. I have my web server pointed to my maven target directory for the deployed webapp. This allows me to build and have my changes immediately available in the webserver. If my changes are in the xhtml files only then there is no need to re-deploy the application or bounce the web server. I can simply refresh my browser and see the changes. This makes for a nice development cycle when editing xhtml files.

The difficulty arises when you bring in the maven filtering.

Netbeans has much better Maven integration than Eclipse. It was also much easier for me to take my existing web application and simply ‘run’ it on the webserver. Unfortunately, when building in netbeans, it would simply copy the resources over to the target directory. For me, this meant death of the page because of the un-filtered properties in the pages.

I’ve been an Eclipse user since 2.x, and am much more comfortable in it. Since I’m not using any maven plugin for Eclipse ( haven’t found one that is worth the effort yet ) I use the Eclipse Java builder to build my java classes directly to my target/classes directory. Now to get the xhtml, properties, xml, etc. files over to where they belong with the appropriate filtering.

My answer was to configure a new builder. In Project Properties, select Builders, then create a new Program builder, with the executable being your mvn executable.

For the working directory, set it to your project directory using the Browse Workspace button. In the Arguments section, put the goals for your maven build. I chose package because it’ll get all the xml, properties, xhtml files, filter them, and copy them to the target directory, which is where my webserver is pointing for its webapp.

The magic is to specify the working set for the builder. Setting it to the src/main/webapp folder of your maven project ( the screenshot isn’t quite correct since it is on a non-maven project, but you get the idea ) means that the builder will only run when a file within that directory is modified.

Using the working set, I’m able to only run the maven target when working on my xhtml files. When I’m doing pure java work, updating the web only files does me no good and is a waste of time.

Now I’m able to work on my xhtml files, press ctrl-b to build, and refresh the browser I’m using for testing to see the changes. Quick turn-around, and no reason to hit the command line to manually run my maven command.

Maybe next time I’ll talk about starting and stopping my glassfish server automatically so I can see my java changes as well.

For information on filtering resources with maven, you can check out