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.
C++ versus Java, or references to references versus values of references.
A few years of Java really make it hard to write C++ again. Quick, which language is this?
That works in Java and C++ but for different reasons. It's usually safer in C++.
In Java that code is less safe because it hasn't been tested for null. That is, one of the following already happened:
-
Stuff stuff = null;
-
Stuff stuff = new Stuff();
-
Stuff stuff = Stuff.class.newInstance();
C++ gives you stronger references. For that same line of code, one of these already happened:
-
Stuff stuff;
-
Stuff *stuff_p = new Stuff(), &stuff = *stuff_p;
-
Stuff& f2() { Stuff stuff; return stuff; }
- This
refers to an object allocated on the stack. It's there, baby -- as much as anystufforint.float
- This
refers to an object successfully allocated in the heap.stuff
- Very bad.
destructed the stuff before giving it to you. Just keep compiler warnings on and it will bark "warning: reference to local variable 'stuff' returned"f2
What wasn't shown for C++ was
-
Stuff *stuff;
-
Stuff *stuff = null;
-
Stuff *stuff = new Stuff();
-
std::auto_ptr<Stuff> stuff(new Stuff());
- Uninitialized pointer, a.k.a. Runtime Russian Roulette. Unfortunately I couldn't get g++ to whine about this even with
.-Wall -Wpedantic -Wextra
- Null pointer, a.k.a. the minimum guarantee of Java.
- Hmm, I don't see a delete any where around here... uh-oh...
- There you go. You've got a smart pointer on the stack to prevent memory leaks, while preserving the expected
syntax.->
So WHAT? Really now!
Java guarantees that a reference will be initialized, and that it must always be tested for null. C++ warms the hearts of bearded old curmudgeons with more types of references. Each type is useful alone and in sometimes in conjunction (e.g. non-const references to pointers for output parameters). This is useful and important information to know. Draping Object everywhere and automating garbage collection is a lowbrow kludge.
Footnote 1: Groovy's safe navigation operator helps test for null by GOTOing the next safe expression. An interesting idea, and hopefully self-preventative. If I saw code with lots of '?' it would be up for a rewrite sooner rather than later.


