tag:blogger.com,1999:blog-74612750497811912612024-03-05T02:14:01.337-08:00Ken's Technical ThoughtsKen Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.comBlogger66125tag:blogger.com,1999:blog-7461275049781191261.post-7463486586280032282014-07-03T17:27:00.002-07:002014-07-03T17:30:03.052-07:00Nobody puts Baby in a Container<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
When it comes to <a href="http://www.docker.com/">Docker</a>, using a Mac in a Linux world comes with some challenges. There are a number of answers out there. Which is best depends on how much you want to understand underneath the abstraction Docker provides. In this blog entry we identify the problem and list a few solutions when it comes to network connectivity and Docker.<br />
<br />
And when it comes to baby... we mean <a href="http://redis.io/">redis</a> :)<br />
<br />
It can be frustrating when the tooling abstracts you from the details, yet you are required to understand the context of your environment to know that things are different. This is the case when using Docker on platforms other than Linux. In this blog we will simple put redis in a docker container and connect to it from the host OS.<br />
<br />
<h4 style="text-align: left;">
Redis Docker Image on Ubuntu</h4>
<div>
Lets look at a working environment to establish expectations. </div>
<div>
<br /></div>
<div>
It was only after working this for some time that I ran across a Redis Server. Lesson 1:(again) search before you build your own thing :). On <a href="https://registry.hub.docker.com/u/kensipe/redis/">my docker registry</a> there is a kensipe/redis container image which contains redis-server. You can pull the image with the following command.<br />
<br /></div>
<pre class="brush: shell">sudo docker pull kensipe/redis</pre>
<br />
<br />
The container is start with the following command:<br />
<br />
<pre class="brush: shell">sudo docker run --name redis -p 6379:6379 -d kensipe/redis
# future invocations of the server could be
sudo docker start redis
</pre>
<br />
With redis installed on the host OS, a simple redis-cli connects to the docker instances of redis and away you go! Isn't it wonderful? Automatic port assignment and forwarding from localhost.<br />
<br />
<h4 style="text-align: left;">
Once you go Mac...</h4>
<div>
<div>
The problem is on a Mac (and I assume any platform that needs to use boot2docker as a bridge), the port forwarding is from the bridge, not from the host OS. When you run <span style="font-family: Courier New, Courier, monospace;">docker run --name redis -p 6379:6379 -d kensipe/redis</span> from the Mac command-line and the docker ps reveals that the port mapping is assigned to 0.0.0.0:6379. However starting up the redis-cli doesn't connect.</div>
<div>
<br /></div>
<div>
Fortunately the boot2docker command provides some help. boot2docker ip will provide the IP address assigned to the underlying VM. For me it results in 192.168.59.103. Lets try redis-cli again. </div>
<div>
<br /></div>
<pre class="brush: shell">redis-cli -h 192.168.59.103</pre>
<div>
<br />
This results in a good connection to the redis server from the host OS.</div>
<div>
<br />
<h4 style="text-align: left;">
VBox Network Mapping</h4>
</div>
<div>
If you still want to tie it to localhost, there are a couple of things you can do. The more involved (not tested, but looks to be a superior way) is to follow the instructions <a href="http://ispyker.blogspot.com/2014/04/accessing-docker-container-private.html">http://ispyker.blogspot.com/2014/04/accessing-docker-container-private.html</a></div>
<div>
<br /></div>
<div>
Another approach is more simple IMO, but comes with some caveats. We will inform <a href="https://www.virtualbox.org/wiki/Downloads">Virtual Box </a>(VBox) to map the ports for us. The caveats are that you need to bring VBox down to configure it and when VBox comes up will take on that port (which could collide with local services). Here is the solution:</div>
<div>
<br /></div>
<pre class="brush: shell">VBoxManage modifyvm "boot2docker-vm" --natpf1 "redis,tcp,,6379,,6379"
boot2docker start
</pre>
<div>
<br /></div>
<div>
If you want to evaluate the configuration use:<br />
<br /></div>
<pre class="brush: shell">VBoxManage showvminfo boot2docker-vm
</pre>
<div>
<br />
If you want to delete that mapping to run redis locally, then<br />
<br /></div>
<pre class="brush: shell">VBoxManage modifyvm boot2docker-vm --natpf1 delete tcp-port6379</pre>
</div>
</div>
<br />
<div>
With the mapping in place, the standard defaults for redis-cli launched from the host will map to the redis in a container.</div>
<div>
<br /></div>
<div>
<br /></div>
<br /></div>
Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com7tag:blogger.com,1999:blog-7461275049781191261.post-52164486825747077792013-02-20T15:09:00.001-08:002013-02-20T15:09:53.131-08:00Hunt the Wumpus<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi0YXcuNek5oZ7WEEluqc9uMYO3r66TGg6XqsJsU0JfcmJiK4YC8wNZNTBcEkCXmmuVBs6FdmfBzMe0sOKqAHaSf4qOldVDAVrLFIIZ9Q1DF_iPJPDP7zLLXhQQlMvpNPnFaDJWr8Bt64/s1600/Screen-Shot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="61" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi0YXcuNek5oZ7WEEluqc9uMYO3r66TGg6XqsJsU0JfcmJiK4YC8wNZNTBcEkCXmmuVBs6FdmfBzMe0sOKqAHaSf4qOldVDAVrLFIIZ9Q1DF_iPJPDP7zLLXhQQlMvpNPnFaDJWr8Bt64/s320/Screen-Shot.png" width="320" /></a></div>
<br />
<div>
From the screen snapshot... what is wrong?</div>
<div>
<br /></div>
<div>
ok... it is using maven... what else?</div>
<div>
<br /></div>
<div>
ever seen a C: on a unix... good times!, apparently the tests build this out. Let's hope the day gets better than this :)</div>
</div>
Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com2tag:blogger.com,1999:blog-7461275049781191261.post-43794023576742264432013-02-19T10:04:00.000-08:002013-02-19T10:04:04.038-08:00Java 6 End of Life<div dir="ltr" style="text-align: left;" trbidi="on">
It may be important to note for companies running on Java, that Java 6 (probably the most common JVM platform for most of my enterprise customers) will reach it's <a href="http://www.oracle.com/technetwork/java/eol-135779.html">EOL</a> this month, Feb 2013.<br />
<br />
Time to be moving to Java 7 if you haven't yet!<br />
<br /></div>
Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com4tag:blogger.com,1999:blog-7461275049781191261.post-75560660142136510522013-02-07T07:59:00.002-08:002013-02-07T08:56:48.639-08:00New Year Commitments<div dir="ltr" style="text-align: left;" trbidi="on">
Looking to recommit to this tech blog... so what to expect from 2013<br />
<br />
<h2 style="text-align: left;">
Conferences</h2>
<div style="text-align: left;">
</div>
<ol style="text-align: left;">
<li>looking forward to a new year with <a href="http://www.nofluffjuststuff.com/home/main">NFJS</a></li>
<ul>
<li>Doing more Groovy this year with <a href="http://www.gradle.org/">Gradle</a> and <a href="http://code.google.com/p/spock/">Spock</a></li>
</ul>
<li>Poland YAY! love Poland!</li>
<ul>
<li><a href="http://2013.geecon.org/">GeeCon 2013</a></li>
<li><a href="http://2013.33degree.org/">33rd Degree</a></li>
</ul>
<li><a href="http://jz13.java.no/">JavaZone 2013 </a>in Oslo</li>
<li><a href="http://uberconf.com/conference/denver/2013/07/home">UberConf 2013</a></li>
</ol>
<div>
that's what is scheduled currently</div>
<div>
<br /></div>
<h2 style="text-align: left;">
Blog Posts</h2>
<div>
I'm going try to post more frequently... and probably on themed subjects... are couple that come to mind:</div>
<div>
<ol style="text-align: left;">
<li>Lessons from clients:) </li>
<li>Tech Review or highlight of components / frameworks</li>
</ol>
<div>
If you have suggestions... please post.</div>
</div>
<div>
<br /></div>
<div>
Currently looking at writing a book on Spock as well... so we will see.<br />
<br />
<h2 style="text-align: left;">
Technical Nugget</h2>
if you haven't noticed... take a look at <a href="http://www.methods.co.nz/asciidoc/">asciidoc</a> and <a href="https://github.com/asciidoctor/asciidoctor">asciidoctor</a>. All my tech writings and book will be written in asciidoc this year :) In addition to all readme files on github,<a href="http://asciidoctor.org/news/asciidoctor-announcement.html"> thanks to the githubbers and Dan Allen!</a><br />
Sweet!!<br />
<br />
<h2 style="text-align: left;">
Predictions for the year</h2>
</div>
<div>
Java 8 release YAY!</div>
<div>
Mobile security will become an issue</div>
<div>
Asciidoc takes over as the preferred markup</div>
<br /></div>
Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com2tag:blogger.com,1999:blog-7461275049781191261.post-75366132970823280302012-09-02T15:52:00.001-07:002012-09-02T15:52:05.212-07:00JavaZone 2012<div dir="ltr" style="text-align: left;" trbidi="on">
If you are looking for one of the top Java conferences, you need to take a look at <a href="http://jz12.java.no/news">JavaZone</a> in Oslo, Norway. Having been there a number of times over the last several years and comparing it to other Java conferences... It is top notch! I'll be speaking there again in a couple of weeks and I'm certainly looking forward to it! <br />
<br />
If you can sneak away... this is the one to come to!<br />
<br />
Hope to see you there!</div>
Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com6tag:blogger.com,1999:blog-7461275049781191261.post-67231940258776926732012-05-28T09:49:00.000-07:002012-05-28T09:49:32.897-07:00The Key Tenets - 7 Years after The Internet Services Disruption<div dir="ltr" style="text-align: left;" trbidi="on">
October 28 2005 Ray Ozzie, having recently joined Microsoft (msft) at the time, put together an interesting manifesto with the subject title of "<a href="http://scripting.com/disruption/ozzie/TheInternetServicesDisruptio.htm">The Internet Services Disruption</a>", with the purpose of "get all of us roughly on the same page". For currently undisclosed reasons, I had reason to review this document and found it completely fascinating. Ray's foresight and ability to forecast the future is just amazing. Although his writing was made public (good for us all), it was intended to inspire and position MSFT for it's next great phase. Let's look at each of the key tenets Ray outlined and see who in our industry has the upper hand.<br />
<br />
1. The power of the advertising-supported model<br />
Is MSFT winning here... definitely not. Winners in this category are Google, making money off google.com. Facebook making money on ads based again on high traffic visitations. While these two companies are making good money with this concept, the company to watch is Apple. Why? Apple is actually empowering developers with this ad-support model through iAd. Like ads or not... Apple is enabling developers to provide solutions free to consumers and are paid through ad hits. There has also been a resent uptick in the number of ads off services like Hulu and youtube. So there is no question that Ray nailed this tenet. <br />
<br />
2. The effectiveness of a new delivery and adoption model<br />
While Ray describes this in a try before you buy, and a readership and review model, while being valid it is ubiquitous, so it is hard to give any one company brownie points for this. Most of the good companies have their share of fan boys, VIP programs and evangelist (in the which MSFT does a stellar good at), I would like to take this concept a little deeper. New delivery... and delivery of what. Considering operating systems and software, everyone is going disc-less. Delivery of updates are internet provided. But lets talk content... There is a new delivery mechanism for content... how do you watch your movies, how to you read your books, how do you get your music? Where is MSFT in this space? No where to be found. Who owns this space? Well... depending it seems divided between Amazon, NetFlix AND the big one? Apple. Apple hits gold stars in this category up and down their product like. In fact one could say that the adoption of an iPod or iPad is a gateway into the full Apple stack.<br />
<br />
3. The demand of compelling, integrated user experiences that "just work"<br />
While I could go into detail and beat around the bush... this statement screams Apple. While apple costs more in some cases, they are uncompromising and focus on the user experience. They have all the advantages in this category as well. they own the full tech stack... they don't have to make it work on a billion devices... they have theirs.<br />
<br />
I consider myself a technologist and I don't "belong" to a specific tech group. I see value in a number of camps. The take away for me... is how insightful Ray was almost 7 years ago. He nailed it. It is too bad that MSFT doesn't seem to be paying attention to him. </div>Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com6tag:blogger.com,1999:blog-7461275049781191261.post-42828757824957697532012-04-05T11:46:00.003-07:002012-04-05T11:55:28.011-07:00Getting the Spock out of a Gradle WarI recent ran into a interesting situation, for which I thought it would be worth sharing. I have a new project with the following build needs: Java, Spring MVC and <a href="http://code.google.com/p/spock/">Spock Testing.</a> The problem is simple... The WAR build in gradle was building a WAR file that included the Groovy libraries. This project has no need for groovy at runtime. <a href="http://groovy.codehaus.org/">Groovy</a> is needed because I'm using Spock for my testing.<br /><br /><h3>Gradle and providedCompile</h3>In older versions of Gradle it was commonly necessary to manage the jars in the lib directory. In the maven world, there is a dependency scope of "provided". This scope basically means that the dependency will be provided on the server classpath, however for the purposes of compiling the code in the project it is necessary. From a WAR perspective it means use this dependency for compile, but do not include it in the lib directory of the WAR. Gradle within the last year has added the same feature as providedCompile or providedRuntime. In my project I have this very need with the servlet-api, shown below.<br /><pre class="brush: groovy">dependencies {<br /> compile "org.springframework:spring-webmvc:$springVersion"<br />compile 'javax.servlet:jstl:1.2'<br /> providedCompile 'javax.servlet:servlet-api:2.5' <br />}<br /></pre><h3>Spock dependencies and Gradle</h3>As Spock is a groovy testing tool, it is no surprise that Spock requires groovy. This requires a couple of well documented configurations in your gradle file. First, you'll have to add the groovy plugin. Second you have to set as a dependency the groovy version. But wait!!! The dependency for groovy doesn't have a scoping ability. This is area where the "model" of gradle breaks down a little bit IMO. Ideally you would be interested in expressing in the model that there are "testing" needs... and those testing needs require groovy and spock dependencies.<br /><pre class="brush: groovy">apply plugin: 'groovy'<br /><br />def spockVersion = '0.5-groovy-1.8'<br />def springVersion = '3.1.0.RELEASE'<br /><br />dependencies { <br />groovy 'org.codehaus.groovy:groovy-all:1.8.3'<br /> testCompile 'junit:junit:4.8.1'<br />testCompile "org.spockframework:spock-core:$spockVersion"<br />testCompile "org.spockframework:spock-spring:$spockVersion"<br />}<br /></pre>With this groovy dependency any build of WAR will result in a the groovy-all-?.?.?.jar file being added to the the WEB-INF/lib directory. The problem is I have no current interest in having groovy in production for this project. What to do? What to do?<br /><h3>Gradle Doc to the Rescue</h3>I find that a large number of people (usually new to gradle) struggle with discovering how to resolve such a problem. The best starting point for getting to know gradle is the gradle <a href="http://gradle.org/docs/current/userguide/userguide.html">user guide documentation</a>, but the best starting point to use as a reference is the gradle <a href="http://gradle.org/docs/current/dsl">dsl documentation</a> (<a href="http://gradle.org/docs/current/dsl">http://gradle.org/docs/current/dsl</a>). Hopefully it is obvious that what we want to change is the build of the WAR. So lets look at the War task. Here we see all of it's properties... which includes the classpath property. The documentation for this property clearly states that this property affects the WEB-INF/classes and the WEB-INF/lib. Diving deeper into that property we see the default behavior which is:<pre class="brush: groovy">project.configurations.runtime - project.configurations.providedRuntime<br /></pre>So our logical solution would be to include a war task configuration for the building of the classpath like this:<pre class="brush: groovy">war {<br /> classpath = classpath - project.configurations.groovy<br />}<br /></pre><br /><br />Happy Coding! and may your builds never fail!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com2tag:blogger.com,1999:blog-7461275049781191261.post-44242126081886154712012-03-18T10:27:00.002-07:002012-03-18T10:29:46.865-07:00Speak at the 33rd Degree<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzXTPc_E13K4oa5Rj_pFE1nNZ1ajzh7zTyK65D6FltFYkEI0YPH8G0jagse7ChNRm_Sf4dOstpvHsix7PIg81UIJU5rQFXO6aQsfxzahQx-W_aIdTAK8XiyW2C72fnjqr8TwiIfRfn_90/s1600/33Degree_2012_Speaker.png"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 250px; height: 250px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzXTPc_E13K4oa5Rj_pFE1nNZ1ajzh7zTyK65D6FltFYkEI0YPH8G0jagse7ChNRm_Sf4dOstpvHsix7PIg81UIJU5rQFXO6aQsfxzahQx-W_aIdTAK8XiyW2C72fnjqr8TwiIfRfn_90/s320/33Degree_2012_Speaker.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5721290606756601762" /></a><br />I will be speaking in Poland this month at the 33rd. It looks like a great conference line up and Krakow is wonderful.<div><br /></div>Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com3tag:blogger.com,1999:blog-7461275049781191261.post-33975141818101421642012-03-14T15:18:00.003-07:002012-03-14T15:51:07.977-07:00Agile: getting the standup right!<span><span style="font-size: 100%;">The standup meeting as part of an agile discipline at first seems like an easy and obvious activity. Yet I keep coming across clients and organizations that seem to struggle with getting it right. It appears that as long as everyone is standing... and we do that everyday... that we can check "standup" off the list. Just standing up doesn't make it a stand up! (Please repeat that... as often as it takes to get it.) On top of that... many organizations seem to think that the stand up is for the scrum master or management to get status. That's not it either! Here are some warning signs:</span></span><div><ul><li><span>Standups take 30 mins or longer</span></li><li><span>People regularly miss the meeting</span></li><li><span>You are always waiting 10 minutes for that one person</span></li><li><span>The PM or Scrum Master is asking clarifying questions</span></li></ul><div><span>The standup meeting is NOT:</span></div></div><div><ul><li><span>Primarily for status (I know that might seem confusing)</span></li><li><span>About the position you are in during the meeting</span></li><li><span>About the Scrum Master</span></li></ul><div><span>Getting the standup right is crucial for a healthy agile team. It is for and about the team. Here is the purpose of the standard up:</span></div></div><div><ul><li><span>Synergy - It is a point for developers to synchronize their efforts and realize when there is about to be some code thrash. It is a point to say, "hey joe, I'm about to do task x which is closely related to your task y, lets get together after the standup".</span></li><li><span>Transparency - Everyone knows what is being done, which provides a double check that each person is doing the highest priority tasks and is there anything holding us up.</span></li><li><span>Accountability - This the best place to realize that a team mate is struggling. When you see that Joe has had a 4 hour task for 2 days its time to say "Joe... lets pair on that... lets see if we can knock that out.</span></li></ul><div><span>These purposes come out of the standard questions most agile developers are aware of: "What did I do?", "What am I going to do?" and "is there anything holding me up?". I know this sounds like status... it's not.</span></div><div><span><br /></span></div><div><span>Advice for Scrum Masters</span></div><div><ul><li><span style="font-family: Georgia, serif; ">First realize you are not the reason for the standup</span></li><li><span style="font-family: Georgia, serif; ">Standups are 10-15 mins.. that's it. </span></li><li><span>Do not ask for follow up during the stand up... if something needs to be followed up, follow the person of interests back to their desk and ask them without tying up everyone else's time.</span></li><li><span>If it becomes clear that the team needs to meet.. for a design discussion or a big status meeting or... doesn't matter. It is super important to delineate that as a separate meeting. "Hey I would like to discuss x with everyone after the standup. Please stick around.". Then announce "ok, that is the end of the standup, lets discuss x"</span></li><li><span>The best thing you (Scrum Master) can do during the standup is to facilitate. Do not allow someone to dominate 5 mins of the 10 min standup or elaborate extensively. The challenge is not to be a jerk about it... If it is a challenge, then it is something that needs to be discussed in a retro meeting, asking for the teams opinion and possible solutions.</span></li></ul><div><span>A big part of getting agile right is to understand why we do certain things! It isn't about standing up. It is about keeping it short and to the point. It is about getting the benefits listed above out of it. </span></div></div></div><div><span><br /></span></div><div><span>Good Luck</span></div>Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com2tag:blogger.com,1999:blog-7461275049781191261.post-43843391811157300312011-12-20T11:49:00.000-08:002011-12-20T12:55:01.147-08:00Constant Pain with Non-Constant ConstantsThis thought has crossed my mind before... since it is on my mind now I thought I might share. Perhaps it will help someone on their software development career path... or perhaps it is just me venting...<br /><br /><h2>The Art of Coding</h2><br />One of the greatest challenges of coding is being able to understand it. Skill in coding is being able to understand the problem well enough to create a solution (otherwise known as coding). <em>Great Skill</em> is being able to write a solution so that someone else (including the future you) can read and understand what it is they are looking at. This concept isn't new, but yet we seem to be either challenged with the concept... or distracted. Even back in 1952 (yes 1952!!), in the computer history archive a <a href="http://archive.computerhistory.org/resources/text/Fortran/102653981.05.01.acc.pdf">set of lecture notes</a> which in them states: "It is quite difficult to decipher coded programs even with notes and even if you yourself made the program several months ago." It also states: "I think the answer is simple: to make it easy one must make coding comprehensible". Well said!<br /><br /><h2>The Point of Constants</h2><br />One area that seems to be a constant :) struggle is constants. There are at least a couple of justifications for using constants I can think of: 1) a point of reference for tools (autocomplete with intellisense in IDEs and refactoring), 2) A common holder of value for which if it changes will be realized across the system. The main point of a constant isn't <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> or reuse... a common point of confusion for some reason.<br /><br />IMO the stronger argument is point 2. if you were coding in VI or emacs, point 1 may not be of value, but point 2 certainly would be. If you name the reference of a constant the same name as the value of the constant... then you lose any the value of point 2. <br />It must also be said that constants, although they add value, they make code less readable (see examples below). If your constants have no value, they don't achieve points 1 and 2, then they need to be whacked!<br /><br /><br /><h2>Examples of Losing with Constants</h2><br />This is real production code... some variables changed to obscure identify.<br /><pre class="brush: java"><br /><br /> // example 1 Really?? where does this end?<br /> String EMPTY_STRING = "";<br /><br /> // this isn't readable... it takes minutes (instead of seconds) to understand its value<br /> // example 2<br /> String ADVERTISE_PROPERTY_PREFIX = OUR_PROPERTY_PREFIX + "advertise.";<br /> String ADVERTISE_TRADER_ADDRESS_PROPERTY = ADVERTISE_PROPERTY_PREFIX + "host";<br /> String ADVERTISE_CONTEXT_PROPERTY = ADVERTISE_PROPERTY_PREFIX + "context";<br /> String ADVERTISE_TYPE_PROPERTY = ADVERTISE_PROPERTY_PREFIX + "type";<br /><br /> // example 3<br /> // here's a common one<br />static final String TABLE_NAME = "email";<br /><br /> // Column names for all the fields in the email table<br />static final String ID = TABLE_NAME + ".email_id";<br />static final String CUSTOMER_ID = TABLE_NAME + ".customer_id";<br />static final String ADDRESS = TABLE_NAME + ".address";<br /> // ...<br />static final String FIELDS = ID + ", " + CUSTOMER_ID + ", " + ADDRESS + ", " + CREATED_BY + ", " + LAST_MOD_BY<br /> + ", " + CREATE_DATE + ", " + LAST_MOD_DATE + ", " + TERM_DATE + ", " + WEB_USER_ID;<br /><br /> // List of fields names with formatting used for select statements<br />static final String SELECT_FIELDS = ID + ", " + CUSTOMER_ID + ", " + ADDRESS + ", " + CREATED_BY + ", "<br /> + LAST_MOD_BY + ", " + "TO_CHAR(" + CREATE_DATE + ",'" + DATE_TIME_FORMAT + "')," + "TO_CHAR("<br /> + LAST_MOD_DATE + ",'" + DATE_TIME_FORMAT + "')," + "TO_CHAR(" + TERM_DATE + ",'" + DATE_TIME_FORMAT<br /> + "')," + WEB_USER_ID;<br /><br /> // SQL used to create a new EMAIL record<br />static final String CREATE_SQL = "INSERT INTO " + TABLE_NAME + " (" + FIELDS<br /> + ") VALUES (?,?,?,?,?,SYSDATE,SYSDATE,NULL,?)";<br /><br /> // SQL used to retrieve an email record by id<br />static final String RETRIEVE_BY_ID_SQL = "SELECT " + SELECT_FIELDS + " FROM " + TABLE_NAME + " WHERE " + TERM_DATE<br /> + " IS NULL AND " + ID + "=?";<br /></pre><br /><br />For example 1... where does it end? would you create a constant A = "A"? When can EMPTY_STRING not be an empty string or ""? In this case, we get no value and less readability.<br /><br />Example 2 is the chaining of constants, commonly found when there are a large number of property values being retrieved from a file or sys env. While not as bad as example 1, it is less readable. Having a prefix constant may be of value, but rarely is the chaining of constants of value. It isn't worth trading the potential for a company name change or something similar for readability. Or put another way, it isn't worth trading something that is unlikely to happen for something else which is more likely to be needed (that being the readability of the code)<br /><br />Example 3 I see all the time... argghhhhh... please... just stop!<br /><br />Examples of good constants would include, urls and database connections strings or a project defined standard date format.<br /><br />May your constants always be final!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com6tag:blogger.com,1999:blog-7461275049781191261.post-40789996876956723582011-12-14T15:10:00.000-08:002011-12-14T15:49:45.433-08:00Advanced Spock Techniques<a href="http://cdn2-b.examiner.com/sites/default/files/c8/da/c8da7f602f266072aed0b46897be8610.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 110px; height: 82px;" src="http://cdn2-b.examiner.com/sites/default/files/c8/da/c8da7f602f266072aed0b46897be8610.jpg" border="0" alt="" /></a><br /><br />In recent years there have been a couple of tools that stand out when it comes to helping me be productive. One of those is the groovy test framework <a href="http://code.google.com/p/spock/">Spock</a>. It is worthy of an introductory blog post... but that isn't this post. One of the challenges to Spock is the documentation isn't a complete as one would hope. The <a href="http://code.google.com/p/spock/wiki/GettingStarted">Spock Basics</a> is fantastic when getting started but it is what it claims to be basics. I've been speaking with <a href="http://www.nofluffjuststuff.com/home/main">NFJS</a> on the subject of Spock for the last half of 2011. On 2 occasions I've had the look our red shirted friend in the picture has when asked about controlling aspects of mocks in spock... meaning I didn't have the answer. In this case, google didn't discover it either... a quick email to the <a href="http://www.springone2gx.com/conference/speaker/peter_niederwieser">Peter Niederwieser</a> reveals the previously undocumented solution. (at least that's my understanding)... and thanks Peter! <div><br /></div><br /><div><br />Here we will discuss 2 advanced aspects of mocking with spock. If you need more details on mocking in general hit the Spock site... or wait patiently for a future post:)<br /></div><div><br /></div><h3>Problem Setup:</h3><div>When mocking with Groovy we get 2 benefits from the verification of the mock. 1) order of execution, 2) failure if another method on the mock was executed but was not setup in the demand configuration.</div><div><br /></div><br /><pre class="brush: groovy"><br />void testDeposit() {<br /><br /> Account account = new Account(TEST_ACCOUNT_NO, 100)<br /><br /> def mock = new MockFor(AccountDao)<br /> mock.demand.findAccount(TEST_ACCOUNT_NO) { account }<br /> mock.demand.updateAccount(account) { assertEquals 150, account.balance }<br /><br /> def dao = mock.proxyDelegateInstance()<br /> def service = new AccountServiceImpl(dao)<br /><br /> service.deposit TEST_ACCOUNT_NO, 50<br /> mock.verify dao<br /> }<br /></pre><br /><br /><h3>Spock Cleanup</h3><br />A similar solution in Spock might look like this:<br /><pre class="brush: groovy"><br /> def "deposit into account test refactor"() {<br /><br /> def mock = Mock(AccountDao)<br /> def service = new AccountServiceImpl(mock)<br /><br /> when:<br /> service.deposit nmr, amt<br /><br /> then:<br /> mock.findAccount(_) >> account<br /> 1 * mock.updateAccount(_)<br /> 0 * mock.createAccount(_)<br /><br /> and:<br /> account.balance == total<br /><br /> where:<br /> nmr | account | amt | total<br /> "101" | new Account("101", 100) | 50 | 150<br /> "101" | new Account("101", 0) | 50 | 50<br /> }<br /></pre><br /><br />However this solution doesn't guarantee order nor do we want to use the 0 * mock.<method> on all possible methods. <br /><br /><h3>Spock Mock Solution</h3><br />It turns out that we can repeatedly use the then: dsl to determine the order of events. So we can modify the Spock code above with the following changes.<br /><br /><pre class="brush: groovy"><br /> then:<br /> 1 * mock.findAccount("1234") >> account<br /><br /> then:<br /> _ * mock.updateAccount(_)<br /></pre><br />In this case we are saying that the findAccount() method will be called exactly once and return the account object and "then" the updateAccount will be call any number of times with any type of argument. The test will fail if the updateAccount is ever called prior to the findAccount being invoked first.<br /><br />We can use this same technique to solve the strictness concern we have as well by adding one more then: block of code as outlined below:<br /><pre class="brush: groovy"><br /> then:<br /> 1 * mock.findAccount("1234") >> account<br /><br /> then:<br /> _ * mock.updateAccount(_)<br /><br /> then:<br /> 0 * mock._<br /></pre><br />In this case the last 0 * mock._ says to expect nothing else. Ahhh.. the beauties of a dynamic language:)<br /><br />Happy Coding... may your builds never fail and your tests always green bar!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com1tag:blogger.com,1999:blog-7461275049781191261.post-89677713809734740902011-10-13T06:07:00.001-07:002011-10-13T07:29:42.288-07:00MongoDB Grails and Copying CollectionsI currently find myself working on a project where Grails and MongoDB are the technology stack... in fact that in part is some of the reason for being interested in the project. I thought I would share 2 aspects of my learning so far:<br /><br /><h2>Grails + Mongo</h2><br />We spent at least 2 weeks trying to understand which approach we were going to take for our persistent tier. The general concensus was to use the Mongo GORM. We started down that path and ran into a bug and then a limitation on embedding. We got amazing support on the bug followed by the next release of the GORM option which fixed our initial document embedding concerns. We ran into more problems.<br /><br />We switched to the morphia driver... once again... challenges caused lots of frustration. The challenges included getting other plugins to work with this driver, the fact that the morphia "domain" objects couldn't be in the standard grails domain folder, which further complicated mocking. Frustrations with getting full capabilities of getting spring security to work. It turns out that with spring security there are a number of relational assumptions (along with assumptions of objects being domain classes.. meaning they live in the grails domain package space) which cause problems when you are using NoSQL.<br /><br />The morphia had another limitation we couldn't live with... we wanted the ability to have different types of objects mapped to the same collection. It appears to me that the Mongo efforts in the Grails space are bolt ons to a rational model. You can get it to work when thinking with a RDBMS mindset. They seem to break down with a NoSQL mindset... this certainly could be attributed to user error (meaning me). I believe we gave it a good try... however the project is under the gun and we didn't have time to "play" with it or wait for responses.<br /><br />Alas we created our own solution... one of our significant constraints was to be prepared for extremely large scale. This had us duplicating a lot of documents not common in RDBMS solutions... along with the fact we needed to control the number of queries. Ideally we want 1 query for a page... certainly for the main page which is high laden with dynamic content.<br /><br /><h2>Mongo Copying Documents - Collection to Collection</h2><br />I'm really getting to like Mongo... a lot. One of the downsides is there is limited documentation... including limited forum comments on it. Because of this, I've decided to post interesting solutions to problems as I discover them... time permitting. so for todays tip. I recently needed to duplicate a "record" in mongo speak a document in a collection. There is so much information out there on how not to duplicate records that a google search at this point usually points you in the wrong direction. My situation was such that we have a CMS component to our application, which sets a publish day on content. What I needed was the ability to duplicate a record (so the BSON id would need to change and set a new publish day.<br /><br />The first thing to recognize for those new to Mongo is that the Mongo console (the command line client to Mongo) works with javascript... so get your javascript fu ready... no.. not your jQuery fu... your plain jane generic javascript fu:)<br /><br />Here is the solution I came up with:<br /><pre class="brush: javascript"><br />db.NewsItem.find({newsType: "Blah"}).forEach( function(x){ x._id = new ObjectId(); x.publishDay=283; db.NewsItem.insert(x)} );<br /></pre><br /><br />So it turns out that you can pass a lambda expression to the forEach method of the collection. The trick is to assign a new ObjectId() to the _id, make any other assignments and then insert into your collection of choice... in this case back into the same collection. This comes in handy as well when you want to backup a collection real quick. (yea, I know you could use the mongodump and mongorestore, for a quick temp solution this just seems more convenient)<br /><pre class="brush: javascript"><br />db.NewsItem.find({publishDay : 285}).forEach( function(x){ db.NewsItemBackup.insert(x)} );<br /></pre><br /><br />Happy Coding!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com16tag:blogger.com,1999:blog-7461275049781191261.post-43792074452846790822011-10-05T09:02:00.000-07:002011-10-05T09:06:16.303-07:00JavaOne: Rocking the GradlePresenting Rocking the Gradle at <a href="http://www.oracle.com/javaone/index.html">JavaOne</a> tomorrow 12:30pm at the Parc 55... see you there!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com1tag:blogger.com,1999:blog-7461275049781191261.post-10090156044752835062011-01-11T14:50:00.000-08:002011-01-11T14:59:43.745-08:00Throughput and High VelocityWow… has it really be 11 months since I’ve blogged. I had many ideas for blogs half written or half thought out… but last year was extremely busy. It’s a new year… and I’m back :) Let’s not focus on the past, let’s get right into it.<br /><br />I had a client recently asking how to improve throughput. It took me a few minutes of questioning to understand what the subject really was. Thoughtput? Are you having scaling issues? It turns out, the interest is closer to developer throughput, although I don’t think they used that term and it may have been broader than that. The interest is in the acceleration of moving an idea into a product. Immediately coming to mind is the book <a href="http://www.amazon.com/Goal-Process-Ongoing-Improvement/dp/0884270610">“The Goal”</a>, whose focus it is to increase the throughput of a manufacturing plant. Although the creation of software is nothing like an assembly line (although the analogies seem to be common place), it is however interesting to consider some of the similarities involved with the theory of constraints. The challenge is, in my opinion, that the constraints for software development are more virtual and harder to measure than assembly line constraints.<br /><br />Consider what slows down the development of software. Of all my years of software development, the issue has never been an issue of programmer to keyboard. In other words, it isn’t how you type or how fast you type, although it certainly needs to be reasonable. It often times isn’t how long a developer has been developing… although again there is a required threshold. Where have there been issues? Let’s see if you list is similar to my list:<br /><ul><li>Poorly written requirements. The user seems to know what they want, but was unable to communicate it effectively or the BA was unable to capture it appropriately.</li><li>Lack of direction, mission and purpose of the entire team… either we have too much time, too much money or a total lack of leadership. Let’s chalk this up to priorities.</li><li>Lack of knowing what to do next… BA or programmer… or PM</li><li>Lack of knowing how what a programmer is working on fits into the whole</li><li>Lack of team coordination</li><li>Large team sizes</li></ul>I’m sure there are plenty more… but what I would say is the #1 issue for teams in trying to achieve high velocity is <b>clarity of thought</b>. I mean the ability to see a problem as the user sees the problem. Being able to see a solution and understand the problem in abstract terms and abstract ways; For a team to have the same thought or to hold within their minds the same mental model / picture. This is a tough task as differing priorities, differing locations, differing experiences and differing thoughts among the team members results in a number of differing ideas to the solution. It brings to mind to me of the scene in the last samurai, where <a href="http://www.youtube.com/watch?v=u7N4UIrC8uY">Koyamada tells Tom Cruise “Too Many Mind”… “No Mind”</a><br /><br />As Dr. Covey says in 7 Habits of Highly Effective People (which is what we are talking about… right?), you must start with the end in mind. Clarity positions people to be as effective as they can be. In the real world, a user really may not have the clarity themselves or may not understand the problem fully to articulate the desired clarity. This is why an agile development process is so effective. It provides an opportunity for the user to discover the clarity through regular feedback with the developers. Or in other words to detect deltas in the forming solution from the ideal or user desired solution. It also places the developer close to the user, so that through the creation of software when the output drifts from the user mental model it is caught quickly and corrected. Also developers are pairing with, and communicating with other developers regularly so that differences in the mental model are detected early.<br />What we are seeking for efficiencies sake is the fastest mechanism to <b>detect</b> that something is just not right.<br /><br />So at the time of development what are the common practices that occur in a corporate development which cause inefficiencies or put another way what are the practices that cause the error detection to be delayed, either the detection itself is delayed or the communication of the detection is delayed.<br /><ul><li>Developers are several degrees removed from the user. So there are either 2 human “hops” for error recognition and for communication.</li><li>Developers are too junior. Junior developers are just less capable of thinking and communicating in abstract software terms and are less able to detect deficiencies in the solution model.</li><li>Separation of the team members. Numerous studies show the increase cost of communication of people in just 2 different rooms, its more expensive for 2 different floors and way expensive when there is an ocean between members of the team. There is an additional cost that isn’t well documented in the fact the difference in the mental model or solution set are very difficult off-shore.</li><li>Communication is all facilitated through paper. This is the worse of all the communication modalities.</li></ul><br />So what can you do to increase throughput? What can you do to increase team velocity?<br /><ol><li>Hire highly skilled developers, developers skilled in their language who also have a proven record of quickly translating problem sets into solution sets. </li><li>Provide them with quick, and easy access to the user</li><li>Put the developers in the same work space</li><li>Reduce the team size, which results in less possibilities of mental model differences.</li></ol>You are looking for a team with a high attention to detail and ability to detect differences in the mental model during the development process. Then you are looking for well-lubricated spontaneous communication.<br /><br />This isn’t fool proof but it does solve one of the largest most common problems I see in corporate software development.<div><br /></div><div>A number of ideas came to mind in the process of writing this blog... and there are some assumptions baked into the content. Based on that, I will likely blog deeper on several of these subjects in the future.</div><div><div><br /></div></div>Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com2tag:blogger.com,1999:blog-7461275049781191261.post-69615163111125898062010-02-21T19:59:00.000-08:002010-02-21T20:27:00.568-08:00Setting up Clojure 1.1.0 on Mac OSXAs part of the <a href="http://lambdalounge.org/">Lambda Lounge</a>, established by Alex Miller (Thanks!!), we have started a group to study the SICP. We just started and are going virtual... if you would like to participate, email or tweet me (@kensipe). In the process of studying SICP and LISP, I plan on focusing on Clojure. Clojure was previously on my machine as I was reading Stu's book <a href="http://www.amazon.com/Programming-Clojure-Pragmatic-Programmers-Halloway/dp/1934356336">Programming Clojure</a>, however increased usage would require some maturing of my tools. This led to the discovery of Mark Reid's blog on <a href="http://mark.reid.name/sap/setting-up-clojure.html">Setting up Clojure for Mac OS X</a>, however I assume based on updates and changes over the last year, it requires some updates.<br /><br />Read Mark's blog first... getting clojure, the clojure-contrib and jline. Here are the differences:<br /><ul><li>Create an environment variable CLOJURE_HOME assigned to the directory for clojure</li><li>Create the /bin directory for the clj script included below</li><li>Add $CLOJURE_HOME/bin in the $PATH</li><li>Clojure is distributed with clojure.jar in the CLOJURE_HOME... so I maintain that. It is expected that contrib and jline are in the same directory.</li><li>Mark's clj script has been updated below... The previous script invokes classes which are depreciated.<br /></li></ul>Here is the updated script:<br /><pre class="brush: bash"><br />#!/bin/bash<br /># Runs Clojure using the classpath specified in the `.clojure` file of the<br /># current directory.<br />#<br /># Ken Sipe <http: com=""> 2010-02-20<br /># Inspired by Mark Reid <http: name=""><br /># original: http://github.com/mreid/clojure-framework/blob/e1c80cc650f448713243be8272dba1fa3c1a7cea/clj<br />#<br /># This scripts expects $JAVA_HOME and $CLOJURE_HOME to be defined for the system it is running on<br /># The clojure.jar is standardly in the clojure_home dir (and not in the lib directory), so<br /># the expectation is that clojure-contrib.jar and the jline.jar are placed in the same dir<br /><br />CLJ_DIR=$CLOJURE_HOME<br />CLOJURE=$CLJ_DIR/clojure.jar<br />CONTRIB=$CLJ_DIR/clojure-contrib.jar<br />JLINE=$CLJ_DIR/jline-0_9_5.jar<br />CP=$PWD:$CLOJURE:$JLINE:$CONTRIB<br /><br /># Add extra jars as specified by `.clojure` file<br />if [ -f .clojure ]<br />then<br /> CP=$CP:`cat .clojure`<br />fi<br /><br />if [ -z "$1" ]; then<br /> java -server -cp $CP \<br /> jline.ConsoleRunner clojure.lang.Repl<br />else<br /> java -server -cp $CP clojure.main -i $*<br />fi<br /></pre>Love the TextMate support and the history support in JLine!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com5tag:blogger.com,1999:blog-7461275049781191261.post-31475773720588571382010-02-17T11:55:00.000-08:002010-02-17T15:14:15.128-08:00Reporting from SpeakerConf 2010I was able to attend<a href="http://speakerconf.com/"> speakerconf 2010</a> this year in Aruba. It was an amazing gathering of talented leaders in the software development space. Each day of the conference started with several 15 – 30 minute talks lasting roughly 3 hours. According to the retro at the end of the conference, most people enjoyed and preferred these short talks as a primer to longer conversations in the afternoon along the pool or beach. Most talks were met with the struggle to maintain time often due to the many follow on questions generated by the subject. As far as I know the subjects were selected by the speaker and they were generally not preannounced. It is impossible to capture the essence of the conference and I make no effort to cover the most valuable part of it… the evening free form discussions. Most of the information went so fast that it was difficult to mentally be engaged and take notes. Here is a glimpse of what was discussed.<br /><br /><span style="font-weight: bold;">Day 1</span><br /><a href="http://thinkrelevance.com/team"><span style="font-weight: bold;">Stu Halloway</span></a><br />Stu introduced the ADD development… which is alcohol driven. Stu then jumped into clojure, introducing a private testing project he is working on called circumspect. Stu offered up some advice for working in clojure:<br /> * be less clever<br /> * idiomatic clojure<br /> * make adjectives not nouns<br /><br />The focus on circumspect was to provide an idiomatic testing option for functional testing in clojure. Stu mentioned that through his testing exploration that an test he created actually detected a bug in the clojure code.<br /><br /><a href="http://notdennisbyrne.blogspot.com/"><span style="font-weight: bold;">Dennis Byrne</span></a><br />Dennis is the first to discuss a topic on hardware and general process constraints in a talk titled Memory Barriers. The challenge is that virtual machines and hardware interfaces reorder code in ways most developers are not aware of. Fences or memory barriers define for the VM what can and can’t be reordered. There was some discussion on the expensive nature of these barriers.<br /><br /><a href="http://www.theagiledeveloper.com/"><span style="font-weight: bold;">Matt Deiters</span></a><br />Matt introduces a challenging problem that he has been working on in a story about vertex. The problem stems from social network analysis… it doesn’t work in SQL. Their previous implementation in SQL might take an hour to find all the details need for just 2 degrees of separation in a social network. Matt introduces <a href="http://neo4j.org/">neo4j</a> an open source nosql graph database and <a href="http://github.com/mdeiters/neo4jr-simple">neo4jr-simple</a>, which is a RESTful ruby API. I enjoyed the fact that Matt wasn’t a No SQL bigot… He espoused a “Not all SQL” approach, using alternatives where SQL databases fall down.<br /><span style="font-weight: bold;"><br />Fred George</span><br />Fred displayed a triangle with management, story and programmers (or workers) at the vertexes. He wanted to focus on the relationship of the story to the programmer. Fred focuses on a Lean process and raises the question if acceptance tests are really lean? This stirred some debate. In the end, It appeared to me that what was being argued in most cases was the definition of acceptance tests vs. other types of tests. I don’t know if I agreed with Fred’s position, which we discussed at length the rest of the conference. My favorite part of his talk was a list of words or phrases that are flags that your project isn’t Agile. They include: Review, I need it in writing, write me a ticket, plan, checklist, code freeze, gant chart.<br /><br /><a href="http://www.briangoetz.com/"><span style="font-weight: bold;">Brian Goetz</span></a><br />Brian’s talk is on how we find ourselves in this mess with multi-cores. Brian gives a wonderful history of processors defining them in eras: CISC era, RISC era, and Multi-Core era. The big take-aways for me include:<br /> * a move from explicit to implicit parallelism<br /> * moore’s law favors bandwidth over latency<br /> * cost of memory access<br /><br />With the speed of today’s processors, it takes 200-300 clock cycles to get 1 memory fetch, where it used to be 1 cycle. As latency increases we need more caches. Memory access times by clock cycle are roughly:<br /> * Register ~ 1 cycle<br /> * L1 ~ 3<br /> * L2 ~ 15<br /> * RAM ~ 200 – 300<br /><br />Brian states “Memory is the new disk”. Clearly memory access is the new problem to solve in computer hardware. Brian also states that there is no programming model for this new multi-core era. Based on the talk, it appears to be that the industry has a new chicken or the egg problem. Hardware is struggling to evolve, because there is no software development model. Software is struggling because there isn’t a new standard. Brian concludes with latency is the enemy and the industries need to provide development teams with new tools. There will be a growing need to understand the memory access model of a running program, which can only be determined at run-time at the chip level. It will be necessary to understand the Integer pipe and memory cache misses. At the end of Brian’s talk, Nygard mentioned Chuck Moore’s Multi-Core chip where each core runs a tiny forth program. It is something I’ve added to the list of things to look into.<br /><br /><a href="http://www.michaelfeathers.com/"><span style="font-weight: bold;">Michael Feathers</span></a><br />Michael discusses challenges to object oriented and functional language hybrids. There is background that I didn’t record, but one of the great observations is that functional programming is a “tell, don’t ask” model and object oriented programming is a “ask, don’t tell” model. In the FP approach, programming logic and data seem to bubble up the call tree and in the OO approach the opposite is true, logic seems to be pushed down the tree. Michael then looks at what it looks like conceptually if FP is on top of OO or OO is on top of FP. Michael then introduces the group to an algorithm used to solve <a href="http://cmm.ensmp.fr/%7Ebeucher/wtshed.html">morphological watersheds</a> :)<br /><br /><span style="font-weight: bold;">Day 2</span><br /><a href="http://steve.vinoski.net/blog/"><span style="font-weight: bold;">Steve Vinoski</span></a><br />Steve introduced us to a product his startup company <a href="http://www.verivue.com/">Verivue</a>, Inc is producing for the big media companies for streaming video. The IO throughput numbers were unbelievable. The software at the core of the product… Erlang!<br /><br /><a href="http://obiefernandez.com/"><span style="font-weight: bold;">Obie Fernadez</span></a><br />Obie and Desi introduced us to the agile practices of Hashrocket, indicating that they have evolved past iterations and they question the value added by iteration activities. They develop in one-week windows and use <a href="http://www.pivotaltracker.com/">Pivotal Tracker</a> for tracking stories and progress. The term “Iteration” isn’t even in their vocabulary. Later in the week, I challenged Obie to see if the word “week” replaces the word “iteration” as a convenience and to see if they were doing all things an ”iteration” would entail. The short answer is No! Clearly pivotal tracker desires a good look. Another tool Obie mentioned later in the week was <a href="http://www.balsamiq.com/">Balsamiq</a>... a tool used for screen mocking. Yet another tool to checkout.<br /><br /><a href="http://ph7spot.com/"><span style="font-weight: bold;">Phillip Hanrigou</span></a><br />Phillip starts with the phrase “any sufficiently advance technology should feel like magic”. He continues with the fact that 30% of Amazon’s sales is based on recommendations. This was an interesting talk that had me flashing back to Matt’s talk on neo4j looking for synergies.<br /><br /><a href="http://ayende.com/blog/"><span style="font-weight: bold;">Oren Eini</span></a><br />Oren suggests that TDD doesn’t scale… with a beautiful picture of a motorcycle with training wheels. The major point is that unit tests are bad and scenario based tests are good.<br /><br /><a href="http://www.exampler.com/"><span style="font-weight: bold;">Brian Marick</span></a><br />The take away… “I don’t want to care about anything until I absolutely have to care about it”… Love it!<br /><br /><a href="http://www.davethomas.net/"><span style="font-weight: bold;">Dave Thomas</span></a><br />Dave introduces us to vector functional languages such as KDB and k. These specialized languages are the workhorses behind querying ½ terabyte of data in 1 second for the hedge fund industry. Dave claims this is the most interesting technology to come along in 25 years. If interested, he suggests getting started with <a href="http://jsoftware.com/">j from jsoftware.com</a><br /><br /><a href="http://www.linkedin.com/in/ericyew"><span style="font-weight: bold;">Eric Yew</span></a><br />Eric gives us a deep dive into GPUs. He was on the NVidia team that built the technology. Eric suggests that GPUs are making the industry rethink previous assumptions that are not correct in the GPU world. How would we code differently if:<br /><ol><li>There were no costs to threads</li><li>And no costs to context switching</li></ol>The approach suggests that memory lookup is too expensive (seems like we keep hearing this :). It is cheaper to recalculate a value on a 100 threads then to retrieve from memory.<br /><br />This model supports scale and throughput and not latency. Latency once again is sacrificed.<br /><br />The memory model is upside down as well from the traditional general processors. There are 3 memory access points:<br /><ol><li>global - ~ 100 cycles to get to it</li><li>shared</li><li>local – stacks</li></ol>It appears that the old paradigm of being abstracted from the hardware is over. The benefit is that the price of 2 Teraflops is near nothing… thank you computer gaming community!<br /><br /><span style="font-weight: bold;">Day 3</span><br /><a href="http://www.nealford.com/"><span style="font-weight: bold;">Neal Ford</span></a><br />Neal did a wonderful job presenting a presentation on presentation :) at a conference on conferences… it was a very meta way to start the morning. The big take away is <a href="http://presentationpatterns.com/">http://presentationpatterns.com/</a> a site and forth-coming book on presentation styles, techniques and anti-patterns. The biggest benefit of the book is its focus on the practical. It will include templates for good practices.<br /><br /><a href="http://pandamonial.grahamis.com/"><span style="font-weight: bold;">Amanda Laucher</span></a><br />Amanda starts by defining the classifications of assholes and morons which got a lot of mileage the rest of the day. Amanda focused on educating us on terminologies in the category theory space with examples in F#. Here was what I was able to capture:<br /><br /> * Catamorphism - a fold<br /> * Anamorphism – unfold<br /> * Endomorphis – takes a type and returns the same type<br /> * Homomorphism – takes a structure and returns the same structure or shape<br /> * Monoid – A Functor<br /> * Monad – Applied context<br /> * A Monad is a monoid in the category endofunctors<br /><br /><a href="http://redsquirrel.com/dave/"><span style="font-weight: bold;">Dave Hoover</span></a><br />Dave discussed the value of <a href="http://github.com/defunkt/resque">Resque</a> and how it help in the development of Groupon.com<br /><br /><a href="http://nutrun.com/"><span style="font-weight: bold;">George Malamidis</span></a><br />George continues the conversation on memory access times and threads, introducing us to <a href="http://nodejs.org/">Node.js</a> as a high scale solution for the web.<br /><br /><a href="http://www.michaelnygard.com/blog/"><span style="font-weight: bold;">Michael Nygard</span></a><br />Thoughts on consistency – what a great talk! Michael introduces the concept of an observer and a super observer in a system through an object lesson. He then follows it up with the fact that with in a database there are often inconsistent states… the point is at the end of a transaction there cannot be any inconsistent states. For example, it is possible that an insert into the database would result in a violation of referential integrity… this is ok and necessary until a commit occurs.<br /><br />Consistency is based on time. Frozen time means no change.<br /><br />Another practical example:<br />2 ebay users making the same query at roughly the same time get different query results. This is viewed as being ok, because from the perspective of the observer it is consistent (they have no idea). From the perspective of a super observer there are some inconsistencies. This led to some discussion in mainly of the corporate failures stemming from the complexity created when trying to maintain consistency from the perspective of a super observer (which is a fallacy and trap).<br /><br /><a href="http://blog.aslakhellesoy.com/"><span style="font-weight: bold;">Aslask Hellesoy</span></a><br />Another agile talk… this one focused on visualization of the return on development through CFD graphs. The suggestion was that velocity is a questionable valuation.<br /><br />References included: <a href="http://bit.ly/3bCNtZ">CFD Details</a> and a <a href="http://bit.ly/bBtRc2">google spreadsheet</a><br /><a href="http://www.objectmentor.com/omTeam/martin_r.html"><span style="font-weight: bold;">Robert Martin</span></a><br />I don’t think you can summarize Uncle Bob… you have to experience him :)<br /><br /><br /><span style="font-weight: bold;">Summary</span><br />I made a couple of interesting observation / assessments through the conference. The first is there was a large percentage of the speakers / attendees that had a strong EE background. I truly enjoyed revisiting challenges at this level again.<br /><br />Here are some of my takeaways from the conference:<br /><ol><li>We are at the beginning of a new era in field of computing. One in which we do not have a standardize model or tools</li><li>There is a need for programming solutions which reduce (or leak) the abstraction from the memory model that is generally preferable in the previous programming model. It will be necessary to indicate that values in memory are near, far or very far. It will be necessary to be able to measure and understand the cache miss rate.</li><li>We appear to be at our limits in our pursuit to improve latency. Worse…. Latency is the component that is consistently sacrificed to increase throughput.</li></ol>Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com5tag:blogger.com,1999:blog-7461275049781191261.post-36172056264924653432010-01-05T09:11:00.000-08:002010-01-05T11:05:34.041-08:00IDEA 9, Gradle and Eating Your Own DogfoodAfter reading the comment on a post a few weeks ago regarding <a href="http://kensipe.blogspot.com/2009/12/intellij-9-and-gradle.html">Intellij 9 and Gradle</a>, I had to laugh. Having worked on open source projects for 15+ years and presenting at countless conferences and user groups, I have stated roughly the same comment countless times... "It's open source, if you don't like it or you want a change, then do it!". Thanks to Peter for the suggestion and encouragement. It clearly seems that my actions were a surprise as Peter's first comment in a private email exchange was "Great you're doing this!"<br /><br /><span style="font-weight: bold;">Intellij 9 Development Experience</span><br />Getting the source and setting up for the first run was fairly painless after you find the <a href="http://www.jetbrains.org/pages/viewpage.action?pageId=983225">download information</a>. It was nice to see that the code repository was git. I ran into 2 issues in getting setup:<br /><ol><li>Git clone failed with an unclear message initially. It turned out I was trying to clone using the git protocol behind a corporate firewall which was blocking it. As soon I was not behind the firewall, all went well. Be prepared... it is 924 MB.</li><li>Setting up the run configuration wasn't complex, but it wasn't as advertised.</li></ol><br />Here is what the <span style="font-weight: bold;">Building and Running from the IDE</span> from the checkout and build page should read:<br /><ul><li>Open the project as a "new" directory-based project</li><li>Configure a JSDK named "IDEA jdk", pointing to an installation of either JDK 1.6 (recommended) or JDK 1.5. This is on the project tab of the project structure.</li><li>Increase the compiler heap size... default is 128M, it works with 512M :)</li><li>Use Build | Make Project to build the code</li><li>To run the code, use the provided shared run configuration "IDEA".</li></ul><br />Important notes:<br /><ol><li>You will see that there are circular dependencies between 4 of the project modules.</li><li>With the default compiler heap size, you will get a compilation error ( which is erroneous )</li><li>There are a number of deprecation warnings during compilation... this might be a great place for someone to get involved and do some clean up.</li></ol><br />After you have an Intellij running another instance of Intellij :) Here is a list of resources to be familiar with:<br /><ol><li><a href="http://www.jetbrains.org/display/IJOS/Source+Repository+Layout">Source Repository Layout</a></li><li>View PSI structure (under the tool menu) - PSI is an IDEA AST abstraction, which was the toughest learning curve. Learn it! Then look at the following clases and their usage in the code base: PsiUtilBase, PsiUtil, PsiResolveHelper, PsiResolveHelperImpl</li></ol><br /><span style="font-weight: bold;">End Result</span><br />In the end, I spent 4 hours adding in additional gradle task support into Intellij 9, created a patch and submitted to Peter... a few days later I was informed that it was committed to repository. Enhanced Gradle support is on it's way!<br /><br />I had mixed feels when IDEA announced it was going open source, but now that it is... Let's get in there and make this an even better editor!<br /><br />Kudos to JetBrains and it's community!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com8tag:blogger.com,1999:blog-7461275049781191261.post-84598534767489131862009-12-31T18:40:00.000-08:002010-02-21T22:00:56.861-08:003 Core Principles from 1998I was off for the holidays which gave me some time to clean out the storage area. I ran across some notes from a conference I attended in 1998 and 3 core principles stood out that I thought I would share as we start this new year.<br /><br />Core Principles (as I wrote them many years ago):<br />1. Smaller is better than larger<br />2. Understood is better than unknown<br />3. Progress is better than promises<br /><br /><span style="font-weight: bold;">Smaller is better than larger</span><br />There was nothing else written and I left nothing by way of context... regardless of what it meant then, it is clear that this is a great principle when it comes to code. Less code that does the same amount of work is better. The paradox is that it may take a little more time to develop a smaller code solution, but it pays off. The skill is in not being so abstract and so small as to not be readable or maintainable. It is this balance that makes a true software craftsman.<br /><br /><span style="font-weight: bold;">Understood is better than unknown</span><br />If there is one word that we would use to describe the issues of software development... it is the word "unknown". Estimating the known is easy. Estimating the unknown, is unknowable. The skill in software development is to separate the unknowns from the knows. Estimate the knowns and provide a SWAG estimate for the unknowns... these are estimates that you need to keep in check. It is best to delay the estimates and work of the unknowns until ( what <a href="http://en.wikipedia.org/wiki/Kevlin_Henney">Kevlin Henney</a> brilliantly describes as) the last responsible moment. Of course this only works for the known unknowns... what will get you is the unknown unknowns:)<br /><br /><span style="font-weight: bold;">Progress is better than promises</span><br />This is why I have been a practitioner and trainer for XP and agile practices for many years. It is all about developing business value on a regular and iterative basis. Promises are meaningless... progress is all that matters.<br /><br />Happy New Year!!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com5tag:blogger.com,1999:blog-7461275049781191261.post-79729195812716679652009-12-14T14:18:00.000-08:002009-12-14T15:14:39.419-08:00Intellij 9 and GradleOne of the hidden gems of the Intellij 9 release is it's support for Gradle. Some of the information on the web is out of date and some features are not intuitive. This post will detail some of the nuances and follow it up with a wish list for the next update :)<br /><br /><span style="font-weight: bold;">Gradle Support</span><br />The <a href="http://blogs.jetbrains.com/idea/2009/08/gradle-support/">information from JetBrains</a> is out of date. In order to setup gradle after the GA release, all you need to do is configure the gradle home under File -> Other Settings -> Template Setttings.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUOsn0bqVQDH-4OSHeLPbZ3KHNLuamS67BBsLD_6DExDLTvGPGeORU9L1hUNNG9TbxntXzJz33g7Jb_KB7uo1RKvyV9lR5S736iaoEY0Yl5Mi740axeJlPMxq65AwPF4WdoRU8jGS6XNI/s1600-h/Screen+shot+2009-12-14+at+Dec+14+-+4.24.43+PM.png"><img style="cursor: pointer; width: 320px; height: 88px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUOsn0bqVQDH-4OSHeLPbZ3KHNLuamS67BBsLD_6DExDLTvGPGeORU9L1hUNNG9TbxntXzJz33g7Jb_KB7uo1RKvyV9lR5S736iaoEY0Yl5Mi740axeJlPMxq65AwPF4WdoRU8jGS6XNI/s320/Screen+shot+2009-12-14+at+Dec+14+-+4.24.43+PM.png" alt="" id="BLOGGER_PHOTO_ID_5415221547032857442" border="0" /></a><br /><br /><span style="font-weight: bold;">Gradle Intellij Nuances</span><br />After setting up IDEA to work with Gradle, you'll need a build file. I didn't discover a way to create a gradle build file from IDEA. Just create a new file and name it "build.gradle" in the root of the module directory structure.<br /><br />When writing the build script, Intellij expects to work with gradle in a way that is depreciated. It will pick up on a createTask(..) method. If the cursor is on a task such as this, and you hit ctrl+shft+F10, it will auto-discover and run that task in the script. (cool stuff)<br /><br />Hotkeys to know:<br />ctrl+shft+F10 - runs task the cursor is on<br />shft+F10 - runs the last script (or the last run)<br />alt+shft+F10 - pops up a run menu (with all previously run gradle run configs)<br /><br />The figure below shows an alt+shft+F10 when the cursor is on a task called task2.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV5mRflsrLTzYRcQImmlCTvGyKy0KpoOyfvz_aV2EDwpxNVqrsrteHaUVcqPjm41AoFoUthMXd4Vvyav27ThtC3Pt7kXuwkJfgB4XhMNOiXMT23X24K2sxkMlavmr3YzQvC7COkM9aGNQ/s1600-h/Screen+shot+2009-12-14+at+Dec+14+-+4.39.30+PM.png"><img style="cursor: pointer; width: 194px; height: 184px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV5mRflsrLTzYRcQImmlCTvGyKy0KpoOyfvz_aV2EDwpxNVqrsrteHaUVcqPjm41AoFoUthMXd4Vvyav27ThtC3Pt7kXuwkJfgB4XhMNOiXMT23X24K2sxkMlavmr3YzQvC7COkM9aGNQ/s320/Screen+shot+2009-12-14+at+Dec+14+-+4.39.30+PM.png" alt="" id="BLOGGER_PHOTO_ID_5415225458400123138" border="0" /></a><br /><br />If you code gradle in a non-depreciated way... then IDEA does not auto-discover the tasks. Below is what one would expect in a gradle build file:<br /><pre class="brush: groovy"><br />usePlugin 'java'<br /><br />repositories {<br />mainCentral()<br />}<br /><br />// from the gradle user guide<br />// http://www.gradle.org/0.8/docs/userguide/tutorial_using_tasks.html<br />task hello << { <br /> println 'Hello world' <br />} <br />task intro(dependsOn: hello) << { <br /> println "I'm Gradle" <br />} <br /></pre><br />Tasks would normally be created this way... It is still great that IDEA has gradle support in general regardless of this oversight. After a run configuration is configured with a targeted task, it worlds with no pain. Also you could add:<br /><pre class="brush: groovy"> defaultTasks "intro"</pre>and gradle runs this as the fallback when IDEA doesn't provide the required task.<br /><br /><span style="font-weight: bold;">Intellij / Gradle features</span> I'm looking forward to:<br /><ol><li>IDEA understands proper task configuration</li><li>IDEA makes it easy to create new projects with a structure maven and gradle expects.</li><li>IDEA treats gradle as a peer with Maven and Ant. This includes:<br />a. Gradle Window (similar to the ant build and maven projects panels)<br />b. Before Launch Gradle tasks in the run configurations<br /></li><br /></ol>Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com4tag:blogger.com,1999:blog-7461275049781191261.post-38451584352401362422009-12-05T20:04:00.000-08:002009-12-05T20:21:55.073-08:00More Trouble with Java and AppleWell the latest update for Java from Apple came through recently. Destroying all in its path...<br />If you followed my <a href="http://kensipe.blogspot.com/2009/09/fixing-java-on-mac-snow-leopard.html">advice in the past </a>on getting Java 1.5 working on a Snow Leopard, then the new Apple update destroys that with the follow error for a Java 5 java -version:<br />Error occurred during initialization of VM<br />Unable to load native library: libjava.jnilib<br />Abort trap<br /><br />I didn't track down the exact issue... however it is easy to detect that the Java update converts the symbolic links for Java 1.5 to point back to Java 6... Apparently Apple is NOT sorry for their crazy choice of ignorantly doing this in the first place. The solution is to completely go through the process out lined at <a href="http://wiki.oneswarm.org/index.php/OS_X_10.6_Snow_Leopard">OneSwarm</a> again and re-establish the symbolic links. This will require you to delete the symbolic links that point to "CurrentJDK" for 1.4, 1.4.2, 1.5, and 1.5.0.<br /><br />After edits an ls -l in the /System/Library/Frameworks/JavaVM.framework/Versions should look like:<br /><pre class="brush: bash"><br />drwxr-xr-x 15 root wheel 510 Dec 5 22:18 .<br />drwxr-xr-x 12 root wheel 408 Dec 5 22:15 ..<br />lrwxr-xr-x 1 root wheel 5 Dec 5 21:35 1.3 -> 1.3.1<br />drwxr-xr-x 3 root wheel 102 Jul 20 18:35 1.3.1<br />lrwxr-xr-x 1 root wheel 5 Dec 5 22:18 1.4 -> 1.4.2<br />lrwxr-xr-x 1 root wheel 14 Dec 5 22:18 1.4.2 -> 1.4.2-leopard/<br />drwxr-xr-x@ 9 root wheel 306 Feb 12 2009 1.4.2-leopard<br />lrwxr-xr-x 1 root wheel 5 Dec 5 22:01 1.5 -> 1.5.0<br />lrwxr-xr-x 1 root wheel 14 Dec 5 22:00 1.5.0 -> 1.5.0-leopard/<br />drwxr-xr-x@ 10 root wheel 340 Dec 5 21:59 1.5.0-leopard<br />lrwxr-xr-x 1 root wheel 5 Dec 5 21:35 1.6 -> 1.6.0<br />drwxr-xr-x 8 root wheel 272 Nov 8 14:35 1.6.0<br />drwxr-xr-x 9 root wheel 306 Dec 5 21:35 A<br />lrwxr-xr-x 1 root wheel 1 Dec 5 21:35 Current -> A<br />lrwxr-xr-x 1 root wheel 3 Dec 5 21:35 CurrentJDK -> 1.6<br /></pre><br /><br />Happy coding!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com3tag:blogger.com,1999:blog-7461275049781191261.post-20472398912301515852009-11-27T13:03:00.000-08:002009-11-27T13:20:04.955-08:00Syntax Highlighting on BlogspotI've been very interested in providing some syntax highlighting in my blog posts, which I've been slow in general getting out... ( I have 6 or so queued up ). I finally found something I like and thought I would share the love. Special thanks to @ecounysis on twitter from whom I made this discovery. There are no excuses for my future posts... they will all have nice highlighting and be more easily copied (via the clipboard feature).<br /><br />The place to start is: <a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter:Hosting">http://alexgorbatchev.com/wiki/SyntaxHighlighter:Hosting</a><br /><br />From there you'll see the link to: <a href="http://blog.cartercole.com/2009/10/awesome-syntax-highlighting-made-easy.html">http://blog.cartercole.com/2009/10/awesome-syntax-highlighting-made-easy.html</a><br /><br />One important thing to note for those on blogger / blogspot. The initial update of the head tag didn't take for me. The solution for me was to add the highlighting entries at the tail end of head, just prior to the closing tag.<br /><br />In addition to many of the bundled options... I've added F# and Objective-C from <a href="http://www.undermyhat.org/blog/2009/09/list-of-brushes-syntaxhighligher/">undermyhat</a>.Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com1tag:blogger.com,1999:blog-7461275049781191261.post-21952779670200144812009-09-03T13:55:00.000-07:002009-11-27T12:49:11.269-08:00Fixing Java on Mac Snow LeopardI have long documented some of the issues and differences for a Java developer on the Mac OS X. Most of that has been on Leopard, OS X 10.5. For quick links the most significant articles are: <a href="http://kensipe.blogspot.com/2009/01/java-is-2nd-class-citizon-on-mac-osx.html">Java is a 2nd Class Citizen on MAC OSX</a>, <a href="http://kensipe.blogspot.com/2008/08/fixing-java-memory-tools-on-mac-os-x.html">Fixing Java Memory Tools on Mac OS X</a> and <a href="http://kensipe.blogspot.com/2009/02/java-7-on-mac-os-x.html">Java 7 on Mac OS X</a>.<br /><br />Monday I was faced with a new situation, Snow Leopard OS X 10.6. There are several issues with Java on the new Mac OSX 10.6 "Snow Leopard". This post will outline the known issues and will provide fixes for several of them (or provide links where fixes are already explained).<br /><br /><span style="font-weight: bold;">Known Issues:</span><br /><ol><li> Java 5 is not installed</li><li> Java 5 symbolic links are set to Java 6</li><li> jmap - some aspects of jmap do not function</li><li>javascript runtime is still missing</li></ol>As a consequence, applications that used Java 5 either don't work, or provide a message as shown here from my favorite stock trading application.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBUkmVYWPwiY4nudM24QF3wHWKcakY3GKy8f4JIpN8z-tK4f9oRVDeH4FcKRmoBNY6dUqqEvwB09zbmKQLDEWQGX1dLvQhq4YZF2rfWkn5HNkK6ptkxB__H2OXifGfF34EysRlxRW-2B4/s1600-h/Screen+shot+2009-09-02+at+Sep+2+-+9.32.12+AM.png"><img style="cursor: pointer; width: 320px; height: 170px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBUkmVYWPwiY4nudM24QF3wHWKcakY3GKy8f4JIpN8z-tK4f9oRVDeH4FcKRmoBNY6dUqqEvwB09zbmKQLDEWQGX1dLvQhq4YZF2rfWkn5HNkK6ptkxB__H2OXifGfF34EysRlxRW-2B4/s320/Screen+shot+2009-09-02+at+Sep+2+-+9.32.12+AM.png" alt="" id="BLOGGER_PHOTO_ID_5377350507583912962" border="0" /></a><br /><br />* I'm still looking for more issues, so if you can add to the list, please add comments, email or twitter.<br />** I have tested the latest BTrace and it works fine.<br /><br /><br /><span style="font-weight: bold;">Java 5 on Snow Leopard</span><br />Whither you agree with the removal of Java 5 or not, it is unbelievable to me that the Java 5 symbolic links are pointing to the CurrentJDK which points to 1.6. For those new to this space the Java version live under /System/Library/Frameworks/JavaVM.framework/Versions . I would advise you to either:<br /><ol><li> replace Java 5 using instructions provided at <a href="http://wiki.oneswarm.org/index.php/OS_X_10.6_Snow_Leopard">leopard http://wiki.oneswarm.org/index.php/OS_X_10.6_Snow_Leopard</a></li><li>simply delete the java 5 symbolic links<br /></li></ol>As a side note, I use a script for swapping between JVM versions. I modified the <a href="http://homepage.mac.com/shawnce/misc/java_functions_bashrc.txt">original script</a> to just include 3 important functions when sourced in. I'll add the script to the bottom of this post as a reference. The 3 functions are jvms, setJava, unsetJava.<br /><ul><li>jvms reads through the version directory and reports what it reads of the file system. </li><li>setJava allows you to type in the name of the version and switches JAVA_HOME and path to this version of the JVM.</li><li>unsetJava reverts the set to the original java version<br /></li></ul><span style="font-weight: bold;">JMap on Snow Leopard</span><br />My initial execution of jmap on snow leopard failed with the following error message:<br /><pre><br />kensipe$ jmap 3407<br />Attaching to process ID 3407, please wait...<br />sun.jvm.hotspot.debugger.NoSuchSymbolException: Could not find symbol "heapOopSize" in any of the known library names (-)<br /> at sun.jvm.hotspot.HotSpotTypeDataBase.lookupInProcess(HotSpotTypeDataBase.java:399)<br /> at sun.jvm.hotspot.HotSpotTypeDataBase.readVMIntConstants(HotSpotTypeDataBase.java:319)<br /> at sun.jvm.hotspot.HotSpotTypeDataBase.<init>(HotSpotTypeDataBase.java:88)<br /> at sun.jvm.hotspot.MacOSXTypeDataBase.<init>(MacOSXTypeDataBase.java:36)<br /> at sun.jvm.hotspot.bugspot.BugSpotAgent.setupVM(BugSpotAgent.java:578)<br /> at sun.jvm.hotspot.bugspot.BugSpotAgent.go(BugSpotAgent.java:499)<br /> at sun.jvm.hotspot.bugspot.BugSpotAgent.attach(BugSpotAgent.java:337)<br /> at sun.jvm.hotspot.tools.Tool.start(Tool.java:163)<br /> at sun.jvm.hotspot.tools.PMap.main(PMap.java:67)<br /> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br /> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br /> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br /> at java.lang.reflect.Method.invoke(Method.java:597)<br /> at sun.tools.jmap.JMap.runTool(JMap.java:179)<br /> at sun.tools.jmap.JMap.main(JMap.java:110)<br />Debugger attached successfully.<br /></pre><br />The good news is that the debugger attached successfully :)<br /><br />Information regarding this issue is scarce. It turns out to likely be an issue with the version of Java that is distributed with snow leopard. The JDK 1.6 rev 14 appears (based on non-confirmed web sources) to have this issue. The latest is JDK 1.6 rev 16 should have the fix, however using the apple distro, we are left waiting for Apple for the fix. Although jmap fails with no arguments it does succeed for certain commands such as jmap -histo 3407.<br />After replacing the JDK 5 with the leopard distro as advertised above and switching to this version with the script above, jmap works fine. However jdk 5 jmap only works against jdk 5 running applications. It fails against java 6.<br /><br /><span style="font-weight: bold;">javascript</span><br />As record in a posting from a year ago, called <a href="http://kensipe.blogspot.com/2009/02/fixing-btrace-on-mac.html">Fixing Java Memory Tools on Mac OS X</a>, the javascript library is still not provided by Apple as part of the Java distro. You will need to following the instructions there to fix it. Unfortunately the Rhino download has disappeared from the Mozilla site, so if you didn't keep a copy, ping me and I will send you want I have. You will also need to duplicate this for each version of Java if you install the Java 5 Leopard package.<br />The test to see if this is setup correctly for you is: jrunscript -q<br />If that command only returns AppleScript, then you are missing the javascript engine which is need for a number of tools in the JDK.<br /><br />After these changes, it appears that Snow Leopard is ready for some hard core Java development. Good Luck and Happy Coding!<br /><br />Java Switching Script that I use:<br /><br /><pre class="brush: bash"><br /><br /># *************************************************************************<br /># Originally written by Shawn Erickson - shawn at freetimesw.com<br />#<br />#<br /># Last Update: 2008y 08m 8d<br />#<br /># The following functions are meant for use with bash shell which is currently the<br /># default on Mac OS X 10.4 (starting with 10.3 IIRC) unless otherwise configured.<br /># Good info on why not sym links: http://lists.apple.com/archives/Java-dev/2006/Jan/msg00290.html<br />#<br /># from: http://lists.apple.com/archives/Java-dev/2005/Aug/msg00506.html<br /># http://homepage.mac.com/shawnce/misc/java_functions_bashrc.txt<br />#<br /># *************************************************************************<br /><br />### Prompt ###<br /><br />export CURRENT_MODE_STRING="";<br /><br />### Java Environment Functions ###<br /><br />J_VERSIONS_DIRECTORY="/System/Library/Frameworks/JavaVM.framework/Versions"<br />J_COMMANDS_SUBPATH="Commands"<br />J_HOME_SUBPATH="Home"<br /><br />function availableJVMs()<br />{<br /> ls -1 $J_VERSIONS_DIRECTORY | grep ^[0-9].[0-9]<br />}<br /><br />function jvms()<br />{<br /> clear<br /> echo "Available JVMs: "$jvms<br /> ls -1 $J_VERSIONS_DIRECTORY | grep ^[0-9].[0-9] # look to remove redundant call<br /> echo " "<br /><br /> echo "Current Java:"<br /> java -version<br />}<br /><br />function setJava()<br />{<br /> local target_jvm=""<br /> local jvms=$(availableJVMs)<br /><br /> # Validate that the user requested an available JVM present on the system<br /><br /> for jvm in $jvms ; do<br /> if [ "$jvm" == "$@" ]; then<br /> target_jvm=$@ <br /> fi<br /> done<br /><br /> if [ "$target_jvm" == "" ]; then<br /> echo "Unsupported Java version requested"<br /> return;<br /> fi<br /><br /> # If we get here the user asked for a valid JVM, so configure it<br /><br /> echo "Configuring Shell Environment for Java "$@<br /> export JAVA_VERSION=$@<br /><br /> # First unset any current set java, back to default before doing configuration<br /> _unsetJava<br /><br /> # Generate the paths needed for the JVM requested<br /> local jcmd="${J_VERSIONS_DIRECTORY}/$@/${J_COMMANDS_SUBPATH}"<br /> local jhome="${J_VERSIONS_DIRECTORY}/$@/${J_HOME_SUBPATH}"<br /><br /> # We save the original path so we can toggle back if unset<br /> ORIGINAL_PATH="$PATH"<br /> PATH="$jcmd:${PATH}"<br /><br /> # We save the original JAVA_HOME so we can toggle back if unset<br /> ORIGINAL_JAVA_HOME="$JAVA_HOME"<br /> JAVA_HOME="$jhome"<br /><br /> # Update command prompt mode tag to note JVM setting<br /> CURRENT_MODE_STRING="J$@"<br /><br /> echo "Current Java:"<br /> java -version<br />}<br /><br />function _unsetJava()<br />{<br /> if [ "$CURRENT_MODE_STRING" != "" ]; then<br /> PATH="$ORIGINAL_PATH"<br /> JAVA_HOME="$ORIGINAL_JAVA_HOME"<br /> CURRENT_MODE_STRING=""<br /> fi<br />}<br /><br />function unsetJava()<br />{<br /> echo "Configuring Shell Environment for default Java"<br /> _unsetJava<br /><br /> echo "Current Java:"<br /> java -version<br />}<br /></pre><br /><br /></init></init>Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com68tag:blogger.com,1999:blog-7461275049781191261.post-67551472721081604402009-08-19T12:14:00.000-07:002009-08-19T12:36:44.221-07:0097 Things Every Project Manager Should Know<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2F30f6ouuwDN-ONeb58Kz9IjljBssPN4KibNFBftq0I7igqqEfqGWIikvWiNvWMZudJgYsbrvb1u3kTGs8L1JDIq1icVuz-HjYRmk46GYcuoFcg1P-AZ-ztWBE7GLjzsvZXEaopvZ5eA/s1600-h/Untitled1.png"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 220px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2F30f6ouuwDN-ONeb58Kz9IjljBssPN4KibNFBftq0I7igqqEfqGWIikvWiNvWMZudJgYsbrvb1u3kTGs8L1JDIq1icVuz-HjYRmk46GYcuoFcg1P-AZ-ztWBE7GLjzsvZXEaopvZ5eA/s320/Untitled1.png" alt="" id="BLOGGER_PHOTO_ID_5371760659684397778" border="0" /></a><br />The book <a href="http://www.amazon.com/Things-Every-Project-Manager-Should/dp/0596804164/ref=sr_1_1?ie=UTF8&s=books&qid=1250709164&sr=8-1"><span style="font-style: italic;">97 Things Every Project Manager Should Know</span></a> put together by Barbee Davis is out, and worth picking up... why the magical 97? Apparently 101 was way over used... or perhaps Barbee couldn't get the last 4 in before it was time to publish :)<br /><br />This book has some great insights from a number of sources, which is a huge value add to any project manager or senior developer. This is the top advice from experts in the field around team building, running a software project, and generally how to herd cats.<br /><br />Most books in this space are limited to the experience of the author and his/her circle of influence. The beautiful part of this book, is the fact that Barbee has captured the most interesting and important tid bits stories of success and failures of software projects from a large sample of project managers and developers each providing a view from different industry verticals.<br /><br />Well done Barbee!Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com0tag:blogger.com,1999:blog-7461275049781191261.post-26572663756781444832009-07-20T08:40:00.000-07:002009-07-20T09:59:14.459-07:00Speaking at JavaZone in OsloIt's official... I will be heading to Oslo, Norway in September for <a href="http://jz09.java.no/agenda-en/">JavaZone</a>. I will be presenting Debugging your production JVM, which is talk largely focused on <a href="http://kenai.com/projects/btrace/pages/Home">BTrace</a>. Also if you didn't realize it yet... BTrace has moved to the kenai site: <a href="http://kenai.com/projects/btrace/pages/Home">http://kenai.com/projects/btrace/pages/Home</a>Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com0tag:blogger.com,1999:blog-7461275049781191261.post-59667370208590351552009-06-22T17:30:00.000-07:002009-06-22T18:20:25.015-07:00If you can't be a good speaker, be a groovy speaker<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.springone2gx.com/conference/new_orleans/2009/10/home"><img style="cursor: pointer; width: 126px; height: 126px;" src="http://www.springone2gx.com/images/2009/2gx_2009_125x125_speaker.jpg" alt="" border="0" /></a><br />I will be speaking on groovy and grails at the up coming 2GX conference in New Orleans in October. If you are in the groovy space or you are just looking, you don't want to miss this... all the big names will be there. Most of the leading authors and committers in the groovy, grails and griffon space will be there!<br /><br />How I got to be among them is beyond me... but it sure is groovy!<br /><br />My topics include security, where the focus will include defense against hacking techniques such as injection flaws and XSS, followed by a walk through of the security plugin and how to secure urls and services. The second session is on Java memory management, the memory demands of a dynamic language, along with tools on debugging Grails applications in production.Ken Sipehttp://www.blogger.com/profile/16182435829804225570noreply@blogger.com4