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.


