Verse Of The Day

Tuesday, April 29, 2008

Some Notes On The Jboss BeanShell Deployer

I've been playing a little with the BeanShell Deployer in Jboss lately. Technically, it's pretty cool. Drop a .bsh script in the deploy directory and the hot deployer picks it up just as if you dropped a .war/.ear/.sar file in there. If it's a simple script, the bsh deployer runs it immediately. Or you can implement any or all of the methods of the ScriptService interface (below) and your script will be deployed as a service mbean.
public interface ScriptService
extends org.jboss.system.Service
public String objectName ();
public String[] dependsOn ();
public Class[] getInterfaces ();

public void setCtx (ServiceMBeanSupport wrapper);

It was extremely easy to write a few scripts and drop them in the deploy directory. Of course, you can start with the requisite "Hello World" script, which upon deployment, prints out to the console. A few more minutes of scripting (adding the above methods) yields a service mbean that can be managed via JMX.

But then the obvious questions: Why? Why would I write mbeans using bsh instead of Java? What do I gain? What do I lose? Is it really any quicker?

I don't really have good answers for the why question yet. I did write a few services using bsh. They were easy enough to implement, but nothing that couldn't have been done in a similar time frame using Java. You lose compile time error checking, but you avoid some of the plumbing regarding build scripts, deployment descriptors, and building .ear or .sar files.

I did write a few services. One connected to a Websphere MQ (a.k.a. MQ Series) queue manager to get queue depths and print them to the Jboss console. I ripped most of the code right from an existing MQ tool I wrote a few years ago. So not the most useful thing in the world, but it proves out importing existing Java classes and the Java syntax. Another used JDBC to connect to an audit database and purge old transactions. Again, nothing that couldn't be done in regular old Java code in the same amount of time.

Overall, I didn't feel like I was saving any time. For one, the syntax is Java. That's great for code re-use (either cutting/pasting or importing libraries), but Java syntax doesn't have that "lightweight scripting" feel to it. Also, the lack of compile-time error checking doesn't save you much time if you have to run the script to find errors. Make a simple mistake like a type mismatch or failing to catch a specific exception, and your IDE and/or compiler will tell you about it. Do the same thing in a bsh script, and you find out after you deploy it and run it.

I think this could prove useful in the future, as one more tool in my programming toolbox, but have to admit I don't have a lot of use for it right now. Maybe I'm just not seeing the big picture, or just haven't run across the scenario where this is the ideal way to solve a problem. If you are using the bsh deployer, please let me know what you are doing with, or what types of problems you are solving with it.

Once I have a reason to use it, at least I know it is easy to do. And once the why question starts to have answers, maybe I'll explore writing a JRuby or Groovy deployer. Or actually, what would be really useful would be a SQL script deployer, so you could run ad-hoc queries against your Jboss DataSources without writing JDBC code or having to launch a DB tool like Squirrel or TOAD. Since Jboss deployers are service mbeans, maybe I could write the SQL deployer in bsh...


If you're looking for a way to feel all warm and fuzzy inside, like you're making a difference in this world, but are just absolutely sick of all this "green" crap, check out the GoodSearch search engine. The underlying search engine is Yahoo, so you should still find what you're looking for. The difference is you choose a charity when you first go to the site, and when you search, half the advertising revenue GoodSearch makes from your search goes to the charity you designated. From what I read in the Seneca Park Zoo newsletter, it comes out to about a penny per search.

You're giving back without opening your wallet or going out of your way. Anybody can do it, and it all just happens while you're doing what you would normally be doing anyways.

GoodSearch: You Search...We Give!

Monday, April 21, 2008

And Now We Wait

We bought our SAI XD-9 this weekend and turned in our pistol permit applications today. Now we just wait, and wait, and wait some more, to get our permit so we can actually pick up the gun.

I feel like a little kid waiting for Santa Claus to come. From what I keep hearing, the process does not take nearly as long for Wayne County as it does for other counties in NYS. We'll see.....

Monday, April 14, 2008

The BeanShell Servlet Filter Summary

OK, now that I step back and look at this post I wrote a few days ago, I realize I use too many words, tend to blather on and on and on.

So to summarize:
  • What's the point? It's a Java Servlet Filter that delegates to BeanShell scripts to do the actual Filter work.
  • Does it really work? Yes. I am currently running it in Glassfish, but should work in any Java servlet container. It's still just a proof-of -concept and needs to be cleaned up to make it production ready.
  • Where's the code? Of course, you still have to go to that post to see the code, but you can skip the blathering on and on and on.
  • What's the point? Well, just because it can be done I guess. My theoretical ramblings on "why" are what made the post so long in the first place.

Saturday, April 12, 2008

Dynamic Servlet Filters Using JVM Scripting

What got me on the subject of Servlet Filters in the first place was an idea that occurred to me recently. Servlet Filters aren't the sort of thing that can be easily altered at runtime. They are mapped in the web.xml file, so if there are Filters you only want for development or test, but not production (like the DebugFilter I presented in the last post), you have to jump through some hoops to make that happen. You could edit the web.xml before deployment, or have separate dev/test/prod web.xml files that ANT copies into place depending on the build, or have some sort of runtime flag (DB property, value bound in JNDI, etc.) that will either run the Filter logic, or just pass through to the next in chain.

But what if you could not only enable or disable the Filter, but also change it's behavior, on the fly at runtime without special build or deploy steps. I was pondering this idea and came up with the concept of a Servlet Filter, that by itself, does nothing.

Nothing? Well, nothing by itself.

"By itself" is the key phrase here. Instead of doing something in the Java code (getting timings, checking security, auditing calls, printing debug statements, etc.) it just instantiates a scripting engine, like BeanShell (BSH), JRuby, Groovy, etc. It starts up the scripting engine, passes the Request and/or Response objects, and runs a script that you have identified. That script does all the meat-n-potatoes work, and the Filter then calls next in chain like it normally would. And the best part is, the script could be changed at runtime, from a simple do-nothing-and-return to full blown screwing around with the Request and Response objects.

I've developed a proof-of-concept (POC) and have it running under Glassfish v2 application server. I used BeanShell for the scripting engine in the POC, but as stated above, any of the scripting engines for the JVM should work. This isn't quite ready for primetime, but it fully works.

There are actually 2 scripts called by this filter, one before the chain.doFilter() call is made, and one after. That way you have the flexibility to do operations either on the request, on the response, or both.

First, the Java code for the Filter:

Then, the 2 BSH scripts:


import java.servlet.*;
import java.servlet.http.*;
import java.util.*;

System.out.println("This is the BSHServletFilter_PRE.bsh script!!!");

StringBuffer output = new StringBuffer();
output.append("\nRequest Attributes\n");
Enumeration attrs = request.getAttributeNames();
while (attrs.hasMoreElements()) {
String attr = (String) attrs.nextElement();
output.append(attr +" - " + request.getAttribute(attr));

output.append("Request Parameters\n");
Enumeration params = request.getParameterNames();
while (params.hasMoreElements()) {
String param = (String) params.nextElement();
output.append(param +" - " + request.getParameter(param));

System.out.println("This consludes the BSHServletFilter_PRE.bsh script!!!");


System.out.println("This is the BSHServletFilter_POST.bsh script!!!");
System.out.println("About to alter the response...");
response.getWriter().print("<h1>This response is from the BSH script</h1>");
System.out.println("Done altering the response");

And the browser screenshot...

This is currently just at the POC stage. It is working as-is, running under Glassfish. But as you will immediately notice, the filenames for the scripts are hard-coded, and there is definitely some more cleanup to make this production quality code. But, you can change the behaviors of the filter, for better or worse, at runtime without any compiling, deploying, or restarting of servers. You can even "disable" the filter by writing BSH scripts that do nothing.

Thursday, April 10, 2008

A Servlet Filter For Easier Debugging

I whipped up this quick Java Servlet Filter (javax.servlet.Filter) to aid in development and debugging. This simply dumps all the HTTP request attributes and parameters and Session attributes to the log. Like any other Servlet filter, it can be chained with other filters like the timing filter, GZIP filter, etc.

This isn't meant to be a tutorial on Servlet filters, I am assuming you either know (or know how to figure out) what filters are, and how to tie them into your application in the web.xml descriptor.

I "printed" the source into a PDF to keep the formatting in tact. Here is the link, or if your PDF plugin is working, it should appear in an iframe below....

Saturday, April 05, 2008

Spring Has Sprung Again

Grandpa Duane's funeral too a lot out of us this week, but now we're trying to get back to normal. And now it's becoming clear that Spring is rapidly approaching. The snow is melted and now the daffodils and tulips are coming up around the house. I haven't worn a jacket all week, and today we're doing "springy" things like pulling trees out of the ground with my truck (YEEEHAAWW!), cleaning up the yard, starting seeds for our herb garden, planning out our chicken purchase, rolling the lawn, etc.