I'm both excited and slightly saddened to announce that I'm leaving Oracle. I've enjoyed my time here, the work I've done, and with whom I've done it. Sometimes an opportunity comes up that's too enticing to pass up, though, and you just have to take it. I hope I can continue to help the evolution of websockets in EE and plan on applying to join that EG as soon as it forms but we'll see. I hope to with the Grizzly implementation, as well, as the standards start to evolve but again we'll have to see how things play out.
It's a bittersweet thing but I'm excited about it overall. I have my JavaOne duties next week and then one more week with Oracle and then it's on to next thing. If you're at JavaOne next week, stop by my session and say hi. Now to finish packing...

There are two main cases I want to cover here: port redirection and serving multiple protocols on one port. I'm pretty sure that covering both in one post would egregiously long so I'm going to break things up into two posts. In this first post, we'll cover what will likely the be more common use case: port redirection. In this example scenario, you only want to serve requests via https rather than http. In this case, you can configure GlassFish to return a 302 and push clients off to https transparently. This type of configuration has been available in GlassFish since at least v2 and is still available in v3. However, in v3 it wasn't "officially" supported so you had to manually massage your domain.xml.
While documented in various blogs around net, it's not officially supported in v3. As of, well now I guess, that's all changed. I've added some asadmin commands to the 3.1 nightly builds that expose a more user friendly way to configure port unification. In this blog, I'll introduce these commands and show you how to set up a simple redirect to enforce https requests on a given listener. As always, when experimenting with this sort of thing, you should back up your domain.xml so if you hose your configuration, you can easily roll back to a working configuration.

There are two main concepts involved: <protocol-filter> and <protocol-finder>. There are a handful of other elements involved but we've hidden them from you by default since very few people will need to manage those elements. The first step is to create the <protocol-filter>:

We need to create a new <protocol> element to hold our new filter first. You can't simply reuse, say, http-listener-1 because port unification elements and <http>/<ssl> can't coexist on the same protocol elements. You could of course issue a number of commands to preserve the name of http-listener-1 but the work involved is likely not worth it. It's certainly overkill for this example so I'll leave that as an exercise for you if you're that interested in it. The next asadmin command creates the actual protocol filter. With these two commands we have now have a new entry in our domain.xml that looks like this:

Notice that there are new elements: <protocol-chain-instance-handler> and <protocol-chain>. These are some implementation details that should be mostly irrelevant to all but a handful of users. I only mention them so that you'll be expecting to see them and that you know you can safely skip over them. With those pieces in place, we can now create our finders.

To create our finders, we need to create another <protocol> element to hold them and then create the finders themselves:

Note that the first <protocol-finder> refers to the http-listener-2 <protocol>. We'll be using that protocol definition to configure the https processing. The second finder refers to the <http-finder protocol> definition we just created and it is this piece that will be doing the redirect from http->https for us. The first finder will trap all https requests and hand them off, while the second will handle all cleartext http requests and redirect for us. The resulting domain.xml elements looks like this:

Again, we silently create the <port-unification> element for you so you needn't worry about it. These elements that we silently create for you, we will also silently delete them for you when you delete the last elements contained in them. So those are our port unification elements. With those created, we just need to reconfigure listener to use these new elements:

asadmin set configs.config.server-config.network-config.network-listeners.network-listener.http-listener-1.protocol=pu-protocol

With that, we can try hitting port 8080 and see things in action. The easiest way to see this, probably, is to use wget:

As you can see there, the server returns a 302 back to the client with the new location of https://localhost:8080. That's all it takes. Now every request will use https regardless of the original request. You could, of course, use a similar set up to push everyone from https back to http. This is especially useful for those without any need for https and are concerned about server load since https can be expensive to process.

In the next entry, I'll tackle the use case of serving up multiple protocols from one listener. This will be especially useful for those behind firewalls wanting to open only a single port to the outside world. Hopefully this will get you started. If you have any questions, feel free to leave a comment or ask on the glassfish users mailing list.

For convenience, here are all the commands necessary to try this out at home in one downloadable file:

GlassFish is a big enough source base that sometimes you just need a little help managing the development lifecycle. Over time I've developed a number of scripts that I use while working on either grizzly or glassfish to help manage the load. After a number of discussions, I've decided to share them in the hopes they will help others, too. Not of all these scripts are really glassfish or grizzly related so you might find them useful in your own projects as well. You can check out these scripts using git from this url: git://kenai.com/schema-doc~git-repo.
There are several scripts but I'll try highlight the more interesting ones. Just a note, though. These are bash scripts that have grown organically for a long time. So they're not necessarily going to be pretty. Some might even consider some of the hoops I've jumped through "stupid." That's fine. I'm not getting a Ph.D. with these. They work and that's enough for me. But anyway.

General Scripts

The first set of scripts that should apply to almost any project.

script

description

changed.shunknown.sh

These scripts will show you any changed (or unknown) files for whichever VCS you're using. They currently support subversion, mercurial, and git. The git support is new-ish so let me know if something's off

findInJar.sh

As the name implies, this script will find every jar in or under the current director and grep for, well, really whatever you tell it. I wrote it with looking for classes in mind but since it just greps the contents, it will find anything that matches. It seems like everyone eventually writes a similar script so maybe this will save some people a little time.

failedTests.sh

This script requires that you use maven. It will run mvn surefire-report:report-only and scan for any failed tests. If it finds any, it will use the open command to open the report html in your default browser. It can, optionally, run your tests before looking for failures. If you'd like it to do this, simply pass --run to the script.

GlassFish/Grizzly Related Scripts

Obviously, these scripts will be of little interest to those not working with some aspect of glassfish development. But if you're not, you're probably reading the wrong blog entry anyway. All of these scripts rely on the presence of environment variables. The scripts are set up to check for the variables and prompt you to define them so I won't go into them here. Just be aware that at first you'll have to define a few variable before these scripts will work for you. And these scripts need a UNIXy environment so if you're on Windows, you'll need something like cygwin to make these work. But even then, I've not tried these with cygwin so you might have issues even still. I'll refer to some of these variables by name below, but the script will walk you through what to set to what.

script

description

distro.sh

This script will build the glassfish distribution bundles. Most of the heavy lifting is really done by maven but this script goes a step further and extracts the "glassfish" distribution of into ${GF_INSTALL}. Executed without parameters, it will build the distro, remove the current install, and unzip the new one. There are 3 options you can pass to this one:

--nobuild: only extract the bundle zip.

--buildonly: just build the bundles. don't extract them.

--clean: have maven clean out the compiled artifacts before building the distributions

devtests.sh

This one is really specific. This will run the webtier devtests after reconfiguring the glassfish install in ${GF_INSTALL}. It can be run from anywhere so you don't need to worry about where to launch this one. Once the devtests finish, it will open the test_results.html displaying the results of the tests. This one takes a while to run. There are a lot of tests...

single.sh

Similar to devtests.sh, this test will run a single test in the webtier devtests. Just pass it the name of the directory while in v2/appserv-tests/devtests/web and it'll do the rest.

quicklook.sh

This script runs the quicklook tests to test your v3 tree. This script takes --debug and will run the quicklook tests using the mvnDebug script.

updateBundle.sh

This script compiles the current maven module and copies the resultant jar into your glassfish install. This should work for any glassfish-related project. I use it with grizzly, too, for example.

rebundle.sh

This script will scan svn looking for changed files and try to determine the module owning each file. It will then call updateBundle for each of those modules and update your glassfish install. Passing --start will then launch glassfish with your updated code.

startgf.shstopgf.sh

These scripts will start/stop glassfish from wherever you may be in the filesystem. Passing --debug will launch glassfish in a debug VM. It will also update your domain.xml such that the launch will pause until you connect to it with a debugger so be aware that things will appear to hang until you do.

tailgf.sh

This will tail your glassfish's server.log from wherever you are in the filesystem. If glassfish is not yet running, it will also truncate the logs first.

That about does it. I use these scripts daily and I find them quite useful. Hopefully, you do as well.