Tuesday, January 26, 2010

My First Spring Roo App (two months later)

Getting Started with Spring Roo


When I started working with Roo I think they were on RC 2 and now we are on the full-fledged Release 1.0.0, and I noticed that a lot of the tutorials that got me through those early days are a little outdated since a few common commands and generated output have changed over the past two months. I thought since I borrowed so heavily from the ROOsters before me (thanks BTW, Ben Alex and Stefan Schmidt) I would return the favor and talk about my experience a bit. I haven't gotten around to writing my own step-by step guide, but at least I can tell you more about why I chose Roo and pass along the things I have learned along the way.


I don't remember when I first learned about Spring Roo, but right from the start I was impressed. I cut my Spring teeth working on a few fairly large and complicated Spring webapps for about a year before I met Roo. I did the Springsource training, drank the koolaid; I honestly like working with Spring and I feel at home working in Java, but I did miss the fun and seemingly fast-paced development on the Rails projects from my past. Roo promised to bring back the fun and help to make a lot of the routine work of writing Java code disappear.


I had a little side project that started up in November of 2009; the idea was basically a really simple CRUD app. Three domain objects, some security, done. We all know how requirements do tend to change and multiply (especially when you bring a nice-looking and complete webapp as a demo to the first meeting, thanks to Roo), but this project is under control and I am still using Roo to add functionality (like email sending) and to manage the simple domain objects and their controllers and views.


Gotchas


Oh man, have I fallen into a few holes on my way to getting this app off the ground. Some of them turned out to be ROO bugs (I was working with the release candidates, after all) and others were just boneheaded mistakes on my part. In hopes of helping you avoid the same traps here is my list of gotchas and tips for working in Roo. I'll update these as I get a chance, but here are some of my recent lessons learned:


  • If you push in Roo on your domain object so that all of the entity management code is laying around and love to collect all of your imports under something like javax.persistence.* make sure you have an explicit import for javax.persistence.EntityManager. I usually set my minimum pretty low, so that if I optimize imports (ctrl + shift + o in eclipse/STS) then it will use a * instead of listing imports individually if I have more than 10 or so from the same package. That is normally fine, but causes serious problems for your little Roo app. It will yell at you for not returning the right type on your entityManager() method.
  • I am using some security on my manager methods and I went to write a test and I wasn't getting the results I expected. It was saying something about "can't parse expression" referring to the Spring EL expression that is used in the PreAuthorize annotation on my manager method. Well, it turns out I was using the wrong kind of authentication token to fake someone being logged in for my tests. Here is the real way to do it:


    I call this from my test:

    private void addResearcherToSecurityContext(Researcher researcher, boolean admin) {
         Collection authorities = researcher.getAuthorities();
         if (admin) {
             authorities.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
         }
         TestingAuthenticationToken authentication = new TestingAuthenticationToken(researcher, researcher.getPassword(), authorities.toArray(new GrantedAuthority[authorities.size()]));
         SecurityContextHolder.getContext().setAuthentication(authentication);
    }
    

    and put this in my test application context:
    <bean class="org.springframework.security.authentication.TestingAuthenticationProvider" id="testAuthenticationProvider" />
    

    and put this in my test application security context:
    <authentication-manager alias="authenticationManager">
    <authentication-provider  ref="testAuthenticationProvider" />
    </authentication-manager> 
    

    Simple, huh? It really is. You should know that my Researcher object extends UserDetails and that is what I use for authentication. Now I can write methods where I try to update someone else's account or do admin-y things as a non-admin and make sure that I get an access denied exception and all my data is safe.


  • This is more of a spring/hibernate thing than a Roo gotcha, but I'm going to put it here anyway because it just happened to me again... If you have a manager or, in this case, a test, and all of the methods are transactional. Don't annotate each method with @Transactional because inevitably you are going forget one time and then sit there running your test over and over wondering why it is saying "org.hibernate.SessionException: Session is closed!". You can stick the @Transactional on your class and then you are all set, no matter how many methods you add.
  • Don't forget: the forums and jira are your friends. There is also a seemingly constantly growing list of Roo links and resources on the forum

Thursday, November 19, 2009

Pair Exchange Program

I just finished the first ever pair programming exchange program!



It all started when I was at SDTConf back in October. I don't remember the exact conversation, but the question was generally if software development as a craft takes two programmers pairing together to pass on and practice the craft then how will it ever scale?



Someone jokingly suggested that Corey Haines should get a bigger car--Corey travels all over the place pairing with people and promoting the craft of software development. One idea that I think Corey actually proposed was the idea of a pair exchange.



The idea is simple: we can't all get Corey Haines or another big name in the XP, Agile, Craftsman, etc. communities to come and pair with us, but there are lots of smart people in every town. If you two are both passionate about practicing and improving your skills then why not use each other as a resource? Everyone has a vacation day to spare, take a day and go pair. If your boss will let you, bring your pair partner to work.



I know a lot of developers in Philadelphia and I had no trouble thinking of the perfect programmer to pilot my pair exchange program with. Woody Zenfell III is not only one of the smartest and most professional programmers I have ever worked with, but we make a killer pair. It is like our brains are wired almost exactly oppositely, but we get along really well. I like that he is fun to work with and we get a lot of good work done together. Plus, I know his company already and I know that he is on a team of 1 and is probably missing working with other developers.



When I first brought this idea up to my manager I had reason to be optimistic. My manager sees the value of pairing, even though my team doesn't really practice it much, and he is very supportive of learning and professional growth. I was thrilled when he agreed to the whole thing, both me going to Woody's office for a day and for Woody to come and pair with me and chat with my team. Woody's boss was also game and we were set!



We decided to do one day at each office, back to back. Since this was our first pair exchange we didn't really know what to expect other than that we would show up, work on some stuff and see what value we get out of it. For me, I knew Woody's code base pretty well, having actually worked on it with him back in our consultant days. For Woody, my team culture and our domain and the code base were all new, so a chunk of time in the morning went to talking about those things. Other than that we just paired; it was awesome. At Woody's place we had some tasks that needed to get done and so we did them. At my place we talked about design for a long time and wrote a test that I was having a hard time writing. Lots of great side-conversations happened with my teammate neighbors. It was fun and we got a lot done.



What did we get out of it?



For this first exchange it seemed like we were for the most part exchanging little tips, tricks and techniques that make us more efficient and effective. Woody, for example, showed me how he is creating dependency graphs (actual pictures) for all of the stored procedures and reports in his system, automatically, so that he can more confidently make changes to them. He is also getting those database elements into source control and refining a test and deployment process for them, which is something I hadn't thought of before, but is really smart given how important those reports are to his company. He also showed me captures in EasyMock, which were exactly what I was always dreaming of but never had because we were still using EasyMock 2.3. In return I showed him ctrl+r in cygwin/linux for searching your history. Then he showed me pushd and popd--that's just so handy.



In addition to tips and tricks we had a lot of conversations about how we do things, like how we work with our users and what process we follow for organizing our work and testing and deployment.



At the end of the second day we took several laps and talked about the experience. We agreed that it was definitely valuable and something we want to do again. We imagined that after a while we will run out of tips and tricks to show each other and then we didn't know what would happen then, but maybe that we could use each other as reinforcements for when something really sticky comes up and we need a fresh perspective. We talked about doing it again quarterly or monthly or more randomly. We aren't sure how our bosses viewed the experiment, and of course they would have to feel like they are getting a good deal out of this for them to allow it to continue. A lot of factors went in to making this experience go smoothly: the fact that we have both paired a lot before and with each other before, that our bosses are agreeable, there are no super-high security requirements that would prevent guests from coming over and peering at the code, etc. I am curious how well it would go if I was pairing with someone I didn't know very well.



I would love to hear about more people who are trying this sort of exchange. If you don't have teammates who pair (or teammates at all) you don't have to miss out on the benefits or pair programming--the discipline and the sharing of new ideas.

Thursday, May 21, 2009

Url patterns for servlet mapping

I came across a baffling problem with my servlet mapping recently for my java web application. In this project we generally use extension-based url patterns for servlet mapping. For example:



<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

This means that every request that comes in that ends in ".html" will get passed into my servlet instead of being handled by Tomcat (who would serve it up like a static file). The problem came up when we could not use extension mapping because we had a few .html files that needed to be served up by Tomcat and the rest were dynamically generated by my servlet. But when I tried to use a path-based url pattern it didn't seem to work as I would expect.



Here is the situation: I know that all .html urls that have the word "library" in the path to need to be sent to my servlet and all other .html requests to be handled by Tomcat, so I tried the following:



<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/library/*</url-pattern>
</servlet-mapping>

My servlet is expecting requests to come in like "/library/index.html", and it worked with the extension url mapping, but with the path url mapping it didn't. It was like nothing was getting passed into my servlet. I did some searching and I didn't find anything in the Java Servlet Specification or on any blogs or forums that explained why path matching would be so different from extension mapping, until I came across this post where PhilipT in the comments explained how tomcat was stripping out the matched part: "So it seems that the Tomcat default servlet (6.0.16 at least) drops the servlet mapping and will try to find the file by using the remaining path." This made me wonder if that always happens with path matching.


I also learned from that post that you can map urls back to tomcat from your servlets web.xml file. In our case we haven't tweaked tomcats configuration so the default servlet is called "default". I let my servlet handle all .html files and I tell tomcat to handle things that come through with the words "static-content" in the path. Since the order of precedence is exact matches, path matches and then extension matches this works exactly as I want it to.



<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static-content/*</url-pattern>
</servlet-mapping>

The only catch with this solution is that you have to remember to put /static-content/ in front of the path to the static content that you want served up by tomcat. It is possibly confusing because there is no "static-content" directory on the server. To give an example, the html files that need to be served by Tomcat are for the fckeditor that we use in our web application. When you want to include a fckeditor on a page you have to tell the javascript where to find the fckeditor home directory. For our project it is a directory called fckeditor sitting in the war directory for our application. Previously we would just say that the home directory was /fckeditor/ and Tomcat would know to find it in <war directory>/fckeditor. Now that we are using path matching we have to tell the fckeditor javascript that its home directory is /static-content/fckeditor/, even though it is still physically on the server at <war directory>/fckeditor

Thursday, April 10, 2008

Scrummity Scrum

As a software developer I find agile/lean practices in general to be a really awesome way to go about making awesome software. This means that you always shoot for the simplest thing that might possibly work and rapidly produce working software that you can show to your client, get feedback on, and improve. Lots of features that seem like great ideas in the beginning end up getting de-prioritized or thrown out all together and other great ideas are added. In the end the client ends up getting software that meets their needs at minimal cost---plus it's a fun way to work. Just saying "let's go lean" doesn't cut it though; the process of building custom software is complex and keeping the clients ideas and feedback organized and up to date so that work can get done effectively and without confusion is a challenge---especially when working on teams. That is where different agile tools come in. One of which is Scrum.

A little while back I completed my Scrum Master training in NYC. I really love it. Scrum is about making everything visible. At my office we have a Scrum board, onto which we pin user stories in different columns, reflecting whether they are to-do, in-progress or done. There is also space for impediments and tasks that the team needs to take on outside of the usual work of producing code. Each day my team gets together to check-in about which stories we worked on and which we intend to work on before the next check-in. As stories are completed throughout the day we walk up to the board and move the index card with the story written on it to the "done" pile. If at any time you don't know what to do, you can always walk up to the Scrum board and pick a task from the to-do pile and start working on it. At the end of each week the team gets together to reflect upon the previous week and every two weeks (our iteration length) we make a plan for the following iteration. Planning entails committing to complete a number of user stories before the next planning session.

Scrum also calls for a "Scrum Master" who runs interference for the team so that (ideally) nothing distracts them from completing the work for the iteration. The SM may also interface with the client to create and prioritize user stories for the upcoming iterations.

Friday, October 26, 2007

Thoughts: "The Outsourced Brain - New York Times"

The Outsourced Brain - New York Times by David Brooks. Read it here.
From the article: "...the magic of the information age is that it allows us to know less. It provides us with external cognitive servants."

I have been thinking a lot about the information age (vs. industrial age) and how technology is extending our minds (as it used to only extend out bodies). This op-ed really catches the essence of the current mind-extending possibilities of technology. Rest assured this is only the beginning... or is it?

Is it just the continuation of a trend that started when the first humans made the first tools?

McLuhan was the first to introduce me to the idea of extensions of ourselves (not personally, of course, but through his book "Understanding Media: the Extensions of Man") I was intrigued by his ideas (example: telephones are extensions of our voices), but it didn't really see technology extending my mind in my everyday life until I became dependent upon my cell phone and google to remember my friends phone numbers and where to find web pages and information that I want.

In the NYTimes op-ed (link above) Brooks claims that this mind-extension is liberating and blissful, but McLuhan often mentions that with extensions of man come amputations. Brooks can no longer navigate without his GPS and he feels zen about it, but what happens when the satellites go down? I am not comfortable with living in a world where I can't function without my tools. To use a historical example: the technology of guns extended mans ability to destroy people/things from afar but it amputated his ability to use a bow and arrow. What if then all the gunpowder ran out? As a pacifist I say all the better, but if people had a need for weapons they'd be screwed. Living in a time of transition from one technology to another this is the risk we face.

I hate to make this argument though because I hear it so often with regard to technology in education. Teachers say things like "why should we bring technology X into the classroom? Shouldn't we just stick with the old way of doing things?" Here is the rub, if you want to extend your mind you sometimes lose (amputate) an older way of doing things. I am sure there is a delicate balance between rushing headlong into adopting new extensions of ourselves and holding steadfast to tired old ways, but it is hard to know where to draw the line, especially within education when we are not only making the decision for ourselves, but for loads of children.

What I need is a good argument to convince educators that some technologies are more beneficial to students than traditional methods, others are not. Considering my argument against Brooks' GPS dependency, maybe I need to first convince myself.

Friday, October 5, 2007

Review of American Prometheus: The Triumph and Tregedy of J. Robert Oppenheimer by Kai Bird and Martin Sherwin.

From beginning to end I was captivated by the story if this enigmatic man, Robert Oppenheimer. He was sometimes arrogant, sometimes naive, and sometimes full of deep wisdom. He was sharp and charismatic to some, though others found him cold. He had a great gift for seeing the big picture and synthesizing ideas, which made him an especially effective leader of the scientists at Los Alamos working on one of the greatest scientific accomplishments of the century, the harnessing of atomic energy and the creation of the atomic bomb. He had to accept responsibility for the terrible destruction that his creation brought to the world but he didn't regret what he had done. At first I didn't understand why, but now I see his wisdom. The science which led to the making of the bomb was being realized by scientists all over the world and it was inevitable that someone was going to make it. In Oppenheimer's case, he felt it was urgent to beat the Nazis to it if they were indeed on track to produce it, which it turns out they really weren't, but he couldn't have known that at the time.


What left me most troubled after reading Oppenheimer's story was not his role in the creation of the bomb, but the way he was treated in the 1950's when his enemies sough to destroy him politically because they didn't agree with his pacifism. Oppenheimer was against the nuclear arms race and especially the creation of the hydrogen bomb, a much more powerful weapon than the atom bomb. The H-bomb couldn't really serve a military purpose, it wasn't even a city destroyer, it would destroy many cities at a time. In Oppenheimer's mind it would be more worthwhile to produce smaller tactical nuclear weapons for combat use, but the republicans in power felt that it would be wiser to instead focus on having the biggest bomb possible, thereby deterring anyone form ever attacking us for fear of total annihilation.


It is true that Oppenheimer had a past worthy of inspection for someone so close to so many national secrets, but despite the fact that no one managed to find him guilty of any crime other than making some "poor decisions" he was still left completely ruined by these accusations. Although the Atomic energy Commission "inquiry" found him totally loyal to America, they decided he was nonetheless a security risk. Why? Because he disagreed about the direction America was headed in foreign policy.


As I read the tactics used by his accusers I was shaken by the realization that nothing they did then couldn't happen today. While I don't want to believe that full scale McCarthy trials could happen in exactly the same way today I think a great scientist or intellectual like Oppenheimer could be taken down privately, the way Oppenheimer was, without justice and in the name of security. This kind of injustice does little to improve security, and even worse, it diminishes the likelihood that we as a society are going to come up with the solutions we need to face tomorrows security challenges because we have disbarred, alienated, or scared off our greatest minds from speaking up when they recognize a problem.


After finishing this book I sat and reflected upon the story and the potential for similar injustices taking place today and I wept. This story must be known by everyone.There is no black and white right and wrong to it, in the end Oppenheimer is not the golden hero, his enemies shamed, instead we are left to reflect upon our past and present actions, as Oppenheimer did his, and accept responsibility for our part in it, whether for good or for evil. Our ability to avoid future disasters depends on our ability to understand this and learn from it.


American Prometheus: The Triumph and Tragedy of J. Robert Oppenheimer by Kai Bird and Martin J. Sherwin. Vintage Books, New York. 2005

Sunday, September 16, 2007

Here is a post I made today for my class on learning technologies:

All of the authors (Engelbart, Schank and Cleary, and Valdez) made a distinction between the role that technology currently plays in teaching and learning and the potential role that technology can play. What seems to be of most interest to the bloggers so far is why the potential usefulness of technology in the classroom has not been reached.


Most would agree that teacher competence/comfort with the technology is a primary requirement for the technology to be useful in the classroom, and as Laura added there are other factors, like administrative and tech support that are important too. I want to add one more requirement to the list before moving on: the software has to be well designed.

Something that resonated with me from Schank and Cleary is that the authors admitted to the shamefully poor design of most educational software out there. Granted they were writing in the 90's, but I think that is still the case today. A lot of software is still written from top to bottom with only a vague idea of who the user is going to be. If a teacher (or any user) can't sit down and immediately figure out how to use the software, then the developer has failed. This is my opinion as a software developer, but it is not an uncommon one. My point is that as much as educators (and all users) need to familiarize themselves with new technologies and approach them with a workable attitude, the technologies have to lend themselves to being easily understood. Unless the creators of educational technologies are working together with educators, no progress can be made towards reaching the potential of technology's use in the classroom.


So what is the potential role of technology in the classroom?


Like textbooks, technology can be a source of information. Like pencil and paper technology can be used for creative purposes. To quote form Valdez, "A reasonable conclusion is that classroom computers and other technology can play many instructional roles, from personal tutor and information source to data organizer and communication tool" (from the overview). I think technology is already being used as an information source (web-based research) and a communication tool (email), and maybe as a data organizer (blackboard, excel), but I don't think classroom technologies have yet to reach their potential as personal tutors.


Each student has unique abilities and interests, but it is exceedingly difficult for one person to attend to the varied needs and interests of 30 young minds in the typical classroom. Technology can help, although it will mean changing the way we think about schooling. Something that I think is the most important point that I took from my reading of Engines for Everybody is the need for more student-directed learning, what Schank and Cleary also called natural learning. To summarize Schank and Cleary about natural learning, students learn best when they are the ones choosing what to learn and when. This doesn't mean that kids should be turned loose in the streets, this can happen in a regular classroom with a regular teacher (check out this biology class example).


I would like to further discuss the ways in which technology is or can be used to personalize each student's education.