introducing jawarepl
JAWAREPL is a JAva Web Application Read Eval Print Loop. It loads a Spring-based Java .war file into groovysh, and then makes its fully actived Spring beans easy to use.
Here's a quick example. It uses 'petclinic', one of the sample apps included with Spring:
$ groovysh . /Users/moi/Documents/code/jawarepl/jawarepl.groovy inst = new JAWAREPL();
Here's how you configure it:
inst.war_path = "/path/to/petclinic/dist/petclinic.war"; inst.context_paths = [ "WEB-INF/applicationContext-hibernate.xml" ]; ctx = inst.context;
After that, the sky's the limit! Start grabbing beans out and call all the methods you want. Put this into groovysh:
clinic = ctx.getBean("clinic");
clinic.vets.each {
println "vet = ${it.lastName}, ${it.firstName}";
it.specialties.each {
println " $it";
}
}
And this should come out:
vet = Carter, James
vet = Douglas, Linda
dentistry
surgery
vet = Jenkins, Sharon
vet = Leary, Helen
radiology
vet = Ortega, Rafael
surgery
vet = Stevens, Henry
radiology
Just to demonstrate that it's not only for reading data, here is another sample where it adds a visit to the petclinic.
owner = clinic.findOwners("Schroeder")[0];
owner.pets.visits.each { println "$it.date, $it.description" }
[2009-01-24, 2009-01-24], [JAWAREPL test, JAWAREPL test]
visit = new org.springframework.samples.petclinic.Visit();
visit.date = new Date();
visit.pet = pets[0];
visit.description = "JAWAREPL test2";
clinic.storeVisit(visit);
...
Hibernate: insert into visits (visit_date, description, pet_id) values (?, ?, ?)
owner = clinic.findOwners("Schroeder")[0];
owner.pets.visits.each { println "$it.date, $it.description" }
[2009-01-24, 2009-01-24, 2009-01-24], [JAWAREPL test,
JAWAREPL test2, JAWAREPL test]
More detailed instructions are available on bitbucket.
JAWAREPL has been tested on three of the sample Spring apps and a basic Grails app. Those are pretty trivial samples and even so, it was a minor task to make them all work; the Grails war had none of the GORM mojo stitched in so it was really not very useful (patches anyone?) That being said, I would not expect a complex war file to load smoothly. I seem to recall some sort of mock/mini JNDI provider in Spring if that what goes wrong. I will try to look at any bug reports, or much better yet patches.
Implementing xor in a bitunwise way
Bitunwise is one of my pet projects. It uses a common algorithm to reimplement memcpy, memset, memcmp, bzero, and kin. I decided to add support for xor'ing two byte streams. The first patch was small and easy to write, but it needed better abstraction. I took another look at the functions I was trying to implement and realized they can be grouped by number of input streams:
- zero input streams: bzero
- one input stream: memset, memcpy
- two input streams: xor
So now instead of calling into the core algorithm manually, the emitting functions call the appropriate arity helper method. It worked out to the same number of lines of code... BUT future emitting methods (e.g. nand) will be one or two liners.
Yay for BitBucket
It's 2009 and I still prefer CVS to Subversion. I earned my source control badge with CVS and learned to live with its warts. Better the devil you know, you know? I decided to learn as much svn as necessary while waiting for the next generation of version control software.
Distributed version control seems to have surged since Linus Torvalds kicked Bitkeeper to the curb in early 2005. Of course he immediately started writing a DVCS named git. His celebrity brought it instant attention, even an hour long presentation at Google HQ (I have to watch this someday).
About a year ago I downloaded version 1.5.3.8 of git and played with it. It was okay, I guess. It wasn't easy to love, not that I mind that too much. The bin directory contains 145+ standalone apps, although I guess they are typically used in the unix-y "my stdout is your stdin" approach?
Git's got the goods, no doubt. It capably manages a top-tier complex and distributed codebase. That is an uncommonly difficult task and satisfying it means leaving some facets less polished. Namely, learning curve and ease of use. I didn't feel like tackling both of those while learning a new type of version control.
Mercurial competes with git in the DVCS arena. It has a nice website and some really nice quick reference cards. It didn't and still doesn't distract me while I'm trying to grok what's different and possibly better about DVCS.
Part of "distributed" means having a read/write repository somewhere on the internet. There's probably a few ways to do it; "hg serve" runs an HTTP server with a decent interface for your repository. It's pretty nice, I've tried it. But the fewer servers I have to maintain the better. That's where BitBucket comes in.
Another part of "distributed" means making it easy to actually share a repository. Pushing and pulling files is critical but viewing prior revisions, tracking bugs, having a wiki, and rss/atom feeds are big wins for daily work. BitBucket offers those and makes it easy. Really easy. Within 30-45 minutes or so I had:
- Signed up using my OpenID / ClaimID account.
- Uploaded a public key
- Created a repository and pushed changes over ssh
- Updated Google Reader with an RSS feed for my repository
All for free! Apparently they also offer features which simplify all the distribute-y goodness in Mercurial. But that's a far cry from where I am now.


