« March 2006 | Main | May 2006 »

April 28, 2006

Goodbye Venkman. Hello FireBug.

While it's not out just yet, FireBug 0.4, the first release that will have a JavaScript debugger, is the best JavaScript/AJAX tool you can find. FireBug already had superb tools for evaluating JavaScript expressions, exploring your DOM and CSS, and more. But now, it is truly a killer tool. The JavaScript debugger beats the pants off of Venkman, especially in terms of speed (Venkman is painfully slow).

The UI is slick. Navigating between different scripts is painless. It just "feels" right. And did I mention it is fast? Yes, really fast.

I can't wait for Joe to unleash it on the world. All web developers will be happier people because of Joe.

Scripting with Groovy

My first real experience with Groovy has started with some mixed results. It's painfully easy to get started with, but I found the regex support to still smell far too much like the Java regex support, which isn't nearly as nice as that found in other scripting languages like perl.

The requirement was to add scripting capabilities to HostedQA. This way customers could write more advanced tests that might not be possibly using the basic set of commands we offer for controlling the browser. One such customer requested that a test go to a page and verify all links on the page were valid. A simple script parsing the HTML of the page and visiting all the links solved the problem.

Groovy is great for this kind of loose "glue" code and I'm very happy to offer it to my customers. But there are some concerns:

No easy way to validate the code

No easy way to validate that the supplied code is syntactically correct. I could run the code to check that it is valid, but considering that the script is part of a larger test, mocking out the inputs isn't really possible.

I also thought about running the code modified with a giant "if (false) { ... }" block around it, but because I want to allow some limited imports, that won't work either - unless I peg the import statements to a pre-selected handful of choices.

Big security hole

I asked about security in the #groovy chat channel on irc.codehaus.org but didn't get much of a response. Basically, I want to lock down what calls the script can make. I know that I can probably work this out using the JVM policy rules, but I'd prefer to avoid this if possible. Perhaps there are other ways to lock down the objects and methods available for execution?

It doesn't help that Groovy offers stuff like "rm -rf".exec()!

I could limit some, but not all of the security concerns by simply locking down import statements. But that still feels "icky".

No easy way to kill long running processes

Because these scripts are run by untrusted users, they could be very dangerous. A tight loop could peg the CPU for long periods of time. I could of course watch the threads and interrupt them myself, but I really think that this issue and security are both something a scripting container should help with.

Another idea is to run the entire thing in a separate JVM. That would make the overall implementation more complex, but perhaps would give me even greater control.

Conclusion

Scripting in JVMs is a very nice tool. And if I can figure out these issues, I think that this type of glue code could really enhance the HostedQA offering. But I can't really go live with it until I have an answer for these problems. Does anyone have any suggestions?

April 26, 2006

Binary diff or rsync in Java?

Try as I might, I can't find any decent binary diff tool written in Java. My needs are fairly simple: I want to reduce the content sent across the wire, and in most cases a diff would be 100X smaller. The continuous integration support provided by HostedQA already supports this and I have verified it is a huge savings. But currently it uses a native program called bsdiff.

Ideally I'd like to use a native Java program so that I don't have even more infrastructure to set up in what is already a very complicated deployment (Software as a Service usually is complex, but I'm quite certain that, for better or for worse, HostedQA takes the cake).

I did find one program, javaxdelta, that does what I want. But, as I previously pointed out, SourceForge CVS is pretty much broken and I have no way to get the code. So back to the drawing board until SF gets its act together.

The bsdiff approach works well enough for now and it is very cool to see a Continuous Integration process update the server with a diff for a 30MB war file and then kick off tests. But even this approach isn't as ideal as I'd like. One word: rsync.

Rsync is great because it doesn't require that both the new and old files are on the local machine to diff. Rsync can send only the diffs while doing the comparisons over the wire. I don't quite understand how it works (it may very well be magic), but that is even better. Currently, my solution will have to send the whole file if someone has updated the files on the server after the most recent upload, since the diff will no longer be valid.

If finding a Java binary diff program was hard, then finding a Java rsync program is even tougher. I did find Jarsync, which has two problems right away: 1) Hosted on SourceForge (grrr), and 2) the home page says "Note: Jarsync is no longer being actively developed. It may be picked up again, but not now."

So, does anyone know of some hidden project that Google hasn't found yet? I imagine at some point we'll have to write one of these two programs in Java, but in the meantime the bsdiff approach isn't too bad for an initial release.

SourceForge CVS problems for WEEKS?

Maybe I'm the last person to realize this, since I don't work on SourceForge projects anymore (OpenSymphony moved from SF to java.net a couple years ago), but apparently SourceForge CVS has been having serious issues for almost a month now. Check the site status page for yourself to see! How do projects survive like this? Doesn't JBoss still use SF?

That's really bad for the open source community. Perhaps uber-communities just can't scale. Java.net actually has been having some serious hiccups as well. Indeed, if you're fed up with their quality of service, check out smaller communities like OpenSymphony and OpenQA. We're always looking for quality projects to join the team.

OpenSymphony is specifically for Java frameworks and components (as opposed to complete applications), and OpenQA is specifically for any testing/automation tool, regardless of language. Both provide their own infrastructure: SVN, JIRA bug tracker, Confluence wiki, continuous integration, XMPP chat server, Jive forums, project blog support, and FishEYe.

Of course, all of this is provided by generous donations from the companies that make those products, and hosting is provided by Contegix. Contegix provides top-notch service for free, managing all these different software installations, as well as providing almost instant support response times.

To date, they have fielded over 600 emails for OpenSymphony and almost 200 for OpenQA. All for free, and always without any serious downtime like SourceForge is having. I think that says a lot about Contegix, and also a lot about the viability of large scale vs small scale open source communities.

April 25, 2006

File transfers using SOAP (XFire)

This past week I've been spending some time working on an API for uploading your resources (applications, war files, database dumps, whatever) to HostedQA. While HostedQA can currently automate the entire test process, including setting up your database and app server, it didn't yet have continuous integration support. Of course, that sort of defeats the purpose of automation, since that is where most automation begins.

So over the last week I spent some time adding an API that allowed for sending large files (100MB or more). At first I figured I'd just go with a simple HTTP POST (REST-style). In fact, at the time that's what we were using to send large data between our client virtual machines and the main HostedQA server (for the rest of the API we were using Hessian). I decided to bit the bullet and try to offer a true SOAP API using XFire.

So, hopping on to #xfire on irc.codehaus.org, Dan Diephouse helped out immediately and ended up actually spending a lot of time making file attachments even better. In almost no time I had switched out Hessian support and created an Ant task that could upload files over SOAP via XFire. The only trick was enabling MTOM. Although not spelled out in that doc, if you're using Spring for your XFire services, you can enable MTOM by simply adding this to your ServiceBean definition (_not_ your actual service bean):

<property name="properties">
    <map>
        <entry key="mtom-enabled" value="true"/>
    </map>
</property>

After that, simply adding a javax.activation.DataSource parameter on the service interface was all you had to do to get file upload support working. Sort of.

It turns out that while it worked, large files would cause OutOfMemoryErrors because they were being buffered up in memory. No good, considering that with HostedQA we have to support database snapshots and war files that could be somewhat large. Even at just 10 or 20MB, I don't want to take up all that memory. So back to #xfire and Dan promises to hack away support for it.

After a day, Dan had a pretty good solution in place that even worked with .NET. Not bad! The only trick was that HTTP chunking needed to be turned on by the client now, otherwise streaming wouldn't even happen at the HTTP level. Since Jetty and Resin (our development and production app servers, respectively) both support chunking, the only thing that I had to do was update my findService method in RpcUtils.java:

public static <T> T findService(String url, Class<T> clazz) {
    Service serviceModel = new ObjectServiceFactory().create(clazz);
    T service = (T) new XFireProxyFactory().create(serviceModel, url);

    Client client = ((XFireProxy) Proxy.getInvocationHandler(service)).getClient();
    client.setProperty("mtom-enabled", "true");
    client.setProperty(HttpTransport.CHUNKING_ENABLED, "true");

    return service;
}

Now files are being streamed across the wire perfectly, all using XFire and open protocols. Hessian was immediately ditched and our continuous integration support is just about complete. There were a few hiccups, however:

  • Currently, servers that are given DataSources (in a method parameter) clean up the temporary File automatically. However, clients that get DataSources returned to them do not have their temp files cleaned up. I'm working on a patch to fix this.
  • On top of all of this, we were also adding SSL support to the whole site. SSL is generally a pain, but even more so when you have a wilcard domain (we make http://yourcompany.hostedqa.com to each of our customers) and many virtual machines all needing to communicate back to the main server. Not impossible, but lots of moving parts that can easily get goofed up.
  • The STAX XML parser is a pain in the butt. Again, I hit more problems than most will due to the complex deployments we do (JVM launches a VM, which launches a JVM, which launches an app server on another JVM... don't ask :P). The solution was to make sure I was using the stax-api-1.0.1.jar and also that -Djavax.xml.stream.XMLInputFactory= com.ctc.wstx.stax.WstxInputFactory was set. Otherwise you might run in to problems where you get a ClassNotFoundError about a BEA class (due to XBean looking for BEA's implementation).
  • Generally, XFire requires a ton of jars - more than I really want. I always liked how Hessian was just a single jar. Because of these jars, I did run in to a couple compatibility issues, especially around Spring parsing applicationContext.xml.
  • Finally, as my first time really using SOAP, I had to change some of the objects I was passing over the wire. Using Hessian, which uses serialization, I could have circular references in my objects. SOAP doesn't support that, so I ended up having to create some simpler versions of my model (TestSuite.getApi() returns TestSuiteAPI).

Overall though, XFire was actually a lot easier than we thought!

April 18, 2006

Job availability in SF

A friend of mine, Auren Hoffman, is starting a company called RapLeaf. If anyone is looking for a job in San Francisco with a very early stage startup, let me know and I'll get you hooked up. Auren is a very smart and well-connected guy and I'm sure RapLeaf will do great. I've tested out early prototypes and I think they are on to something.

Job openings cover both engineering and marketing. See more at Auren's blog about two marketing positions (here and here). For the engineering positions, you can just drop me a note and I can pass your resume along.

Bonus points: they are using Rails, if that helps (personally, I'll forgive Auren, but just this one time) :)

April 16, 2006

WebWork at The Ajax Experience

I'll be speaking at "The Ajax Experience": http://www.theajaxexperience.com next month (just before JavaOne). This is a pretty exciting conference and presentation for me, mostly because I consider myself "an ajax idiot". That is, I often have no idea how to do the low level AJAX stuff that all the other presenters know about. Instead, I hope my perspective is a little unique and even interesting, especially to Java web developers.

What we are doing in WebWork (and now Struts Action Framework 2.0) is wrapping up various complicated AJAX techniques and libraries, and making them as simple as using a JSP tag. Want to have AJAX-based validation in your forms? Easy, just add validate=true to your ww:form tag. Need a reloading chunk of HTML? Simply drop in a ww:div tag and specify a URL and refresh time.

My presentation will be all about how we've wrapped up much of complexity and JavaScript-ness of AJAX and rolled it in to a nice set of libraries that are readily familiar to WebWork users and other Java web developers. We hope that this perspective can not only teach other "ajax idiots" how to quickly add AJAX to their application, but also perhaps show other AJAX framework authors (Dojo, Prototype, Scriptaculous, Rico, etc) what is appealing to novice users.

Anyway, I hope to see some of my readers at the conference. If you're going to be in town for it, or for JavaOne, let me know!

April 12, 2006

HostedQA: J2EE acceptance testing solution

For the last three months my company, Autoriginate, has been working hard on our first product. Today, we are pleased to announce HostedQA to the world. HostedQA is a super-low-cost QA solution for J2EE web applications. With a focus on complete automation (including starting your database and application server and in-depth reporting) and convenience, HostedQA is by far the lowest cost and most innovative option for Java web application testing.

With an intuitive AJAX-based UI, you can upload WAR files, database snapshots, and other resources. Then assemble these resources together in to deployments unique to your testing requirements, such as "Tomcat running on Postgres" or "JBoss running on MySQL".

Launch your application from within HostedQA's virtual servers and record test scripts from within your browser. You can upload your scripts to hostedqa.com and even refactor them by introducing macros with common functionality. HostedQA is smart enough to even analyze your tests for potential replacements for macros.

We're really excited about HostedQA and hope to make it available for any open source project that could benefit from it. We're also offering extended free trials during our initial rollout, so please check it out if you're interested.

Now that we're finally announced to the world, I plan to be blogging a lot more about HostedQA, our company, and testing in general. I definitely want to hear from my readers about what pains you have when testing your products. Hopefully we already have or soon will address it with HostedQA!