<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6771745358752002825</id><updated>2011-12-06T17:08:33.795-08:00</updated><category term='ruby'/><category term='data integrity'/><category term='GWT'/><category term='JSP'/><category term='JavaServer Faces'/><category term='legacy'/><category term='actors'/><category term='singleton'/><category term='Continuous Build'/><category term='CI'/><category term='collection'/><category term='template'/><category term='initialization'/><category term='SOA'/><category term='convention'/><category term='HTML 5'/><category term='Build Server'/><category term='Module'/><category term='TDD'/><category term='Apache Commons Collections'/><category term='configuration'/><category term='Guava'/><category term='rails'/><category term='Hudson'/><category term='Grails'/><category term='No Fluff Just Stuff'/><category term='Build Automation'/><category term='professional'/><category term='courtesy'/><category term='Spring'/><category term='JUnit'/><category term='code'/><category term='JEE'/><category term='Unit Testing'/><category term='load test'/><category term='system'/><category term='dependency injection'/><category term='STM'/><category term='Struts'/><category term='Continuous Integration'/><category term='Apache Commons Lang'/><category term='Script'/><category term='OSGi'/><category term='technical'/><category term='Google Web Toolkit'/><category term='NFJS'/><category term='engine'/><category term='size'/><category term='stress test'/><category term='web services'/><category term='Java'/><category term='concurrency'/><category term='Groovy'/><category term='verbatim'/><category term='akka actors'/><category term='Canvas'/><category term='ruby on rails'/><category term='Learning'/><category term='integration'/><category term='thread safe'/><category term='Jenkins'/><category term='data types'/><category term='Agile'/><category term='optimistic locking'/><category term='HTML'/><category term='Software Transactional Memory'/><category term='WebGL'/><category term='JSF'/><category term='Tiles'/><category term='Java Server Faces'/><category term='framework'/><category term='Facelets'/><category term='Sitemesh'/><category term='htmLib'/><category term='data'/><category term='Metrics'/><title type='text'>Scripted Zen</title><subtitle type='html'>Random bits on software engineering, programming, and applications.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Joe</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/_CDHt6uFEfhk/THcot56QmoI/AAAAAAAAAAo/DM_gYcIJAGI/S220/100_0057.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-1190866881740209883</id><published>2011-12-06T16:57:00.000-08:00</published><updated>2011-12-06T17:08:33.817-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='professional'/><category scheme='http://www.blogger.com/atom/ns#' term='technical'/><category scheme='http://www.blogger.com/atom/ns#' term='courtesy'/><title type='text'>professional courtesy of presenters</title><content type='html'>The other day I went to an Akka presentation at a Scala Enthusiasts Group and I enjoyed it very much.  However I thought of some questions for the presenter after I had gotten home that night so I emailed them and it's been a few weeks without answer.  If you are presenting on something you should have the professional courtesy to answer follow up questions.  Maybe my questions were too basic, non-sense, or trivial but as a professional courtesy the presenter should have taken the time to answer.  Even an answer like I'm too busy this month to answer questions would have sufficed.  This lack of professional courtesy does not encourage me to use the technology, attend the group again, or touch base with this individual again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-1190866881740209883?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/1190866881740209883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=1190866881740209883' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/1190866881740209883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/1190866881740209883'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2011/12/professional-courtesy-of-presenters.html' title='professional courtesy of presenters'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-1636869732354572492</id><published>2011-12-03T11:03:00.000-08:00</published><updated>2011-12-03T12:07:01.210-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='dependency injection'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><title type='text'>spring framework, dependency injection, junit</title><content type='html'>I just joined a new team which is very different from my old team.  I don't want to go into the details too much but it was out of my control.&lt;br /&gt;&lt;br /&gt;My old team was very much into using the Spring Framework, dependency injection, and writing unit tests using JUnit.&lt;br /&gt;However my new team is very anti Spring, dependency injection, and unit tests.  They had some unit tests but they let them fall into abandonment.&lt;br /&gt;&lt;br /&gt;My old team was pretty much a new development team that didn't really do much support other than warranty after a release.&lt;br /&gt;&lt;br /&gt;My new team does production support and fixes but also does new development.&lt;br /&gt;&lt;br /&gt;I got into a conversation with one of the team members because I was using Spring context XML file.&lt;br /&gt;He was like it's so complex it took me a while just to figure out the project.&lt;br /&gt;This was really counter intuitive because I always thought that proper dependency injection made things less complex.  But he likes to press f3 and see everything defined so he can clearly trace from the beginning to the end of the app.  He saw it as introducing something overly complex into the application.  &lt;br /&gt;&lt;br /&gt;He went out of his way to say it was even evil and that we shouldn't use anything that new college graduate wouldn't be able to use.  This seems rather silly since we don't hire that many college graduates, they teach mostly theory, and little about practical tools to be productive.  I answered him we should use any tools that will make us more productive and writing boiler plate code all the time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let me ask this of the reader, do you agree you shouldn't use anything a college graduate couldn't figure out?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It seems now with the newest version most all that the XML is gone from Spring and with JEE 6 there will be less of a need for spring but the concepts are still there.&lt;br /&gt;&lt;br /&gt;Here's the benefits of Spring I see:&lt;br /&gt;- Bean life-cycle management&lt;br /&gt;- Promotes Dependency Injection&lt;br /&gt;- Has some nice DAO and Templates for ORM&lt;br /&gt;- Transactions management&lt;br /&gt;- Manages singletons instead of coding them&lt;br /&gt;- Focus writing code you need to instead of boiler plate code&lt;br /&gt;- Has some nice utilities to aid in unit testing (I like the simple JNDI stuff so to eliminate container resource dependencies)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let me ask this of the reader, is the Spring Framework really that complex and is there a set of problems where it's overkill?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then he came and asked me if I thought dependency injection was good.&lt;br /&gt;I came back and said yes with the following points:&lt;br /&gt;-It allows you to more easily write JUnit Test Cases externalizing the dependencies&lt;br /&gt;-It allows for classes to be single purpose principal and allow for separation of concerns. &lt;br /&gt;-It's getting built into the Java and JEE specs in the future (not sure which versions but we're not there yet)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let me ask this of the reader, you see value in dependency injection?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've gotten my projects setup on the continuous integration server so I can get complexity bugs from both Findbugs and PMD which is the kind of complexity I think we should really be concerned about.&lt;br /&gt;&lt;br /&gt;This brings me back to the type of team it is.  I'm thinking this is more of a classical programming team where they don't care if they introduce issues in prod because they can just fix them.  They spend more time fixing that unit testing which is more costly in the long time.  They don't see the connection between the production maintenance bug fixes and the lack of unit tests.  This also seems to me the difference is this team is more focused on programming rather than software development.  They don't do any sort of code reviews either which really surprises me.  Part of me thinks it's the culture that the main guy is getting older and doesn't want to learn new skills to the point he doesn't accept things very easily.  He probably never has worked anywhere else in his life and cares very little about changes in the industry and things stay relatively the same.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let me ask this of the reader, have you been in a similar situation?  What did you do?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-1636869732354572492?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/1636869732354572492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=1636869732354572492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/1636869732354572492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/1636869732354572492'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2011/12/spring-framework-dependency-injection.html' title='spring framework, dependency injection, junit'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-5906181073254820110</id><published>2011-10-16T20:08:00.000-07:00</published><updated>2011-10-16T20:28:15.849-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Web Toolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='Canvas'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML 5'/><title type='text'>GWT and HTML Canvas</title><content type='html'>I started to learn Google Web Toolkit this weekend and am very pleasantly surprised.&lt;br /&gt;I installed it via Eclipse update site and got right to work.&lt;br /&gt;I was able to manipulate the base project and look at the demos to figure out stuff.&lt;br /&gt;I was interested in creating a demo site using HTML 5 Canvas.  With little effort and writing zero JavaScript I was able to get an effective Demo.&lt;br /&gt;I used mainly base GWT classes but I did use some of the classes in gwt-g2d.  The main classes appear to be partly integrated into GWT so I mainly just used the support classes.  It would be nice if gwt-g2d did some of the things it had on it's list and wrapped GWT's canvas classes.&lt;br /&gt;GWT's tooling was very refreshingly fast and easy to use.&lt;br /&gt;I was able to write a little demo artificial intelligence app to show off different programming techniques I had learned in the class I'm taking.&lt;br /&gt;&lt;br /&gt;It would be nice if I could fail over my canvas to something else for browsers that don't support HTML 5. LimeJS appears to do this autmatically.  LimeJS is probably better for writing HTML based games but I don't want to write a bunch of JavaScript which is why I like GWT.  GWT automatically converts all my Java code into JavaScript for me.  &lt;br /&gt;&lt;br /&gt;Another thing is it puts the war contents in a war directory.  All the conventions I've seen it is always a WebContent folder.  Also the default source and test directories don't match the standard Maven structure which I imagine I could manually change but it's nice to be able to do it when creating a new project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-5906181073254820110?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/5906181073254820110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=5906181073254820110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/5906181073254820110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/5906181073254820110'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2011/10/gwt-and-html-canvas.html' title='GWT and HTML Canvas'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-560102115909825430</id><published>2011-10-01T14:24:00.000-07:00</published><updated>2011-10-01T14:29:42.939-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='framework'/><category scheme='http://www.blogger.com/atom/ns#' term='engine'/><category scheme='http://www.blogger.com/atom/ns#' term='WebGL'/><title type='text'>WebGL and game development</title><content type='html'>I would like to create a game with WebGL and have mainly a Java background. &lt;br /&gt;I don't have much game development experience and no professional experience.&lt;br /&gt;I have worked with OpenGL but it was years ago in college.&lt;br /&gt;&lt;br /&gt;I would like to know what engine/framework others would recommend.&lt;br /&gt;I don't really want to pay for a license or pro features so free would be one stipulation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-560102115909825430?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/560102115909825430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=560102115909825430' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/560102115909825430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/560102115909825430'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2011/10/webgl-and-game-development.html' title='WebGL and game development'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-9134335435539208852</id><published>2011-10-01T13:37:00.000-07:00</published><updated>2011-10-02T12:28:26.093-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='thread safe'/><category scheme='http://www.blogger.com/atom/ns#' term='STM'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Transactional Memory'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='akka actors'/><title type='text'>Akka Actors</title><content type='html'>I really like the notion of using &lt;a href="http://akka.io/"&gt;akka actors&lt;/a&gt; in Java.  Basically it is trying to solve the problem of easily writing thread safe code.  It does this by passing immutable messages to actors which process them.  The idea is that the actor should be stateless and only act upon the immutable object it's given.  They also appear to have Software Transactional Memory (STM) for when you do need mutable object and locking.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have doubts novice programmers which couldn't write a correct singleton or proper thread safe class would be able to use akka to write thread safe code.  I could see them creating all kind of actors which are not thread safe.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I did find it was really easy to get a lot of concurrency almost to a fault where my laptop was maxed out and overheating.  Of course that may have been my fault as I gave it an infinite computation to work on.&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;I don't understand why packages don't have remoting support built for the Servlet API.  Akka has a remoting support but I always work in a full J2EE container so getting ports opened and bypassing it would not be an option.  I would like to know who needs stand alone remoting and is not working with at least Tomcat.&lt;br /&gt;&lt;br /&gt;I'll definitely check akka out in more depth.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-9134335435539208852?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/9134335435539208852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=9134335435539208852' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/9134335435539208852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/9134335435539208852'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2011/10/akka-actors.html' title='Akka Actors'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-2662639468069128961</id><published>2011-10-01T13:19:00.000-07:00</published><updated>2011-10-01T13:35:48.342-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Apache Commons Lang'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Guava'/><category scheme='http://www.blogger.com/atom/ns#' term='Apache Commons Collections'/><title type='text'>Guava</title><content type='html'>I really like the &lt;a href="http://code.google.com/p/guava-libraries/"&gt;Guava libraries&lt;/a&gt;.  One of the best things in there is ImmutableList.  I like the idea of using ImmutableList on an interface.  This way you don't have to worry about synchronizing the list because the list won't change on you and throw a concurrent modification exception.  The builders are awesome.  Unlike Apache Commons Collections it supports Generics on collections which is awesome.  There's other Immutable collections and objects in this library too.&lt;br /&gt;&lt;br /&gt;I do find a lot of other useful utility classes in Guava but it is not as complete as Apache Commons Lang and Collections.  So I find myself using all three.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-2662639468069128961?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/2662639468069128961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=2662639468069128961' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/2662639468069128961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/2662639468069128961'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2011/10/guava.html' title='Guava'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-8441377557689056463</id><published>2010-08-25T08:22:00.000-07:00</published><updated>2011-03-19T18:32:04.738-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CI'/><category scheme='http://www.blogger.com/atom/ns#' term='Jenkins'/><category scheme='http://www.blogger.com/atom/ns#' term='Build Automation'/><category scheme='http://www.blogger.com/atom/ns#' term='Hudson'/><category scheme='http://www.blogger.com/atom/ns#' term='Build Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Metrics'/><category scheme='http://www.blogger.com/atom/ns#' term='Continuous Integration'/><title type='text'>Continuous Integration</title><content type='html'>We used continuous integration in my department for a year and wanted to share some feedback.  First just to summarize I absolutely loved it.  I tend to think about the time before we were using it as the dark ages and now we are in the renaissance of development.  We used Hudson for our continuous integration server.  We used the version prior to the fork with Jenkins and I'm not sure which I'd opt for now.  I'd probably go with Jenkins if the community moved there.  I may also refer to it as our build server although it really does a lot more than building. &lt;br /&gt;&lt;br /&gt;Benefits:&lt;br /&gt;1) Automatic feedback when somebody breaks the build.&lt;br /&gt;&lt;br /&gt;This is really important to get that immediate feedback so somebody can go in and fix things right away.  No more waiting for days and then discovering somebody made a change and everything is broken.  This was immensely helpful with our developers in India as they regularly forget to check in files.  If they don't leave things in a stable state they will get an email that the build is broken.&lt;br /&gt;&lt;br /&gt;2) Automatic running of unit tests.&lt;br /&gt;&lt;br /&gt;Some developers are better at writing unit tests than others.  Some don't bother to run them after they make changes.  Then when the application went from development to maintenance who knows if the tests were ran or updated.&lt;br /&gt;With a continuous integration the tests get ran automatically every time a build runs so you get an email if you've introduced something that goes against the set behavior outlined in the unit tests.&lt;br /&gt;&lt;br /&gt;3) Standardized project configuration and setup.&lt;br /&gt;&lt;br /&gt;Every application we created was basically up to the person creating them as to the folder structure and conventions used.  Once you start putting things on the build server you see the need for a standardized folders and conventions.  User libraries get standardized.  This helped us in the fact that once you have a job setup for a project you have standard setup for an application to refer to.  Less issues with it working on one persons machine and then not another persons machine.&lt;br /&gt;&lt;br /&gt;4) Automatic deployments&lt;br /&gt;&lt;br /&gt;We had the capability to automatically deploy the EAR files directly to our developer and staging environments.  This is a huge time saver and reduces errors.  There was always people exporting EAR files from our IDE, deploying them, and they wouldn't work.  Just repeated exporting and deploying can eat up time.  It's just nice that if the build is successful and passes unit tests that it is auto deployed.  This also helped with people working remotely from home as it was slow to deploy when connected to VPN.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5) Metrics&lt;br /&gt;&lt;br /&gt;The reports you get out of Hudson with plugins are great.  Unit tests pass/fail, code coverage, bugs.&lt;br /&gt;We utilized FindBugs, PMD, Task scanner, and Checkstyle plugins.  We also created a couple custom ones to suit our specific needs.&lt;br /&gt;The FindBugs and PMD bugs are great in that you can find common coding mistakes and critical errors like thread safety problems automatically.  They let you navigate to the line of code with issues and then gives you a description of the issue and an example how to fix it.  You can also check for duplicate code with the copy and paste feature.&lt;br /&gt;We are in the process of investigating enabling Crap4j and JDepend to measure complexity and dependencies.&lt;br /&gt;These reports are very helpful to determine when coding is complete and ready for integration testing.  For example: When the unit tests get to 70% code coverage, they all pass, there are no outsanding critical/high level bugs, and there are no open FIXME or TODO issues then you are ready to start integration testing.&lt;br /&gt;If someone ever asked my how confident that what we wrote is right I'd go to the code coverage to the conditionals covered and say well I'm 30% sure.&lt;br /&gt;The only report I didn't really find was lines of code which there probably is a plugin or option for.  With lines of code report you can tell when the lines of code have hit their peek and the developers are refactoring code instead of actually developing code which indicates they will be ready for integration testing soon.&lt;br /&gt;Some of the complexity warnings from PMD and FindBugs are helpful in detecting overly complex code which should be re-written so it will be easier to read and maintain but also less bugs and issues.&lt;br /&gt;&lt;br /&gt;6) Traceability and Meta-Information&lt;br /&gt;&lt;br /&gt;Every JAR built with the build server was given a fingerprint.  If the JAR is used in multiple builds you can trace the JAR back to which build it came from.  In addition we wrote out meta information with the build job name, build number in the MANIFEST.MF in the META-INF folder of EARs, JARs, and WARs.  This way we could look at our environments and see where an artifact actually came from.  We also utilized this a bit for our QA testers to report bugs they would write down this information so we could tell if it was an old bug that potentially needed retested or new bug.&lt;br /&gt;&lt;br /&gt;7) History&lt;br /&gt;&lt;br /&gt;You can keep a history of builds for however long you want.  This was helpful if we wanted to restore old code to back out changes quickly.  You can also see who introduced what changes and when.&lt;br /&gt;&lt;br /&gt;8) Fun&lt;br /&gt;&lt;br /&gt;We enabled the The Continuous Integration Game plugin which helps build good development habits of doing commits small sets of code changes and running unit tests before commits.  Basically if you break the build or break unit tests you get points subtracted.  If you have a successful build then you get points added.  It keeps track of a leader board. &lt;br /&gt;&lt;br /&gt;We also enabled the ChuckNorris Plugin which was loads of fun with funny pictures and programmer sayings when the build is broken or successful. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Drawbacks:&lt;br /&gt;1) Setup of projects.  &lt;br /&gt;&lt;br /&gt;It was nice for new applications we just used a generator to generate it according to standards.  However legacy applications were all built in a non-standard way.  We had to either add options to our build scripts to override the defaults or change the legacy applications.&lt;br /&gt;&lt;br /&gt;Once we got an example of each particular application type on the build server it was not really any effort at all to add another.  You just copy an existing job and change the parameters.&lt;br /&gt;&lt;br /&gt;2) Abandoned unit tests&lt;br /&gt;&lt;br /&gt;Some of our older applications had either no unit tests or were in such bad shape that most didn't pass anymore.  We had to set a standard for legacy or maintenance applications verses newly developed applications.&lt;br /&gt;&lt;br /&gt;3) Clearcase integration&lt;br /&gt;&lt;br /&gt;Clearcase did not seem to integrate well with Hudson as views would randomly get lost from the repository.  While this was an occasional hiccup it certainly was not enough to prevent us from continuing.  Not sure if we ever figured out the issue but we had the notion that ClearCase command prompt api was never tested with any concurrency of commands.&lt;br /&gt;We later moved to using Subversion with Hudson and it works wonderfully.&lt;br /&gt;&lt;br /&gt;4) Ant&lt;br /&gt;&lt;br /&gt;While Ant is a wonderful tool I believe we could have managed build inter-dependencies better if we had used Maven with an artifact repository.  A lot of times we manually copied jars from the build server and checked them into the consuming application's code.  It would be nice if we were using Maven that if we changed a Java Project the build would create a new JAR and publish it to the maven repository.  Which in turn would be detected and kick off builds for all the applications that used that JAR.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-8441377557689056463?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/8441377557689056463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=8441377557689056463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/8441377557689056463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/8441377557689056463'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2010/08/continuous-integration.html' title='Continuous Integration'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-2111596960812039157</id><published>2010-08-21T04:42:00.000-07:00</published><updated>2011-03-17T23:57:38.077-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='collection'/><category scheme='http://www.blogger.com/atom/ns#' term='initialization'/><category scheme='http://www.blogger.com/atom/ns#' term='size'/><title type='text'>Collection Initialization</title><content type='html'>Early in my career, fresh out of college, I inherited the code for one of our tools that ran on a nightly timer.  I was in charge of enhancing part of the application to add some functionality.  &lt;br /&gt;&lt;br /&gt;Fresh out of college I remembered that initializing hash maps size to just over the desired size leads to optimal hashing.  Basically without proper sizing everything is hashed to the same node in a linked list which defeats the purpose of a hash map.&lt;br /&gt;&lt;br /&gt;This tool used to take around 8 hours which was scheduled to run at night.  &lt;br /&gt;So you might think the following:&lt;br /&gt;1) So what if it is more efficient&lt;br /&gt;2) It re-sizes itself so why bother doing it myself&lt;br /&gt;&lt;br /&gt;After I initialized the the hash map to the appropriate size the tool went from running 8 hours to running in less than an hour.  That's a 7 hour gain.&lt;br /&gt;After this I realized that:&lt;br /&gt;1) Collections take time to dynamically re-size.&lt;br /&gt;2) Collections will constantly be resizing as they run out of room.&lt;br /&gt;&lt;br /&gt;Now that the tool took less than an hour it could be run a couple times during the day ad-hoc.  When changes were needed to the tool you could verify the results in a manageable time period.  When the job failed for whatever reason the whole task could be restarted and do two days of work in 2 hours instead of 16 hours.&lt;br /&gt;&lt;br /&gt;Suggestions as to when you should initialize collections:&lt;br /&gt;1) If you are going to put more than 100 objects in it.&lt;br /&gt;2) If you are a cautious/defensive developer like me.&lt;br /&gt;&lt;br /&gt;I'm not as worried about getting the optimal size as long as you are relatively close.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-2111596960812039157?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/2111596960812039157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=2111596960812039157' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/2111596960812039157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/2111596960812039157'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2010/08/collection-initialization.html' title='Collection Initialization'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-8721073627281637654</id><published>2010-07-03T19:57:00.000-07:00</published><updated>2010-07-03T20:14:54.821-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JEE'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Module'/><title type='text'>OSGi and JEE.  Is it possible?</title><content type='html'>I am curious about others experiences OSGi with JEE?  OSGi seems like a solution to dependency collisions, allows for versioned modules, and hot deployment.  I've seen several different variations on using OSGi with JEE.  It seems application servers are starting to pick up on it which is a great thing.  However I was wondering if anyone has used it for local native services?  I see people use it for Servlets and serving simple JSPs.  I was hoping to use it for local native Java services that allow exposing interfaces in Java like web services do but don't bring any dependencies into the picture like normal POJO Java Services do.  Unlike web services OSGi services should  not have the overhead of transferring things over the wire.  I've saw forum postings where people have troubles using JEE resources that are exposed through JNDI. Is this really an issue that is of concern?  Also if people have any tools or tips for working with OSGi bundles it would be much appreciated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-8721073627281637654?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/8721073627281637654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=8721073627281637654' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/8721073627281637654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/8721073627281637654'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2010/07/osgi-and-jee-is-it-possible.html' title='OSGi and JEE.  Is it possible?'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-6526051107259191887</id><published>2010-06-19T07:23:00.000-07:00</published><updated>2010-06-19T08:14:34.304-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stress test'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='load test'/><category scheme='http://www.blogger.com/atom/ns#' term='thread safe'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='singleton'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Thread Safe Code and Stress Testing</title><content type='html'>It just amazes me how much code makes it past code reviews that is not thread safe but should be.&lt;br /&gt;Developers often know that certain code has troubles if it is not thread safe and what thread safe means.  However they are not able to effective discern what needs to be thread safe and what does not.  I had an individual that was very aware of these issues help mentor me as to how to detect these types of problems.  I had seen problems and fix them prior to his mentoring but he really helped me to be proactive and see threading issues when authoring code.&lt;br /&gt;&lt;br /&gt;The biggest issue is lack of understanding that beans defined in Spring are singletons.  Also even if you inject a prototype into a singleton it effectively makes it a singleton.  Then there are the problems where they improperly implement the singleton pattern, randomly synchronize things that don't need to, or create static variables that are not thread safe.  I've seen so many times where developers create a static SimpleDateFormat instance.  Recently I saw a DAO with local variables that were not thread safe.  I also recently saw a persistence layer where they tried to manually implement the singleton pattern but didn't do it correctly so the local variables that were thread safe were not initialized correctly leading to NullPointerExceptions. &lt;br /&gt;&lt;br /&gt;I tend to see threading issues revealed when load testing is performed.  However to my amazement load testing is not always performed.  I've also seen some some threading issues that have snuck past load testing and have never presented themselves as a problem.&lt;br /&gt;&lt;br /&gt;We use a continuous integration build server but it only lists thread safety problems as warnings and then only catches half of them because it doesn't know what should or shouldn't be a singleton and thread safe any more than the developers do.&lt;br /&gt;&lt;br /&gt;I've recently initialized an internal developer training effort.&lt;br /&gt;There are relatively few developers that can detect these errors and even fewer that can fix them.  So it is really an issue as these developers can not code review every line of code.&lt;br /&gt;&lt;br /&gt;Are there any ways to catch these kind of problems earlier or some good resources to aid in developer training?  Do people have similar experiences?  &lt;br /&gt;&lt;br /&gt;It seems most developers don't care that code has any more quality than it appears to work correctly.  Am I being a little anal retentive and should just go with the flow, realize that code will not be perfect, and just let these problems exist and get resolved later?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-6526051107259191887?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/6526051107259191887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=6526051107259191887' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/6526051107259191887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/6526051107259191887'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2010/06/thread-safe-code-and-stress-testing.html' title='Thread Safe Code and Stress Testing'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-3688925861835233028</id><published>2010-06-15T10:06:00.000-07:00</published><updated>2010-06-15T10:28:19.834-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Script'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Learning'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>First Groovy Script</title><content type='html'>A couple days ago I wrote my first Groovy script.  Of course it had to be loaded into the Spring IoC container to wire it up to the beans using it.&lt;br /&gt;Having a Java background and looking at Groovy's website it was very hard to define a pretty simple class with a method that implements a java interface.&lt;br /&gt;First it made me use the def keyword with the method definition whereas the documentation didn't even have an example of how to write a method.&lt;br /&gt;Then it made me define the return type of the method because it was saying it didn't match the interface return wheras the documentation seemed to indicate these did not have to be statically defined/typed. &lt;br /&gt;The method took in no parameters and returned a List&lt;MyObject&gt; and was returning [instanceofMyObject1, instanceofMyObject2]&lt;br /&gt;The documention showed defining typeless variables without using the def keyword.&lt;br /&gt;It kept looking for member variables in the class so I had to define each one with the keyword def to get it to work.&lt;br /&gt;&lt;br /&gt;Is the Groovy documentation really lacking good basic examples like writing a class with a method and using local variables?&lt;br /&gt;&lt;br /&gt;The documentation outlined some of the power features but did very little to help people learn the basics other than go over some command line Groovy examples.&lt;br /&gt;&lt;br /&gt;Can people recommend some good resources for a Java developer to learn and effectively take full advantage of the capabilities of Groovy?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-3688925861835233028?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/3688925861835233028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=3688925861835233028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/3688925861835233028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/3688925861835233028'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2010/06/first-groovy-script.html' title='First Groovy Script'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-419447327778316411</id><published>2008-08-21T23:29:00.000-07:00</published><updated>2008-08-23T09:40:18.611-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data'/><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><category scheme='http://www.blogger.com/atom/ns#' term='web services'/><category scheme='http://www.blogger.com/atom/ns#' term='legacy'/><category scheme='http://www.blogger.com/atom/ns#' term='system'/><title type='text'>Integrating Legacy Systems</title><content type='html'>Recently we tried to integrate a legacy system via exposing a few mainframe programs via web services.  &lt;br /&gt;&lt;br /&gt;Exposing data as a web service does not make a web service.&lt;br /&gt;Lets examine why:&lt;br /&gt;  a) Lack of re-usability - The mainframe programs return course grained data specific to a particular need it was developed for.  This leads to having more data and more specific data than any other app would need to reuse the data.  For example instead of a code or status returned it returns a message intended to be used by the consuming application.  This data is virtually unusable to another application because most of the time you need the deciding code or status to perform logic later on.&lt;br /&gt;  b) Lack of performance - Instead of returning a code or status very verbose text is being returned.  Now instead of a low overhead code or status you have a large message being transferred over the wire which may not be used.  If this web service is consumed by another web service layer then transporting this around is going to be slow.&lt;br /&gt;  c) Design constraints - The mainframe program was designed for a particular use which they didn't take into account limiting the repetitive sections.  They would return all 100 instances of a section of data.  If only the first 5 had data they would return all 100.  This adds great overhead on a web service.  Also the data that comes from a mainframe program is not trimmed and has filler fields filled with whitespace.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you don't have somebody regulating or asking the right questions then anything will become a web service which shouldn't be.  I recommend a group of architects and/or tech leads making the decision of whether something should be a service.&lt;br /&gt;&lt;br /&gt;Here are some guidelines/questions to ask yourself for web services:&lt;br /&gt;1) Ask yourself or group why are we making this a web service?  What are we hoping to accomplish?&lt;br /&gt;  a) When you go to a web service you are giving up performance for agility.&lt;br /&gt;  b) Make sure you're willing to deal or accept the trade off.&lt;br /&gt;2) Does it meet any of this criteria?&lt;br /&gt;  a) Is this going to reusable by other applications?  Which ones?&lt;br /&gt;  b) Is this something that crosses boundaries or something which I can't control?    For example if you are exposing something to another business unit or exposing it for public use.&lt;br /&gt;  c) Is this enabling system integration for systems that were not able to integrate before.&lt;br /&gt;  d) Is this coarse grained enough for general use?&lt;br /&gt;  e) Is this data going to be suitable for multiple hops?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-419447327778316411?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/419447327778316411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=419447327778316411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/419447327778316411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/419447327778316411'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2008/08/integrating-legacy-systems.html' title='Integrating Legacy Systems'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-7985747127733745105</id><published>2008-08-16T09:04:00.001-07:00</published><updated>2008-08-16T09:47:09.220-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data integrity'/><category scheme='http://www.blogger.com/atom/ns#' term='data types'/><title type='text'>Building the Base - Data Integrity</title><content type='html'>Something I feel is far too often overlooked in software development is data integrity.&lt;br /&gt;I would like to further define it as strong data typing.&lt;br /&gt;&lt;br /&gt;The source of lack of strong data typing is several places.&lt;br /&gt;1) Lack of proper column types in the database.&lt;br /&gt;2) Reuse of typed columns to mean different things.&lt;br /&gt;3) Programs/Stored Procedures that decrease the strength of data typing.&lt;br /&gt;4) Flat file (fixed record formats)&lt;br /&gt;&lt;br /&gt;Now I'm not a DBA or anything like that.  &lt;br /&gt;But one thing I've noticed when developing JSF applications is lack of data integrity seems to bubble it's way up into the presentation layer.&lt;br /&gt;&lt;br /&gt;It should be dealt with at the source to provide a better base for an presentation/gui layer.&lt;br /&gt;&lt;br /&gt;1) Lack of proper column types in the database.&lt;br /&gt;If you are using clobs, blobs, text, varchar, or whatever flavor of large catch-me-all for typed data please stop.  One symptom is that all your columns seem to have the same type.  Please use date, int, time, timestamp, bit, numeric, float, decimal, bigint, tinyint.&lt;br /&gt;&lt;br /&gt;2) Reuse of typed columns to mean different things.&lt;br /&gt;Use of low values or high values to mean something:&lt;br /&gt;99.99, -1, or any date like January 1st, 1900.&lt;br /&gt;I think almost any database or language has null built in for this reason.&lt;br /&gt;I'll see logic if 0.00 or 99.99 then display N/A so why don't we just define another column with a one character value and a domain table.&lt;br /&gt;So instead of this: &lt;br /&gt;Effective Date: Jan 1st, 1900&lt;br /&gt;We do this:&lt;br /&gt;Effective Date: null  Effective Status: 'P'&lt;br /&gt;where there would be a Domain Table with things like 'P' - Pending, 'T' - Terminated, 'I' - Invalid and 'U' - Under Review&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3) Programs/Stored Procedures that decrease the strength of data typing.&lt;br /&gt;If you read in two strongly typed and return a lesser typed one this would be a smell.  For example if you take two Numbers in and generate a String number result and N/A result sometimes.&lt;br /&gt;&lt;br /&gt;If you take two specific things and return a generic one then that is a smell.&lt;br /&gt;For example if you take name fields and put them together to display.  Well this is all good but what if you then want to pre-populate a name into a form.  How do you parse a complex name which may or may not have middle initials and a suffix?&lt;br /&gt;&lt;br /&gt;4) Flat file (fixed record formats)&lt;br /&gt;This is the root of all evil because there are no rules as to what goes where as long as it fits.&lt;br /&gt;I propose that you establish a contract with the generator about the types if possible.&lt;br /&gt;Don't leave it in flat file format, extract it into a strongly typed database and throw out invalid data.  It is better to throw out or reject rows than to have it in your database.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-7985747127733745105?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/7985747127733745105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=7985747127733745105' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/7985747127733745105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/7985747127733745105'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2008/08/building-base-data-integrity.html' title='Building the Base - Data Integrity'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-6509819273488199304</id><published>2008-08-03T05:17:00.000-07:00</published><updated>2008-08-21T23:26:53.333-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Facelets'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='NFJS'/><category scheme='http://www.blogger.com/atom/ns#' term='Continuous Build'/><category scheme='http://www.blogger.com/atom/ns#' term='No Fluff Just Stuff'/><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>No Fluff Just Stuff</title><content type='html'>This is the second year I've attended the No Fluff Just Stuff conference.  &lt;br /&gt;&lt;br /&gt;If you've never experienced the conference and you do any kind of software development that involves/runs on the Java VM (Java EE, Java SE, Groovy, Grails, etc) I strongly encourage you to go.&lt;br /&gt;&lt;br /&gt;Even if you don't do any Java related software development but you work in Quality Assurance/Testing or Business Analyst/Requirements Development there are beneficial courses for you too.  Some of these courses seem to be more geared towards this group but are attended mostly by developers.  This seems to stress the notion of one software developer to change the world.  One thing that comes from some of these sessions is the notion of collaboration.  So instead of one person in one group (Software Development in my case) I'd like to encourage people from other groups (Quality Assurance/Testing or Business Analyst/Requirements Development) to attend also.  This way we can change the world together!&lt;br /&gt;&lt;br /&gt;The only thing I can say in any way negative about this conference is they seem to have a lot of things that are new and shiny new things like Groovy, Grails, Agile, and GWT.  I work in a large behemoth of a company that is a slow moving, slow to adopt, vendor locked, internal standards driven.  These things seem to be something that can be implemented more in small shops or don't have resistance to change (or regulations).  Even this being said I still thing attending some of these are good for me because you can extrapolate some of the tips for your organization even if it really is an apples vs oranges environment.&lt;br /&gt;&lt;br /&gt;I really enjoyed some of the concurrency, architecture and scaling, SOA, and Agile sessions.  Last year I liked some of the continuous build, testing, and hacking sessions.  I find some of the Facelets, JSF, Spring, Hibernate courses rather introductory but for some might be invaluable.&lt;br /&gt;&lt;br /&gt;One thing (it's hard to name everything) I really like about the conference is that it is small enough you can ask questions and have a small group feel.  A lot of the sessions are interactive and make good points.&lt;br /&gt;&lt;br /&gt;You really get a lot of books recommendations from this conference some related more to software development philosophy rather than really technical books.&lt;br /&gt;&lt;br /&gt;The keynote speech is greatly entertaining, funny, and informative.&lt;br /&gt;&lt;br /&gt;This conference is also big on open source and you don't find any real vendor driven presentations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-6509819273488199304?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/6509819273488199304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=6509819273488199304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/6509819273488199304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/6509819273488199304'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2008/08/no-fluff-just-stuff.html' title='No Fluff Just Stuff'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-3195175881085296036</id><published>2007-12-07T04:52:00.000-08:00</published><updated>2007-12-09T15:26:17.855-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='verbatim'/><category scheme='http://www.blogger.com/atom/ns#' term='JSP'/><category scheme='http://www.blogger.com/atom/ns#' term='Facelets'/><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='htmLib'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaServer Faces'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>JSP vs Facelets</title><content type='html'>One of the saddening aspects of JSF is the rendering of HTML along with JSF components in JSP pages.&lt;br /&gt;For example&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&amp;lt;div&amp;gt;&amp;lt;div&amp;gt;Some Header&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;ul&amp;gt;&lt;br /&gt;   &amp;lt;li&amp;gt;&amp;lt;h:outputText value="list item 1"&amp;gt;&lt;br /&gt;   &amp;lt;/h:outputText&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;&amp;lt;h:outputText value="list item 2"&amp;gt;&lt;br /&gt;&amp;lt;/h:outputText&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;will actually render as&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;list item 1list item 2&lt;br /&gt;   Some Header&lt;br /&gt;&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&lt;br /&gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;&lt;br /&gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Alright now the problem is that the HTML is written out right away and the JSF components are rendered at a different time.&lt;br /&gt;&lt;br /&gt;Another situation is when you have HTML before or after a JSF Component.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&amp;lt;h:panelGroup&amp;gt;&lt;br /&gt;     &amp;lt;p&amp;gt;some markup&amp;lt;/p&amp;gt;&lt;br /&gt;           &amp;lt;h:outputText value="some text"/&amp;gt;  &lt;br /&gt;      &amp;lt;p&amp;gt;some more markup&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/h:panelGroup&amp;gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;will render as&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;some text&lt;br /&gt;some markup&lt;br /&gt;some more markup&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Now if you ask me since the default view is JSP for JSF they should have taken this into account.&lt;br /&gt;&lt;br /&gt;They should key off the include of JSF tags in a page to parse the JSP differently.&lt;br /&gt;Instead of rendering it like they do they should gather the HTML and attach it to the view in a verbatim component or some other kind of ui output component in the appropriate place in the JSF component tree.  This should be possible because everything should be enclosed in a &amp;lt;f:view&amp;gt; tag.&lt;br /&gt;&lt;br /&gt;Either that or you have the custom jsf tags be body aware which I assume they are and output the html prior to rendering their component/child component and then render html after the component.&lt;br /&gt;&lt;br /&gt;I'm not sure which way is best or where this would take place but it seems very doable.&lt;br /&gt;&lt;br /&gt;Now some people say Facelets is the answer and dump JSP all together.&lt;br /&gt;I agree this is a way to fix it but this doesn't let you reuse any JSP tags that are non-JSF.&lt;br /&gt;In the real world there are lots of JSP tags that are not JSF that still need to be reusable.&lt;br /&gt;Also there was a reason for JSP pages in the first place and I'm not sure facelets fully fills that gap.&lt;br /&gt;&lt;br /&gt;The real answer should be to fix JSP complation, JSP Rendering, or JSF tags where ever this should take place.&lt;br /&gt;&lt;br /&gt;Whoever was responsible for the JSF spec should have seen to this in the first 1.0 release.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-3195175881085296036?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/3195175881085296036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=3195175881085296036' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/3195175881085296036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/3195175881085296036'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2007/12/jsp-vs-facelets.html' title='JSP vs Facelets'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-6034818759849153961</id><published>2007-08-12T06:20:00.000-07:00</published><updated>2007-08-14T01:52:08.301-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Facelets'/><category scheme='http://www.blogger.com/atom/ns#' term='convention'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitemesh'/><category scheme='http://www.blogger.com/atom/ns#' term='configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='JSF'/><category scheme='http://www.blogger.com/atom/ns#' term='template'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Server Faces'/><category scheme='http://www.blogger.com/atom/ns#' term='Tiles'/><category scheme='http://www.blogger.com/atom/ns#' term='Struts'/><title type='text'>Tiles Killed Convention - Facelets Templating</title><content type='html'>I recently went to a developers conference and listened to a rapid application development with JSF session by David Geary.  I found the session very helpful and informative but something keeps bothering me every time somebody talks about templating as he did with Facelets.&lt;br /&gt;&lt;br /&gt;Every time I hear about templating I think it should be easier and more reuseable.  I started out developing Struts applications which use Tiles.  I then moved on to JSF and Tiles.   The nice thing about Tiles is "it works".  Sometimes just working is not enough and a little convention goes a long ways.&lt;br /&gt;&lt;br /&gt;Recently I've been thinking about the convention over configuration mentality that RoR uses.  Also I've come upon a great templating package called Sitemesh.  What I love about Sitemesh is you can define a decorator and decorate multiple pages by a matching URL pattern.  This is a GREAT idea.  Using Tiles I've always had to create a definition for every page in a Tiles definition file, a JSP that inserts the definition, and the page that actually has the content.  Well that's three files for each page of content the user sees.  Now the problem I have with this is the Tiles definition  for the page and the tiles insert JSP is basically repeated for every page.   Sure you can define a base Tiles definition and extend it but it tends to be mostly repetitive.  You can also define your tiles definition in the JSP page which is just as messy and repetitive.&lt;br /&gt;&lt;br /&gt;Let me get back to Facelets.  Facelets is a wonderful idea to use the html view and bind to components.  The problem is when you get to the templating part it goes back to the Tiles mentality again.  You have a page which defines a composition and a page which contains the content.  The page with the composition is repeated for every content page and in most cases the exact same composition definition.  This is where the convention of Sitemesh is nice and could come in handy.  It would be nice if you could define a Facelets composition for a URL path and apply it to all pages in a directory.  That's a heck of a start for reuse and convention over configuration.  Then you can just configure the exceptions to the case which should be rare.&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;  Sidenote: You can use JSF components in a Sitemesh decorator (http://jira.opensymphony.com/browse/SIM-201).&lt;blockquote&gt;&lt;/blockquote&gt;There are a couple of positive benefits to applying templates based on a URL path that are a side effect.  I've been on too many projects where everything is thrown into the base directory of a web application or relatively few directories.  This gets out of hand quickly and not good structure.  There are also security packages like Acegi that will apply security based on the URL path.  So if you have your files in an appropriate file structure it should be easy to find pages, apply templates, and apply security.&lt;br /&gt;&lt;br /&gt;(If you don't think it can be done check this out: http://jira.opensymphony.com/browse/SIM-223)&lt;br /&gt;&lt;br /&gt;This brings up another annoyance of JSF.  JSF has no notion of subdirectories built in.  With Struts you could define config files for each URL path and then you didn't need to put the subdirectory paths for the JSP pages in a configuration file.  JSF should add this in and promote appropriate directory structure.&lt;br /&gt;&lt;br /&gt;As a closing note if you're doing something multiple times and not much changes maybe you should refactor it out.  If you are doing this in programming maybe you would extract the commonalities out into a method passing in the parameters and then the method can be reused. In the case of a templating package you should refactor the configuration out of the JSP page or Faclets xhtml view and move it into the URL path with a configuring Servlet or Filter.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-6034818759849153961?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/6034818759849153961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=6034818759849153961' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/6034818759849153961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/6034818759849153961'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2007/08/tiles-killed-convention-facelets.html' title='Tiles Killed Convention - Facelets Templating'/><author><name>BusyByte</name><uri>http://www.blogger.com/profile/14304598155320168408</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-1159878290450718608</id><published>2007-08-09T10:03:00.000-07:00</published><updated>2007-08-09T10:37:12.734-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='optimistic locking'/><category scheme='http://www.blogger.com/atom/ns#' term='ruby on rails'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Optimistic Locking in Rails with Active Record for Free...almost</title><content type='html'>Like other persistence frameworks, ActiveRecord helps us with concurrency issues.  This is actually fairly simple, but in general the documentation I have found on this subject has been poor.  I will try to sum this up very quickly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1) Add lock_version&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    For each table where concurrency is a concern a lock_version column must be added; Rails is then supposed to perform some magic behind the scenes...&lt;br /&gt;&lt;br /&gt;   In your migration this should look as follows.&lt;br /&gt;   table_name.column :lock_version, :integer, :default=&gt;0&lt;br /&gt;&lt;br /&gt;  Alternatively, if you already have a versioning column in your database you can inform rails of your column by adding the line "set_locking_column 'your_versioning_column_name'" to the associated model class.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2) Catch StaleObjectError&lt;br /&gt;&lt;br /&gt;      &lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Now that you have added the lock_version column you get concurrency for free.  Whenever an attempt occurs to save over the same record version an ActiveRecord::StaleObjectError will be raised.&lt;br /&gt;&lt;br /&gt;     So now you can update your controllers to catch StaleObjectErrors and handle these however you wish...&lt;br /&gt;&lt;br /&gt;     This would look something like this.&lt;br /&gt;&lt;br /&gt;      def some_updating_method(an_object)&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;        &lt;/span&gt;an_object.update_attributes(params[:an_object])&lt;br /&gt;      rescue ActiveRecord::StaleObjectError =&gt; e&lt;br /&gt;        flash[:notice] = "This record changed while you were editing it.  Please try again."&lt;br /&gt;        #maybe perform a redirect here...&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3) But Wait!  Update methods aren't actually passed objects that's too much overhead!&lt;br /&gt;&lt;br /&gt;     &lt;/span&gt;How observant you are.  This is where most of the example tend to fall short.  In fact, try implementing your update method exactly like Recipe 3.18 from the Rails Cookbook and see what happens...&lt;br /&gt;&lt;br /&gt;    Generally an update method actually looks more like this.&lt;br /&gt;   &lt;br /&gt;   &lt;span style="font-style: italic;"&gt; def update&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;     my_object = MyObject.find(params[id])&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;     my_object.update_attributes(params[:my_object])&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;   end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   While this will stop to users from updating at the exact same time this isn't exactly what we want in many cases.  More often than not we want to prevent two users from editing over each other without knowing. &lt;br /&gt;&lt;br /&gt;  This is easily fixed with the following...&lt;br /&gt;&lt;br /&gt;  def edit&lt;br /&gt;     my_object = MyObject.find(params[id])&lt;br /&gt;     session[lock_version] = my_object.lock_version&lt;br /&gt;      # whatever we want edit to do&lt;br /&gt;     # ...&lt;br /&gt;     # ...&lt;br /&gt;     # call update...&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  Now we update update (har har) to detect the concurrency issue...&lt;br /&gt;&lt;br /&gt;      &lt;span style="font-style: italic;"&gt;def update&lt;/span&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;        if my_object.lock_version != session[:lock_version]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;           raise ActiveRecord::StaleObjectError&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;         end&lt;/span&gt;&lt;br /&gt; &lt;span style="font-style: italic;"&gt;        my_object = MyObject.find(params[id])&lt;/span&gt;&lt;br /&gt; &lt;span style="font-style: italic;"&gt;        my_object.update_attributes(params[:my_object])&lt;/span&gt;&lt;br /&gt; &lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;     &lt;/span&gt;&lt;span style="font-style: italic;"&gt; rescue ActiveRecord::StaleObjectError =&gt; e&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;         flash[:notice] = "This record changed while you were editing it.  Please try again."&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;         #maybe perform a redirect here...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;       end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hopefully this helps someone out.  If you have a better/cleaner way of doing this, let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-1159878290450718608?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/1159878290450718608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=1159878290450718608' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/1159878290450718608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/1159878290450718608'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2007/08/optimistic-locking-in-rails-with-active.html' title='Optimistic Locking in Rails with Active Record for Free...almost'/><author><name>Joe</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/_CDHt6uFEfhk/THcot56QmoI/AAAAAAAAAAo/DM_gYcIJAGI/S220/100_0057.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6771745358752002825.post-4653986059083866158</id><published>2007-08-02T07:28:00.000-07:00</published><updated>2007-08-02T07:32:03.866-07:00</updated><title type='text'>Drop all tables in MySQL</title><content type='html'>From time to time I would like to be able to drop all of the tables in my MySQL database without actually dropping the database.  This can be painful if there are many tables in the database.  Recently I came across this little nugget that simplifies the process.&lt;br /&gt;&lt;br /&gt;mysqldump -u[username] -p[password] --add-drop-table --no-data [database] | grep ^DROP | mysql -u[username] -p[password] [database]&lt;br /&gt;&lt;br /&gt;Voila!  All your tables are gone!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6771745358752002825-4653986059083866158?l=scriptedzen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scriptedzen.blogspot.com/feeds/4653986059083866158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6771745358752002825&amp;postID=4653986059083866158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/4653986059083866158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6771745358752002825/posts/default/4653986059083866158'/><link rel='alternate' type='text/html' href='http://scriptedzen.blogspot.com/2007/08/drop-all-tables-in-mysql.html' title='Drop all tables in MySQL'/><author><name>Joe</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/_CDHt6uFEfhk/THcot56QmoI/AAAAAAAAAAo/DM_gYcIJAGI/S220/100_0057.jpg'/></author><thr:total>0</thr:total></entry></feed>
