<?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-7625178889455096573</id><updated>2012-01-12T17:37:34.263-06:00</updated><category term='JPA'/><category term='design patterns'/><category term='javascript'/><category term='funny'/><category term='java'/><category term='personal'/><category term='InputStream'/><category term='whs'/><category term='REST'/><category term='ajax'/><category term='Web Services'/><category term='maven'/><category term='OpenEJB'/><category term='military'/><category term='netgear'/><category term='cute'/><category term='EJB'/><category term='Tomcat'/><category term='SCEA'/><category term='JNDI'/><category term='css'/><category term='scrum'/><category term='agile'/><category term='JCA'/><category term='backlog'/><category term='gigabit'/><category term='XTemplate'/><category term='persistence'/><category term='html'/><category term='jboss'/><category term='iBatis'/><category term='performance'/><category term='career'/><category term='JMS'/><category term='Spring'/><category term='J2EE'/><category term='sprints'/><category term='Jersey'/><category term='extjs'/><category term='servlet filter'/><title type='text'>my kingdom for a smile :-)</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-3211023796130275518</id><published>2012-01-07T20:44:00.000-06:00</published><updated>2012-01-07T20:44:02.883-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>The Agile Machine</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-nLdJOgfg8a8/TwkBqdi22KI/AAAAAAAAABo/INZswEQ9WGs/s1600/TheAgileMachine.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="472" src="http://4.bp.blogspot.com/-nLdJOgfg8a8/TwkBqdi22KI/AAAAAAAAABo/INZswEQ9WGs/s640/TheAgileMachine.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-3211023796130275518?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/3211023796130275518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=3211023796130275518' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/3211023796130275518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/3211023796130275518'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2012/01/agile-machine.html' title='The Agile Machine'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-nLdJOgfg8a8/TwkBqdi22KI/AAAAAAAAABo/INZswEQ9WGs/s72-c/TheAgileMachine.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-6827662438573276609</id><published>2011-04-05T23:02:00.006-05:00</published><updated>2011-04-06T09:11:27.060-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='whs'/><category scheme='http://www.blogger.com/atom/ns#' term='netgear'/><category scheme='http://www.blogger.com/atom/ns#' term='gigabit'/><title type='text'>Network tune-up for Windows Home Server (WHS) performance</title><content type='html'>&lt;i&gt;It's all about the cables&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Although I've been very pleased with my Windows Home Server, one area that has been a little disappointing is performance - until today that is.&lt;br /&gt;&lt;br /&gt;Recently I tried restoring a 120 GB backup onto a new hard drive.&amp;nbsp; Unfortunately, WHS reported that it was going to take upwards of 22 hours - yes HOURS - to complete.&amp;nbsp; I figured there was something wrong with that so I cancelled and proceeded to investigate.&amp;nbsp; I found some interesting things on Google that said do this or that but none of those suggestions seemed to work for me.&lt;br /&gt;&lt;br /&gt;Since my router was only capable of 100 Mbps and since my WHS box has a Gigabit LAN port I figured I would try upgrading my router.&amp;nbsp; After setting up my new &lt;a href="http://www.amazon.com/gp/product/B002HWRJY4"&gt;Netgear gigabit router&lt;/a&gt; I noticed that my WHS box was only connecting to the network at 10 Mbps.&amp;nbsp; That would certainly explain where the 22 hours to restore a 120 GB backup was coming from - 120 gigabytes at 10 megabits per second would take about that long to transfer across the network.&amp;nbsp; But I had a gigabit router and a gigabit LAN port - why was the WHS box only connecting at 10 Mbps?&lt;br /&gt;&lt;br /&gt;Well, it turns out, it was the cable.&amp;nbsp; My network, which I built several years ago, was wired with CAT5 cable.&amp;nbsp; Apparently cabling has come a long way since then and I was unaware.&amp;nbsp; But, when I swapped out the CAT5 cable from my router to my WHS box with the shielded CAT6 cable that came with the new router my WHS box was now connecting to the network at the 1 Gbps speed.&amp;nbsp; Yeah!&amp;nbsp; And, the restore of that 120 GB backup now took less than 30 minutes to complete.&amp;nbsp; Wow, what a difference.&lt;br /&gt;&lt;br /&gt;So, if you're having trouble with performance from your WHS check your LAN cables.&lt;br /&gt;&lt;br /&gt;I would also like to mention that the Netgear N600 router I bought has an awesome feature that I was unaware of when I bought it as it doesn't seem to be described in the product literature.&amp;nbsp; There is a button on the front where you can turn off the wireless portion of the router - very cool since all of my connections are currently wired connections.&lt;br /&gt;&lt;br /&gt;If you want to see how to restore a backup to new/different hardware see my post on&amp;nbsp;&lt;a href="http://usna86-techbits.blogspot.com/2011/03/windows-home-server-to-rescue.html"&gt;'Windows Home Server to the rescue'&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-6827662438573276609?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/6827662438573276609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=6827662438573276609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/6827662438573276609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/6827662438573276609'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2011/04/network-tune-up-for-windows-home-server.html' title='Network tune-up for Windows Home Server (WHS) performance'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-6055706911719178945</id><published>2011-03-06T21:28:00.007-06:00</published><updated>2011-04-06T09:14:38.661-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='sprints'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Agile Thoughts : Sprint Length</title><content type='html'>&lt;i&gt;team maturity and work definition are key factors&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;There are many factors that can/should influence sprint length, such as delivery schedules, resource availability, customer requirements, need for feedback, etc., but two often overlooked and perhaps most important factors are team maturity and how well the requirements/work are defined.&lt;br /&gt;&lt;br /&gt;If I were putting together a new team or implementing scrum/agile processes for the first time with an existing team I would lean towards shorter sprints, perhaps on the order of a week or two.&amp;nbsp; I believe this would allow a team to mature much more quickly as there are more opportunities to exercise the full sprint process and more opportunities to use feedback to more rapidly move toward becoming a high-performing team.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-hGPLbBnrbSI/TXRJM-JWDnI/AAAAAAAAABA/LtKEgI367IQ/s1600/sprint-length.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-7yhwBC5LxtI/TXRcACZQYyI/AAAAAAAAABE/T5BlLF2G6yQ/s1600/sprint-length.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="250" src="https://lh5.googleusercontent.com/-7yhwBC5LxtI/TXRcACZQYyI/AAAAAAAAABE/T5BlLF2G6yQ/s320/sprint-length.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Another key factor affecting sprint length is how well the work to be performed is defined and understood.&amp;nbsp; This includes both the business and technical aspects.&amp;nbsp; If the requirements are vague or unclear or if the technologies to be used are new or not widely known by the team then it might be a good idea to shorten the sprints to flush out more detail and get more rapid feedback from the customer on whether the team is on or off course.&amp;nbsp; Likewise, shorter, more focused sprints might help the team determine whether technology or architecture choices were appropriate and correct as well as helping to minimize risk or wasted effort.&lt;br /&gt;&lt;br /&gt;As you can see from the above chart, mature, high-performing teams with poorly defined requirements and new, immature teams with outstanding requirements are in virtually the same place - they both need shorter sprints, for different reasons of course, but shorter sprints none-the-less.&lt;br /&gt;&lt;br /&gt;See also: &amp;nbsp;&lt;a href="http://usna86-techbits.blogspot.com/2011/02/agile-thoughts-backlog-preparation.html"&gt;agile thoughts : backlog preparation&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-6055706911719178945?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/6055706911719178945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=6055706911719178945' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/6055706911719178945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/6055706911719178945'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2011/03/agile-thoughts-sprint-length.html' title='Agile Thoughts : Sprint Length'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-7yhwBC5LxtI/TXRcACZQYyI/AAAAAAAAABE/T5BlLF2G6yQ/s72-c/sprint-length.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-4167812723269167350</id><published>2011-03-05T22:40:00.008-06:00</published><updated>2011-04-06T09:13:11.792-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='whs'/><title type='text'>Windows Home Server to the rescue</title><content type='html'>&lt;i&gt;restoring a PC to new hardware&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Several months ago I built a Windows Home Server box partly to back up the family's PCs - one of which is an aging Windows XP machine that I built seven or eight years ago.&amp;nbsp; As luck would have it the last remaining SCSI hard drive in that old XP box started to fail last week, corrupting the OS and causing the machine to fail to boot.&lt;br /&gt;&lt;br /&gt;Since I had this new WHS box I figured I had nothing to lose so I decided to try my first restore.&amp;nbsp; It was dirt simple and it worked, for a day or two, until the OS was corrupted again.&amp;nbsp; I ended up swapping out my SCSI controller for a SATA controller, added a new SATA hard drive and performed a restore from WHS onto my new hardware.&amp;nbsp; It looked like it was going to work just fine - until the first reboot after the restore.&amp;nbsp; As most of you probably guessed, the backup image did not have the drivers for my new PCI SATA card and thus Windows failed to boot.&lt;br /&gt;&lt;br /&gt;I tried numerous things and finally discovered the recipe that would let me successfully restore the backup for my old hardware onto my new hardware:&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp; Restore the PC from WHS onto the new hardware&lt;br /&gt;&lt;br /&gt;2.&amp;nbsp; Boot from the Windows XP CD, pressing F6 at the right time to install the SATA drivers for the new hardware&lt;br /&gt;&lt;br /&gt;3.&amp;nbsp; Choose to install Windows XP (do not enter the XP recovery console)&lt;br /&gt;&lt;br /&gt;4.&amp;nbsp; When prompted, choose to 'Repair' the current installation&lt;br /&gt;&lt;br /&gt;Windows will appear to be performing a fresh install (and to some extent it is), but all of your programs and data will be left intact.&amp;nbsp; If you goof up along the way and accidentally do a full reinstall instead of a repair don't fret, simply go back to step 1 and start over by restoring the PC from WHS again.&lt;br /&gt;&lt;br /&gt;5.&amp;nbsp; Once the repair is complete reboot into the OS and run Windows Update to recover all the patches and updates that were lost by the repair (in my case Windows was set back to SP2 from SP3 since SP2 is the service pack level of my installation CD)&lt;br /&gt;&lt;br /&gt;6.&amp;nbsp; I would advise performing a manual backup to WHS at this point&lt;br /&gt;&lt;br /&gt;In hindsight it seems like a pretty simple process, and it is, but it did take some trial and error to figure out.&amp;nbsp; Needless to say I am very pleased with Windows Home Server and my decision to add a WHS box to my home network.&lt;br /&gt;&lt;br /&gt;See my post on&amp;nbsp;&lt;a href="http://usna86-techbits.blogspot.com/2011/04/network-tune-up-for-windows-home-server.html"&gt;'network tune-up for WHS'&lt;/a&gt; to find out how to make the above process much faster and smoother.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-4167812723269167350?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/4167812723269167350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=4167812723269167350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/4167812723269167350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/4167812723269167350'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2011/03/windows-home-server-to-rescue.html' title='Windows Home Server to the rescue'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-2159626229283133054</id><published>2011-02-26T11:51:00.005-06:00</published><updated>2011-04-06T09:15:40.389-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='backlog'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Agile Thoughts : Backlog Preparation</title><content type='html'>&lt;i&gt;Two hours can make a huge difference.&lt;/i&gt; &lt;br /&gt;&lt;br /&gt;I've been working in an agile development shop using the Scrum methodology for over four years now and have a few thoughts on what works well, what doesn't work so well and some thoughts on how to improve the process. The first topic I would like to discuss is backlog preparation and where that fits/should fit into the sprint schedule.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;For those of you unfamiliar with Scrum/agile a 'sprint' is a short iteration, somewhere in the 2 to 4 week range (+- a week) that consists of work selection, planning, design, implementation/development, testing, presentation to the client and a team retrospective - usually fairly rigid and in that order.&lt;br /&gt;&lt;br /&gt;The team works from the 'backlog' - a list of features or capabilities (called stories) that need to be researched, developed or integrated into the software.&amp;nbsp; This list is created and prioritized by the 'solution owner' in cooperation with the client/customer.&amp;nbsp; But since we are talking about agile, this list can be changed frequently based on customer feedback and changing priorities.&lt;br /&gt;&lt;br /&gt;Usually, these stories start out as nothing more than simple one line statements or short paragraphs of the form 'as a user I need to be able to do X.'&amp;nbsp; At some point in this agile/scrum process these stories need to be flushed out in enough detail so that (a) the story can become actionable by the team and (b) the amount and type of effort required to complete the story can be estimated with some degree of accuracy.&amp;nbsp; In my experience this usually occurs at backlog selection (the kickoff meeting for the new sprint where work is selected).&amp;nbsp; This usually, without exception, leads to meetings that are long, frustrating, and less productive than they need to be.&lt;br /&gt;&lt;br /&gt;Agile/scrum teams usually try to combat this by holding 'backlog grooming' meetings throughout the sprint to flush out some of the details of these future stories and make some preliminary design decisions.&amp;nbsp; This, however, has several shortcomings that I have seen time and again:&amp;nbsp; (1) it interrupts the flow/focus of the current sprint, (2) team members are distracted by the current sprint's work and don't fully focus/participate in the thought process for developing future stories and (3) the team many times invests time in preparing stories that they will never actually work or that change dramatically by the time they do.&lt;br /&gt;&lt;br /&gt;I use to work in manufacturing and one of the key concepts was 'just in time' - you bring the materials, machinery, and manpower together at just the right time so that inventory isn't building up or so that people and machinery aren't sitting idly by.&amp;nbsp; It's a great concept and aptly applies to software development and agile processes.&amp;nbsp; In this context &lt;b&gt;I believe there is one, and only one, place for backlog preparation and that is sometime between when the team has completed its work on the current sprint and prior to the next backlog selection meeting&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;The purpose of these backlog preparation meetings is for the solution owner to present the team with the stories that are to be worked in the coming sprint, for the team to ask some initial questions, and for the team to then go off and do some initial brainstorming.&amp;nbsp; The result should be stories that have a clearer 'definition of done' with some initial high-level tasking from which reasonable estimates of effort can be made.&amp;nbsp; This meeting should be short, perhaps no more than an hour with the solution owner present and perhaps another hour for the team to brainstorm and come up with an initial tasking, estimates, additional questions for the solution owner and, if need be, alternative implementations/paths forward.&lt;br /&gt;&lt;br /&gt;The benefits to this approach are that the team is constantly focused on the work they are to be performing at any given point in time, resources are more efficiently and effectively utilized, the actual backlog selection meeting is more productive, estimates are more accurate, teams are happier and more engaged, and sprints get started off on the right foot and have a higher probability of success.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Two hours spent in backlog preparation - &lt;u&gt;at the right time&lt;/u&gt; - can make a huge difference.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;See also: &amp;nbsp;&lt;a href="http://usna86-techbits.blogspot.com/2011/03/agile-thoughts-sprint-length.html"&gt;agile thoughts : sprint length&lt;/a&gt;&lt;i&gt; &lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-2159626229283133054?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/2159626229283133054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=2159626229283133054' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2159626229283133054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2159626229283133054'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2011/02/agile-thoughts-backlog-preparation.html' title='Agile Thoughts : Backlog Preparation'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-7449675157496199123</id><published>2011-02-26T10:44:00.006-06:00</published><updated>2011-04-06T09:17:45.609-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XTemplate'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='extjs'/><title type='text'>Standalone ExtJS XTemplate classes</title><content type='html'>ExtJS XTemplates are awesome!&amp;nbsp; They provide an easy way to combine custom presentation markup with simple or complex data on the client.&amp;nbsp; Sometimes that markup needs to be more dynamic than simply plugging the data straight into the template.&amp;nbsp; But, the Ext folks already thought of that and allow you to add methods to your XTemplate definition.&amp;nbsp; This is great, but can lead to gangly template definitions with scoping issues.&lt;br /&gt;&lt;br /&gt;In a recent situation at work we had a 400+ line template definition - only about 20 lines of that was the presentation template, the rest being methods to manipulate/interpret the data (beyond the conversions we had already applied to the data).&amp;nbsp; In our situation we needed to interpret the same piece of data in different ways depending on where we were in the template (context) as well as the type of view the user wanted to see.&amp;nbsp; For those of you familiar with XTemplates you will realize that the 400+ lines of template definition are in the constructor call to the XTemplate class - basically a huge constructor parameter.&amp;nbsp; Obviously it was time for some refactoring.&lt;br /&gt;&lt;br /&gt;I have written numerous custom components in javascript, but never one extending the XTemplate, so I decided to try making our template a custom class that extended the ExtJS XTemplate.&amp;nbsp; Turns out it worked beautifully with very little modification to the original template (other than relocating it to its own file and doing some minor restructuring).&amp;nbsp; The template markup became part of the call to the super constructor in my new class' constructor and the methods became first class citizens of my new class (which ext accomplishes behind the scenes anyway in the original implementation).&lt;br /&gt;&lt;br /&gt;As a result the client code using the template only needed a single line to create an instance of the template, the template is now reusable if needed, the code is cleaner all around, and the scope/context inside the template methods is more natural and easier to understand.&lt;br /&gt;&lt;br /&gt;See also: &amp;nbsp;&lt;a href="http://usna86-techbits.blogspot.com/2011/01/injecting-extjs-components-via-html.html"&gt;injecting extjs components via html templates&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-7449675157496199123?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/7449675157496199123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=7449675157496199123' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/7449675157496199123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/7449675157496199123'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2011/02/standalone-extjs-xtemplate-classes.html' title='Standalone ExtJS XTemplate classes'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-2462870510284569847</id><published>2011-01-17T18:47:00.003-06:00</published><updated>2011-04-06T09:18:49.274-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XTemplate'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='extjs'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Injecting ExtJS components via an html template</title><content type='html'>Use Ajax to load an html page as a template for ExtJS and then plug ExtJS components into it.&lt;br /&gt;&lt;br /&gt;Sometimes a web page layout may be too complicated or time-consuming to develop purely in ExtJS or perhaps you want to convert an existing html page to use ExtJS components.&amp;nbsp; In either case there is a simple and straightforward way to inject ExtJS components into a complex html page.&lt;br /&gt;&lt;br /&gt;There are only a few simple steps needed to accomplish this:&amp;nbsp; &lt;br /&gt;&lt;ul&gt;&lt;li&gt;create the html&lt;/li&gt;&amp;nbsp;&lt;li&gt;fetch the html&lt;/li&gt;&amp;nbsp;&lt;li&gt;load the html&lt;/li&gt;&amp;nbsp;&lt;li&gt;plug in the ExtJS components&lt;/li&gt;&lt;/ul&gt;Here is a snippet from myPage.html.&amp;nbsp; Notice the {idBase} included as part of the id.&amp;nbsp; That is a template param that will be replaced when the ExtJS XTemplate is processed.&amp;nbsp; The purpose of {idBase} is to help make sure that each div section has a unique ID and is not really germain to this article.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;table&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td style="padding-right: 5px;"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div id="&lt;b&gt;myButton&lt;/b&gt;_{idBase}"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br /&gt;&lt;br /&gt;The following methods are from myScript.js.&lt;br /&gt;&lt;br /&gt;This method loads the html using an Ajax request:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initStructure : function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ext.Ajax.request({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; url : 'myPage.html',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; disableCaching : false,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; method : 'GET',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; success : this.onStructureLoaded.createDelegate(this)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } // initStructure()&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;This success handler puts the html text into an ExtJS XTemplate and then loads that into the body of this component (an ExtJS panel or window):&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; onStructureLoaded : function(response, options) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var template = new Ext.XTemplate(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; response.responseText&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.body.update(template.apply({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; idBase : this.id&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.initMyButton();&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } // onStructureLoaded()&lt;br /&gt;&lt;br /&gt;Once the html has been loaded into the DOM we can start plugging our ExtJS components into it:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; initMyButton : function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new Ext.Button({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; applyTo : this.getCustomId('&lt;b&gt;myButton&lt;/b&gt;'),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; text : 'My Button',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; handler : this.onMyButtonClick.createDelegate(this)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } // initMyButton()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; getCustomId : function(name) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return String.format('{0}_{1}', name, this.id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } // getCustomId()&lt;br /&gt;&lt;br /&gt;See also: &amp;nbsp;&lt;a href="http://usna86-techbits.blogspot.com/2011/02/standalone-extjs-xtemplate-classes.html"&gt;standalone extjs template classes&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-2462870510284569847?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/2462870510284569847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=2462870510284569847' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2462870510284569847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2462870510284569847'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2011/01/injecting-extjs-components-via-html.html' title='Injecting ExtJS components via an html template'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-5439894656018199076</id><published>2011-01-12T21:23:00.000-06:00</published><updated>2011-01-12T21:24:33.686-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring-loading and injecting external properties into beans</title><content type='html'>Let's say you have a Spring managed bean that contains some properties that you would like to externalize from your application, say perhaps in a JBoss 'conf' folder properties file.&amp;nbsp; Apparently you can do this via annotations in Spring 3, but it's also fairly straightforward in Spring 2.5:&lt;br /&gt;&lt;br /&gt;From the context.xml file:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;bean id="propertyConfigurer"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name="location" value="classpath:my_app.properties"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name="placeholderPrefix" value="$prop{"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;bean id="someBeanWithProps" class="my.class.with.Props"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name="myPropA" value="$prop{prop.file.entry.prop.A}"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name="myPropB" value="$prop{prop.file.entry.prop.B}"/&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/bean&amp;gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-5439894656018199076?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/5439894656018199076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=5439894656018199076' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5439894656018199076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5439894656018199076'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2011/01/spring-loading-and-injecting-external.html' title='Spring-loading and injecting external properties into beans'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-5079538817320326243</id><published>2011-01-12T20:51:00.000-06:00</published><updated>2011-01-12T21:12:08.142-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JNDI'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>JBoss, JNDI and java:comp/env</title><content type='html'>On startup JBoss will process any xyz-service.xml files it finds in the deploy folder before it processes any war or ear files, etc.&amp;nbsp; One thing this could be useful for is to preload configuration values into JNDI, thus making them available to web applications when they start up.&amp;nbsp; It may sound simple but it consists of a non-obvious four step process:&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp; Create a JNDIBindingServiceMgr mbean in the xzy-service.xml file.&lt;br /&gt;&lt;br /&gt;2.&amp;nbsp; In the WEB-INF/jboss-web.xml file map a resource-env-ref entry over to a JNDI value bound in step 1.&lt;br /&gt;&lt;br /&gt;3.&amp;nbsp; In the WEB-INF/web.xml file create a resource-env-ref entry for each JNDI bound value.&lt;br /&gt;&lt;br /&gt;4.&amp;nbsp; Access the JNDI value from somewhere, such as a servlet filter, using 'java:comp/env'&lt;br /&gt;&lt;br /&gt;First, the xyz-service.xml file:&lt;br /&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE server PUBLIC "-//JBoss//DTD MBean Service 4.0//EN"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "http://www.jboss.org/j2ee/dtd/jboss-service_4_0.dtd"&amp;gt;&lt;br /&gt;&amp;lt;server&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;mbean code="org.jboss.naming.JNDIBindingServiceMgr"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name="netcds.cas.client:service=JNDIBindingServiceMgr"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;attribute name="BindingsConfig" serialDataType="jbxb"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;jndi:bindings&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:jndi="urn:jboss:jndi-binding-service:1.0"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xs:schemaLocation="urn:jboss:jndi-binding-service:1.0 resource:jndi-binding-service_1_0.xsd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;jndi:binding name="my/jndi/property"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;jndi:value type="java.lang.Boolean"&amp;gt;false&amp;lt;/jndi:value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/jndi:binding&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/jndi:bindings&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/attribute&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;depends&amp;gt;jboss:service=Naming&amp;lt;/depends&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/mbean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/server&amp;gt;&lt;br /&gt;&lt;br /&gt;Next, the resource-env-ref entry in the jboss-web.xml file:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;resource-env-ref&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;resource-env-ref-name&amp;gt;my/jndi/property&amp;lt;/resource-env-ref-name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;jndi-name&amp;gt;my/jndi/property&amp;lt;/jndi-name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/resource-env-ref&amp;gt;&lt;br /&gt;&lt;br /&gt;And the associated web.xml entry:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;resource-env-ref&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;resource-env-ref-name&amp;gt;my/jndi/property&amp;lt;/resource-env-ref-name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;resource-env-ref-type&amp;gt;java.lang.Boolean&amp;lt;/resource-env-ref-type&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/resource-env-ref&amp;gt;&lt;br /&gt;&lt;br /&gt;Finally, accessing the JNDI value from a servlet filter:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean result = false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InitialContext context = new InitialContext();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = (Boolean)context.lookup("java:comp/env/my/jndi/property");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (final NamingException e) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // log and/or sys out&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-5079538817320326243?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/5079538817320326243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=5079538817320326243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5079538817320326243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5079538817320326243'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2011/01/jboss-jndi-and-javacompenv.html' title='JBoss, JNDI and java:comp/env'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-2073899618034362680</id><published>2010-12-16T18:04:00.000-06:00</published><updated>2010-12-16T18:21:55.311-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='servlet filter'/><title type='text'>No dynamic filters in servlet spec 2.4 you say?</title><content type='html'>I had a requirement recently to be able to dynamically control CAS security filters in a web application (default CAS security to off for development and allow it to be turned on by external configuration post-deployment).&amp;nbsp; Unfortunately, servlet spec 2.4 does not allow one to programatically add new servlet filters (at least that's the prevailing theory).&amp;nbsp; This is a feature added/being added to the servlet 3.0 API.&lt;br /&gt;&lt;br /&gt;My friend Google said there were a number of others who wanted to do the same thing but they were being pointed to servlet 3.0.&amp;nbsp; Unfortunately, servlet 3.0 and J2EE 6 were not an option for me, so it was looking like a tough nut to crack.&lt;br /&gt;&lt;br /&gt;Then it struck me, what if I created a generic, conditional servlet filter that took the name of the class of the real filter as an init param?&amp;nbsp; And, what if I passed in the condition that was to be evaluated to determine whether or not to create and/or invoke the real filter?&amp;nbsp; Then, in the conditional filter, I could examine the condition and, as necessary, dynamically create an instance of the wrapped filter class.&lt;br /&gt;&lt;br /&gt;Turns out it worked like a charm.&amp;nbsp; Here's how.&amp;nbsp; First the filter definition in web.xml:&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;filter&gt;&lt;/filter&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter-name&amp;gt;CAS Authentication Filter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;filter-class&amp;gt;my.org.security.servlet.ConditionalFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;init-param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param-name&amp;gt;condition&amp;lt;/param-name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param-value&amp;gt;cas/enabled&amp;lt;/param-value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/init-param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;init-param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param-name&amp;gt;wrapped-class&amp;lt;/param-name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;param-value&amp;gt;org.jasig.cas.client.authentication.AuthenticationFilter&amp;lt;/param-value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/init-param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/filter&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;Next, the ConditionalFilter itself: &lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;...&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;public class ConditionalFilter implements Filter {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // instance of the actual filter being wrapped&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Filter _wrappedFilter;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // are we to ignore the wrapped filter?&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private boolean _ignore = true;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ConditionalFilter() {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } // constructor&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void init(FilterConfig filterConfig) throws ServletException {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // the 'condition' init param tells us whether or not the wrapped filter&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // is active&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ignore = !checkCondition(filterConfig.getInitParameter("condition"));&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!_ignore) {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // the wrapped filter is active so we create an instance of it&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and initialize it&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _wrappedFilter = getFilterInstance(&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filterConfig.getInitParameter("wrapped-class")&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _wrappedFilter.init(filterConfig);&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (Exception e) {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ServletException(e);&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void doFilter(ServletRequest request,&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ServletResponse response,&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FilterChain filterChain)&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throws IOException, ServletException {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!_ignore) {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // the wrapped filter is active so we let it do its work&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _wrappedFilter.doFilter(request, response, filterChain);&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // wrapped filter is inactive so simply move on to the next filter&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filterChain.doFilter(request, response);&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void destroy() {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (_ignore) {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _wrappedFilter.destroy();&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Filter getFilterInstance(String className)&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throws ClassNotFoundException, InvalidClassException,&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InvocationTargetException, IllegalAccessException,&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InstantiationException, NoSuchMethodException {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // try to create an instance of the wrapped filter with the given class name&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Class filterClass = Class.forName(className);&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; java.lang.reflect.Constructor constructor = filterClass.getConstructor();&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object filter = constructor.newInstance();&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!(filter instanceof Filter)) {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new InvalidClassException(&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String.format("'%s' is not an instance of Filter", className)&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (Filter)filter;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } // getFilterInstance()&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * looks up the configured 'condition' via JNDI to determine whether or not the&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * wrapped filter is active&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private boolean checkCondition(String condition) {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean result = false;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InitialContext context = new InitialContext();&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String path = String.format("java:comp/env/%s", condition);&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result =(Boolean)context.lookup(path);&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (final NamingException e) {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println("ConditionFilter:checkCondition() - unable to load condition from JNDI");&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } // checkCondition()&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;} // class ConditionalFilter&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-2073899618034362680?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/2073899618034362680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=2073899618034362680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2073899618034362680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2073899618034362680'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2010/12/no-dynamic-filters-in-servlet-spec-24.html' title='No dynamic filters in servlet spec 2.4 you say?'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-6671094144848462840</id><published>2010-04-02T15:36:00.000-05:00</published><updated>2010-04-03T00:19:03.129-05:00</updated><title type='text'>One Thumb Up for Pair Programming</title><content type='html'>Pair programming is one of the characteristics of extreme programming and is, frankly, something I have not been a particularly strong advocate of.  The idea of two developers sitting side-by-side, sharing one keyboard and working the exact same problem seems terribly inneficient to me.  However, there are two reasons why, for short periods of time, that it would be beneficial to engage in pair programming.&lt;br /&gt;&lt;br /&gt;The first one would be for test driven development.  For a particular functional area under development one developer would write the unit/integration tests and one would write the code.  To me, this would be the most efficient use of pair programming.&lt;br /&gt;&lt;br /&gt;The second reason why I think it would be beneficial to perform short stints of pair programming would be to gain insight into the work practices, processes and procedures of one's teammates.  For me personally, I could see how my teammates work and glean some ideas on how I could be more productive and efficient.  What tools do they use?  How do they use them?  Do they have any shortcuts or time-savers?  Likewise, it would be an opportunity for me to help my teammates improve their efficiency by offering suggestions based on the things that I do that help me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-6671094144848462840?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/6671094144848462840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=6671094144848462840' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/6671094144848462840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/6671094144848462840'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2010/04/pair-programming.html' title='One Thumb Up for Pair Programming'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-1202755228939740415</id><published>2010-03-09T11:16:00.000-06:00</published><updated>2010-04-02T15:39:25.429-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>jboss plugin for auto-deploying artifact during build</title><content type='html'>This is VERY handy for automatically deploying your artifact/war after a maven build is completed.  Simply add the mvn goal &lt;b&gt;jboss:hard-deploy&lt;/b&gt; to your maven command.&lt;br /&gt;&lt;pre&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;jboss-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;1.4&amp;lt;/version&amp;gt;&lt;br /&gt;   &amp;lt;configuration&amp;gt;&lt;br /&gt;      &amp;lt;jbossHome&amp;gt;${jboss.home}&amp;lt;/jbossHome&amp;gt;&lt;br /&gt;      &amp;lt;serverName&amp;gt;default&amp;lt;/serverName&amp;gt;&lt;br /&gt;      &amp;lt;fileName&amp;gt;target/my-app.war&amp;lt;/fileName&amp;gt;&lt;br /&gt;   &amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-1202755228939740415?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/1202755228939740415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=1202755228939740415' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/1202755228939740415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/1202755228939740415'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2010/03/jboss-plugin-for-auto-deploying.html' title='jboss plugin for auto-deploying artifact during build'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-4218935994317554687</id><published>2010-03-06T10:45:00.000-06:00</published><updated>2010-03-06T11:11:10.911-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='Jersey'/><category scheme='http://www.blogger.com/atom/ns#' term='extjs'/><title type='text'>Tunneling PUT and DELETE from ExtJS to Jersey ReST</title><content type='html'>Here is how you can invoke AJAX POSTs in ExtJS that map to PUT and/or DELETE methods in your Jersey ReST services.&lt;br /&gt;&lt;br /&gt;The first step is to configure Jersey to allow this: &lt;br /&gt;&lt;pre&gt;&amp;lt;init-param&amp;gt;&lt;br /&gt;    &amp;lt;param-name&amp;gt;com.sun.jersey.spi.container.ContainerRequestFilters&amp;lt;/param-name&amp;gt;&lt;br /&gt;    &amp;lt;param-value&amp;gt;com.sun.jersey.api.container.filter.PostReplaceFilter&amp;lt;/param-value&amp;gt;&lt;br /&gt;&amp;lt;/init-param&amp;gt;&lt;/pre&gt;The next step is to issue the AJAX request (in this case we're going to issue a POST but tell Jersey to invoke the PUT mapped method instead):&lt;br /&gt;&lt;pre&gt;Ext.Ajax.request({&lt;/pre&gt;&lt;div style="color:red;margin-top:-1em;"&gt;&lt;pre&gt;    headers : {&lt;br /&gt;        'X-HTTP-Method-Override' : 'PUT'&lt;br /&gt;    },&lt;br /&gt;    method: 'POST',&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="margin-top:-1em;"&gt;&lt;pre&gt;    url: '/my-api/some-service',&lt;br /&gt;    params: {&lt;br /&gt;        name : someObj.name,&lt;br /&gt;        date : someObj.date,&lt;br /&gt;        amount : someObj.amount&lt;br /&gt;    },&lt;br /&gt;    success: this.onSaveSuccess.createDelegate(this),&lt;br /&gt;    failure: this.onSaveFailure.createDelegate(this)&lt;br /&gt;});&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-4218935994317554687?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/4218935994317554687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=4218935994317554687' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/4218935994317554687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/4218935994317554687'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2010/03/tunneling-put-and-delete-from-extjs-to.html' title='Tunneling PUT and DELETE from ExtJS to Jersey ReST'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-2800801302218897572</id><published>2010-03-05T15:06:00.000-06:00</published><updated>2010-03-06T10:35:51.590-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='extjs'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>CSS for flowing boxes in a DataView</title><content type='html'>Here is some CSS that can be used to flow/float boxes inside an ExtJS DataView:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;pre&gt;.dataViewNode {&lt;br /&gt;   width: 10em;&lt;br /&gt;   float: left;&lt;br /&gt;   height: auto;&lt;br /&gt;   overflow: hidden;&lt;br /&gt;   position: relative;&lt;br /&gt;   margin: 4px;&lt;br /&gt;   z-index: 5;&lt;br /&gt;   text-align: center;&lt;br /&gt;   padding: 2px 0 0 0;&lt;br /&gt;   font-size: 0.8em;&lt;br /&gt;}  &lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-2800801302218897572?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/2800801302218897572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=2800801302218897572' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2800801302218897572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2800801302218897572'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2010/03/css-for-flowing-boxes-in-dataview.html' title='CSS for flowing boxes in a DataView'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-3263944392570297260</id><published>2010-01-28T15:47:00.000-06:00</published><updated>2010-01-28T15:47:43.948-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='InputStream'/><title type='text'>InputStream from URL BufferedImage</title><content type='html'>Here is how you can make an InputStream for a BufferedImage:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;    URL url = new URL("http://www.google.com/intl/en_ALL/images/logo.gif");&lt;br /&gt;    BufferedImage image = ImageIO.read(url);&lt;br /&gt;    ByteArrayOutputStream os = new ByteArrayOutputStream();&lt;br /&gt;    ImageIO.write(image, "gif", os);&lt;br /&gt;    InputStream is = new ByteArrayInputStream(os.toByteArray());&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-3263944392570297260?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/3263944392570297260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=3263944392570297260' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/3263944392570297260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/3263944392570297260'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2010/01/inputstream-from-url-bufferedimage.html' title='InputStream from URL BufferedImage'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-1099732838727574773</id><published>2009-12-20T15:40:00.000-06:00</published><updated>2009-12-20T16:26:02.038-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JNDI'/><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenEJB'/><category scheme='http://www.blogger.com/atom/ns#' term='Jersey'/><title type='text'>Was I defeating bean pooling in OpenEJB?</title><content type='html'>As I previously reported I had to use JNDI to obtain a reference to my stateless session bean from my Jersey Rest service.&lt;br /&gt;&lt;br /&gt;In so doing I created a helper class that would, among other things, cache the JNDI and EJB references I needed.&lt;br /&gt;&lt;br /&gt;That got me to wondering - since I was using the same EJB reference over and over was I somehow defeating the stateless session bean pooling that OpenEJB was surely providing me?&lt;br /&gt;&lt;br /&gt;The only documentation I could find on this hinted that pooling worked via the bean method invocations and not the bean reference itself.  But, I wanted to see it with my own eyes.  I did notice that my JNDI lookup was returning a proxy object and not my bean implementaion, so this provided me some hope that I was not defeating pooling.&lt;br /&gt;&lt;br /&gt;My first test was to invoke my EJB 10 times via the same reference and, from inside my EJB implementation identify the bean instance that was invoked.  Well, the 10 invocations went to the same instance - no pooling so far.&lt;br /&gt;&lt;br /&gt;But, my test was not very realistic so I modified it to invoke my EJB 10 times via the same reference but from 10 separate threads.  This time the 10 invocations were handled by 10 different instances of my bean implementation.  Whew - proof that I had not defeated pooling by caching and reusing the bean reference I was retrieving from JNDI.&lt;br /&gt;&lt;br /&gt;Out of curiosity I increased my invocations to 100 and this time only 9 unique instances of my stateless session bean were used to handle these 100 requests.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-1099732838727574773?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/1099732838727574773/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=1099732838727574773' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/1099732838727574773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/1099732838727574773'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2009/12/was-i-defeating-bean-pooling-in-openejb.html' title='Was I defeating bean pooling in OpenEJB?'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-6616698231651068575</id><published>2009-12-20T15:00:00.000-06:00</published><updated>2009-12-20T15:17:00.579-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenEJB'/><category scheme='http://www.blogger.com/atom/ns#' term='Jersey'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><title type='text'>Tomcat, OpenEJB and Jersey, oh my</title><content type='html'>I was recently investigating putting EJBs behind Restful web services.  &lt;br /&gt;&lt;br /&gt;I did get it working without too much trouble using Jersey and JBoss AS 5.1, but I had to deploy my web app in exploded directory form and not as a war.  No matter what I tried I could not get Jersey to find the rest service classes when I deployed my app as a war.  This was contrary to my experiences with JBoss 4 and is probably due to the new virtual file system architecture in JBoss 5.&lt;br /&gt;&lt;br /&gt;This prompted me to take a look around and see what else is out there.  I stumbled upon OpenEJB and thought I would give that a shot inside Tomcat 6.&lt;br /&gt;&lt;br /&gt;It was pretty simple getting Tomcat going with Jersey and within a few minutes I had my web service running inside standalone tomcat (without the EJB usage, of course).&lt;br /&gt;&lt;br /&gt;However, when I dropped the OpenEJB war file into Tomcat things fell apart and my app would no longer deploy due to an apparent class loader issue which seemed to be introduced by OpenEJB.  I tried a lot of different things but couldn't get past the class loader problem.  I even went as far as to download and debug into the OpenEJB source code but I quickly found myself in compiled 3rd party code.  &lt;br /&gt;&lt;br /&gt;Here is the error I kept getting: &lt;i&gt;&lt;b&gt;Could not fully load class: com.sun.jersey.spi.container.servlet.ServletContainer due to: javax/ws/rs/core/Application in classLoader: org.apache.openejb.core.TempClassLoader&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I finally decided to simply place the Jersey jars (asm.jar, jersey-core.jar, jersey-server.jar, and jsr311-api.jar) into the Tomcat lib folder and that did the trick.  I also set the Jersey dependency to 'provided' in the maven pom for my webapp.&lt;br /&gt;&lt;pre&gt;    &amp;lt;dependency&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;com.sun.jersey&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;jersey-server&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;1.1.4.1&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;&lt;br /&gt;    &amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/pre&gt;Also, I was hoping the @EJB annotation in my rest service class would inject my stateless bean reference, but it did not - I had to use JNDI.  By default, OpenEJB uses the following scheme (you can configure) for naming your beans in JNDI: implementation class name + either 'Local' or 'Remote'.&lt;br /&gt;&lt;br /&gt;For example, say you have an EJB class named AccountBeanImpl and it implements interfaces AccountBeanLocal and AccountBeanRemote.  The corresponding JNDI names for the account bean would be AccountBeanImplLocal and AccountBeanImplRemote.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-6616698231651068575?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/6616698231651068575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=6616698231651068575' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/6616698231651068575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/6616698231651068575'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2009/12/tomcat-openejb-and-jersey-oh-my.html' title='Tomcat, OpenEJB and Jersey, oh my'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-2277415591944803848</id><published>2009-10-22T23:11:00.000-05:00</published><updated>2009-10-22T23:21:39.984-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Services'/><category scheme='http://www.blogger.com/atom/ns#' term='J2EE'/><category scheme='http://www.blogger.com/atom/ns#' term='SCEA'/><category scheme='http://www.blogger.com/atom/ns#' term='JCA'/><title type='text'>J2EE Integration and Messaging</title><content type='html'>work in progress&lt;br /&gt;&lt;style&gt;#int-messaging-table th {  font-weight: bold;  color: white;  background: seagreen;  text-align: center;}#int-messaging-table td {  text-align: center;}.characteristic-name {  font-weight: bold;  color: seagreen;  text-align: right;}&lt;/style&gt;&lt;br /&gt;&lt;div style="font-size:smaller;"&gt;&lt;table id="int-messaging-table" border="1" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Characteristic&lt;/th&gt;&lt;th&gt;Web Services&lt;/th&gt;&lt;th&gt;JMS&lt;/th&gt;&lt;th&gt;JCA&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt;&lt;tr&gt;&lt;td class='characteristic-name'&gt;sync vs. async&lt;/td&gt;&lt;td&gt;sync&lt;/td&gt;&lt;td&gt;async&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='characteristic-name'&gt;security/encryption&lt;/td&gt;&lt;td&gt;yes, WS-Security&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='characteristic-name'&gt;transactions&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='characteristic-name'&gt;reliability (guaranteed delivery)&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='characteristic-name'&gt;batch&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='characteristic-name'&gt;systems use same technology&lt;/td&gt;&lt;td&gt;java-non java&lt;/td&gt;&lt;td&gt;java-java&lt;/td&gt;&lt;td&gt;java-legacy/EIS&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-2277415591944803848?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/2277415591944803848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=2277415591944803848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2277415591944803848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/2277415591944803848'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2009/10/j2ee-integration-and-messaging.html' title='J2EE Integration and Messaging'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-5948758705405142565</id><published>2009-10-22T20:19:00.000-05:00</published><updated>2010-03-06T11:19:25.306-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SCEA'/><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><title type='text'>GoF Design Patterns</title><content type='html'>work in progress&lt;br /&gt;&lt;style&gt;#gof-patterns-table th {  font-weight: bold;  color: white;  background: seagreen;}.pattern-name {  font-weight: bold;  color: seagreen;  text-align: right;}.pattern-desc {  font-style: italic;  text-align: left;  padding-left: 5px;}.pattern-category {  background: limegreen;  font-weight: bold;  text-align: left;}.pattern-used {  text-decoration: underline;}&lt;/style&gt;&lt;br /&gt;&lt;div style="font-size:smaller;"&gt;&lt;table id="gof-patterns-table" border="1" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style="text-align:right;"&gt;Name&lt;/th&gt;&lt;th style="text-align:left; padding-left:5px;"&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt;&lt;tr&gt;&lt;td colspan=2 class='pattern-category'&gt;Creational Patterns (AbFacBuildFacProSingle)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Abstract Factory&lt;/td&gt;&lt;td class='pattern-desc'&gt;interface for creating family of related/dependent objects without specifying concrete classes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Builder&lt;/td&gt;&lt;td class='pattern-desc'&gt;separates construction from representation; same construction process can create different objects&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Factory Method&lt;/td&gt;&lt;td class='pattern-desc'&gt;interface for creating an object; lets subclasses decide which class to instantiate&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Prototype&lt;/td&gt;&lt;td class='pattern-desc'&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Singleton&lt;/td&gt;&lt;td class='pattern-desc'&gt;controls access to finite number of instances&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=2 class='pattern-category'&gt;Structural Patterns (AdBriComDecFaFlyProx)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Adapter&lt;/td&gt;&lt;td class='pattern-desc'&gt;convert one interface to one the client expects&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Bridge&lt;/td&gt;&lt;td class='pattern-desc'&gt;functional abstraction -&gt; internal implementation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Composite&lt;/td&gt;&lt;td class='pattern-desc'&gt;hierarchical tree structures with elements of varying complexity but a uniform interface&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Decorator&lt;/td&gt;&lt;td class='pattern-desc'&gt;add or remove functionality without changing external appearance&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Facade&lt;/td&gt;&lt;td class='pattern-desc'&gt;unifying interface on top of a group of interfaces/components of a subsystem&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Flyweight&lt;/td&gt;&lt;td class='pattern-desc'&gt;sharing/reusing objects&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Proxy&lt;/td&gt;&lt;td class='pattern-desc'&gt;surrogate controls access to real object&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=2 class='pattern-category'&gt;Behavioral Patterns (ChainComIntItMedMemObStateStratTempVis or C2I2M2-OSS-TV)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Chain of Responsibility&lt;/td&gt;&lt;td class='pattern-desc'&gt;message handled where it is first received or directed on to another object for handling&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Command&lt;/td&gt;&lt;td class='pattern-desc'&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Interpreter&lt;/td&gt;&lt;td class='pattern-desc'&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Iterator&lt;/td&gt;&lt;td class='pattern-desc'&gt;sequentially access items in a collection that is separate from the underlying collection&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Mediator&lt;/td&gt;&lt;td class='pattern-desc'&gt;object that manages message distribution among other objects&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Memento&lt;/td&gt;&lt;td class='pattern-desc'&gt;represents snapshot of object's state&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name pattern-used'&gt;Observer&lt;/td&gt;&lt;td class='pattern-desc'&gt;broadcast messages to interested listeners&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;State&lt;/td&gt;&lt;td class='pattern-desc'&gt;object alters behavior when internal state changes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Strategy&lt;/td&gt;&lt;td class='pattern-desc'&gt;group of classes that represent a set of possible behaviors&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Template Method&lt;/td&gt;&lt;td class='pattern-desc'&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='pattern-name'&gt;Visitor&lt;/td&gt;&lt;td class='pattern-desc'&gt;think of using the enhanced for to iterate over a list in java and perform some operation on that list&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;/div&gt;&lt;u&gt;underlined&lt;/u&gt; patterns are ones I have personally used&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-5948758705405142565?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/5948758705405142565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=5948758705405142565' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5948758705405142565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5948758705405142565'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2009/10/gof-design-patterns.html' title='GoF Design Patterns'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-7015488653886550738</id><published>2009-10-22T18:12:00.000-05:00</published><updated>2009-10-22T23:25:30.334-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iBatis'/><category scheme='http://www.blogger.com/atom/ns#' term='EJB'/><category scheme='http://www.blogger.com/atom/ns#' term='persistence'/><category scheme='http://www.blogger.com/atom/ns#' term='J2EE'/><category scheme='http://www.blogger.com/atom/ns#' term='SCEA'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>J2EE Persistence Strategies</title><content type='html'>This is a summary of the J2EE persistence strategies that a Sun Certified Enterprise Architect should be familiar with (use scrollbars at bottom to view entire table):&lt;br /&gt;&lt;style&gt;#j2ee-persistence-table th {  font-weight: bold;  color: white;  background: seagreen;  text-align: center;}#j2ee-persistence-table td {  color : black;  text-align: center;}.strategy-name {  font-weight: bold;  color: seagreen;}.non-j2ee-entry {  background: khaki;}&lt;/style&gt;&lt;br /&gt;&lt;div style="overflow:auto;font-size:smaller;"&gt;&lt;table id="j2ee-persistence-table" border="1" cellpadding="5" width="500px"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Strategy&lt;/th&gt;&lt;th&gt;Ease of Development&lt;/th&gt;&lt;th&gt;Performance&lt;/th&gt;&lt;th&gt;Scalability&lt;/th&gt;&lt;th&gt;Extensibility&lt;/th&gt;&lt;th&gt;Security&lt;/th&gt;&lt;th&gt;Strategy&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt;&lt;tr&gt;&lt;td class='strategy-name'&gt;CMP&lt;/td&gt;&lt;td&gt;relatively simple; preferred over BMP&lt;/td&gt;&lt;td&gt;container dependent&lt;/td&gt;&lt;td&gt;EJB container dependent *a&lt;/td&gt;&lt;td&gt;varies by implementation&lt;/td&gt;&lt;td&gt;EJB provided&lt;/td&gt;&lt;td class='strategy-name'&gt;CMP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='strategy-name'&gt;BMP&lt;/td&gt;&lt;td&gt;more involved&lt;/td&gt;&lt;td&gt;very efficient w/control over SQL&lt;/td&gt;&lt;td&gt;EJB container dependent *a&lt;/td&gt;&lt;td&gt;varies by implementation&lt;/td&gt;&lt;td&gt;EJB provided&lt;/td&gt;&lt;td class='strategy-name'&gt;BMP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='strategy-name'&gt;JDO&lt;/td&gt;&lt;td&gt;simple&lt;/td&gt;&lt;td&gt;possibly some performance penalty&lt;/td&gt;&lt;td&gt;developer managed&lt;/td&gt;&lt;td&gt;varies by implementation&lt;/td&gt;&lt;td&gt;developer managed&lt;/td&gt;&lt;td class='strategy-name'&gt;JDO&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='strategy-name'&gt;JPA&lt;/td&gt;&lt;td&gt;the simplest&lt;/td&gt;&lt;td&gt;possibly some performance penalty&lt;/td&gt;&lt;td&gt;EJB container dependent *a&lt;/td&gt;&lt;td&gt;varies by implementation&lt;/td&gt;&lt;td&gt;EJB provided&lt;/td&gt;&lt;td class='strategy-name'&gt;JPA&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='strategy-name'&gt;ORM/DAOs&lt;/td&gt;&lt;td&gt;simple&lt;/td&gt;&lt;td&gt;possibly some performance penalty&lt;/td&gt;&lt;td&gt;developer managed&lt;/td&gt;&lt;td&gt;varies by implementation&lt;/td&gt;&lt;td&gt;developer managed&lt;/td&gt;&lt;td class='strategy-name'&gt;ORM/DAOs&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='strategy-name'&gt;JDBC&lt;/td&gt;&lt;td&gt;most time-consuming and involved&lt;/td&gt;&lt;td&gt;theoretical best performance&lt;/td&gt;&lt;td&gt;developer managed&lt;/td&gt;&lt;td&gt;varies by implementation&lt;/td&gt;&lt;td&gt;developer managed&lt;/td&gt;&lt;td class='strategy-name'&gt;JDBC&lt;/td&gt;&lt;/tr&gt;&lt;tr class='non-j2ee-entry'&gt;&lt;td class='strategy-name'&gt;iBatis/DAO&lt;/td&gt;&lt;td&gt;somewhere between ORM and JDBC&lt;/td&gt;&lt;td&gt;excellent performance&lt;/td&gt;&lt;td&gt;developer managed&lt;/td&gt;&lt;td&gt;varies by implementation&lt;/td&gt;&lt;td&gt;developer managed&lt;/td&gt;&lt;td class='strategy-name'&gt;iBatis/DAO&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;*a = stateless session beans more scalable than stateful&lt;br /&gt;&lt;p class='non-j2ee-entry'&gt;not covered by SCEA exam&lt;/p&gt;Spring can help level the playing field outside EJB in some of the above developer managed areas by helping with transactioning, scalability and security.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-7015488653886550738?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/7015488653886550738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=7015488653886550738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/7015488653886550738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/7015488653886550738'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2009/10/j2ee-persistence-strategies-for-scea.html' title='J2EE Persistence Strategies'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-4017155639804128962</id><published>2009-09-18T00:21:00.000-05:00</published><updated>2009-09-18T00:32:57.801-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='extjs'/><title type='text'>assign IDs in ExtJS, or else...</title><content type='html'>&lt;p&gt;I was recently working on the UI side of things and having difficulty getting my complex 2-column form layout to display correctly (creating components dynamically and adding them to the the parent window object and nested panel objects).  Elements were either missing or grossly misplaced.&lt;/p&gt;&lt;p&gt;In ExtJS, IDs are automatically generated for your UI elements if you don't specifically assign them yourself, so I didn't really give much thought to the fact that I wasn't assigning my own IDs.  I was taking stabs in the dark and then for some reason decided to assign my own IDs and when I did, viola, it started working like a charm.  Lesson learned.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-4017155639804128962?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/4017155639804128962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=4017155639804128962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/4017155639804128962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/4017155639804128962'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2009/09/assign-ids-in-extjs-or-else.html' title='assign IDs in ExtJS, or else...'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-7905719975981806574</id><published>2009-09-17T23:47:00.000-05:00</published><updated>2009-09-18T00:07:19.007-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cute'/><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>the phone call</title><content type='html'>Yesterday morning my 3-year-old son called me at work to talk about something we would do together later that day.  He knows that I get home around dinner time so, mid conversation, I hear him call out to my wife "mom, can you make dinner now?"  Simply heart warming.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-7905719975981806574?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/7905719975981806574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=7905719975981806574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/7905719975981806574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/7905719975981806574'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2009/09/phone-call.html' title='the phone call'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-5474233155074203492</id><published>2009-09-17T21:53:00.000-05:00</published><updated>2009-09-22T13:01:53.251-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='military'/><category scheme='http://www.blogger.com/atom/ns#' term='career'/><title type='text'>reflections on opportunities past</title><content type='html'>&lt;p&gt;&lt;span style="font-family:verdana;"&gt;There are a lot of things I miss about being in the service (military) and be&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;sides the people, one of the things I miss most was the knowledge that no matter how good or how bad your current assignment was you knew it was going to change.  &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;The military thrives on leadership and to cultivate this its members are regularly reassigned in order to broaden their experiences and afford them opportunities for increased responsibility.  And there were so many choices of places you could go and things you could do.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;My first experience with this was what they call "service selection night" at the Naval Academy.  It's actually an entire day and they start very early in the morning as it takes a while to get through 1000 people.  They make announcements over the PA system and summon people in groups, according to their ranking in the graduating class, down to the selection office.  The purpose of this event is for first class midshipmen (seniors or "firsties" as we were affectionately called) to choose what they were going to do after they graduated.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;So, you hear your number called and you head down to the selection office.  You walk in the room and on the walls are listings of all the possible assignments that a young ensign or 2nd lieutenant could have.  There was Naval Aviation (Navy Air), Marine Air, Navy SEALs, Marine Infantry, artillery, Navy surface, or subs (submarines) or nuclear power, or whatever.  You could even pick the exact ship you were going to be assigned to and thus your home port.  It was really very exciting.  &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;For me, I knew I wanted to be a Marine and flying sounded exciting too so I thought I would give it a shot and become a pilot.  So that's what I chose - Marine Air.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;And that's kinda how it was during my time in the service - there were always new opportunities and always choices and there was always something new to look forward to while you were busy enjoying where you currently were and the people you were with.  &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;After flight school I got to choose what aircraft I would get to fly and where I would be stationed.  At the end of my first tour where I flew CH-46 helicopters out of Southern California things got a little more interesting.  As you move up you start talking to your 'monitor' (aka career counselor - someone back at Headquarters Marine Corps in Washington, DC) who is another officer temporarily assigned on his way up the ladder to work with a certain group of people and fill the openings left by others moving on to new assignments.  Again - choices, but now there was some negotiation and you had someone who had a bigger picture than you who could help guide you to the next assignment that would set you up for the one after that, and so on.  &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:verdana;"&gt;In my dozen years of post-military life I really haven't seen that - at least not at the places where I've worked.  I think there may have been something remotely similar to that at General Motors.  I mean, they did send me to leadership development courses and they did say they "had big plans for me" when I informed them I was leaving.  But, although I enjoyed my time there, I did not stay long enough to find out.  &lt;/span&gt;&lt;span style="font-family:verdana;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-5474233155074203492?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/5474233155074203492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=5474233155074203492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5474233155074203492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5474233155074203492'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2009/09/reflections-on-opportunities-past.html' title='reflections on opportunities past'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-5879572892545122143</id><published>2008-07-30T22:50:00.000-05:00</published><updated>2009-09-18T00:06:04.840-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Instrumenting with proxies</title><content type='html'>&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Using the InvocationHandler interface one can create a simple, yet sophisticated, means of instrumenting a class to obtain statistics about its usage:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; &lt;br /&gt;&lt;br /&gt;import java.lang.reflect.InvocationHandler;&lt;br /&gt;import java.lang.reflect.Method;&lt;br /&gt;import java.lang.reflect.Proxy;&lt;br /&gt;import java.lang.reflect.InvocationTargetException;&lt;br /&gt;&lt;br /&gt;public class MyProxy implements InvocationHandler {&lt;br /&gt;&lt;br /&gt;    private Object _target;&lt;br /&gt;    public Object getTarget() { return _target; }&lt;br /&gt;    public void setTarget(Object target) { _target = target; }&lt;br /&gt;&lt;br /&gt;    public &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;MyProxy&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;(Object target) {&lt;br /&gt;            _target = target;&lt;br /&gt;    } // constructor&lt;br /&gt;&lt;br /&gt;    public Object invoke(Object proxy,&lt;br /&gt;                         Method method,&lt;br /&gt;                         Object[] args)&lt;br /&gt;                throws Throwable {&lt;br /&gt;&lt;br /&gt;            Object result = null;&lt;br /&gt;&lt;br /&gt;            long start = System.currentTimeMillis();&lt;br /&gt;&lt;br /&gt;            try {&lt;br /&gt;                    result = method.invoke(_target, args);&lt;br /&gt;            } catch (InvocationTargetException ite) {&lt;br /&gt;                    long stop = System.currentTimeMillis();&lt;br /&gt;                    // log the exception here&lt;br /&gt;&lt;br /&gt;                    throw ite.getCause();&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            long stop = System.currentTimeMillis();&lt;br /&gt;            // log the invokation results&lt;br /&gt;        // (_target, method, stop - start);&lt;br /&gt;&lt;br /&gt;            return result;&lt;br /&gt;    } // invoke()&lt;br /&gt;&lt;br /&gt;    public static Object createProxy(Object target) {&lt;br /&gt;            Object result = target;&lt;br /&gt;&lt;br /&gt;            Class targetClass = target.getClass();&lt;br /&gt;                result = Proxy.newProxyInstance(&lt;br /&gt;                        targetClass.getClassLoader(),&lt;br /&gt;                        targetClass.getInterfaces(),&lt;br /&gt;                        new &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;MyProxy&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;(target)&lt;br /&gt;                );&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;             return result;&lt;br /&gt;    } // createProxy()&lt;br /&gt;&lt;br /&gt;} // class MyProxy&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-5879572892545122143?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/5879572892545122143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=5879572892545122143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5879572892545122143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/5879572892545122143'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2008/07/instrumenting-with-proxies.html' title='Instrumenting with proxies'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7625178889455096573.post-1561148980312947560</id><published>2008-07-28T15:13:00.000-05:00</published><updated>2009-09-18T00:20:44.746-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>limiting characters in an html textarea</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Here is a way to limit the amount of text entered into a textarea.  Note, this works in both IE and FireFox.  Also, this only limits characters entered via keystrokes and does not work for copy/paste.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;/* -------------------------------------------------------------------------&lt;br /&gt;limits the amount of text that can be typed into a textarea&lt;br /&gt;example usage: &amp;lt;textarea onkeypress="return limitText(event, this, 40);"&amp;gt;&lt;br /&gt;--------------------------------------------------------------------------*/&lt;br /&gt;limitText : function(event, textArea, maxChars) {&lt;br /&gt;    var result = true;&lt;br /&gt;&lt;br /&gt;    if (textArea.value.length &amp;gt;= maxChars) {&lt;br /&gt;&lt;br /&gt;            if (textArea.createTextRange) {&lt;br /&gt;                    var range = document.selection.createRange().duplicate();&lt;br /&gt;                    result = range.text.length  &amp;gt; 0;&lt;br /&gt;            } else {&lt;br /&gt;                    result = event.keyCode in {  // always let these keys through&lt;br /&gt;                            37 : "left",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;39 : "right",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;38 : "up",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;40 : "down",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;33 : "pageUp",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;34 : "pageDown",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;46 : "del",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;36 : "home",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;35 : "end",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;27 : "esc",&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;8 : "back"&lt;br /&gt;                    };&lt;br /&gt;            }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return result&lt;br /&gt;} // limitText()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7625178889455096573-1561148980312947560?l=usna86-techbits.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usna86-techbits.blogspot.com/feeds/1561148980312947560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7625178889455096573&amp;postID=1561148980312947560' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/1561148980312947560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7625178889455096573/posts/default/1561148980312947560'/><link rel='alternate' type='text/html' href='http://usna86-techbits.blogspot.com/2008/07/limiting-characters-in-html-textarea.html' title='limiting characters in an html textarea'/><author><name>Russ Jackson</name><uri>http://www.blogger.com/profile/15521749913146166813</uri><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/_61quPPv1xEc/TTTlmJIGrXI/AAAAAAAAAAc/vHc03C1VvNE/S220/russ.JPG'/></author><thr:total>0</thr:total></entry></feed>
