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.