Posts tagged ‘Programming’

Gotta love companies that “get it”.  Late last night I was hacking away on some Android stuff using IntelliJ 9.0.2 (on Ubuntu 10.04). For reasons unknown to me, none of my breakpoints seemed to be working.  In fact, IntelliJ just didn’t seem to be working.  I narrowed it down to the breakpoints I was setting – it seemed that every time the breakpoints were being hit.  I managed to narrow it down to this error:

[ 166030]  ERROR – lij.debugger.impl.InvokeThread – null
java.lang.UnsupportedOperationException
at com.sun.tools.jdi.ReferenceTypeImpl.sourceDebugExtension(ReferenceTypeImpl.java:774)
at org.jetbrains.plugins.ruby.jruby.debug.JRubyPositionManager.getPath(JRubyPositionManager.java:141)
at org.jetbrains.plugins.ruby.jruby.debug.JRubyPositionManager.getPsiFileByLocation(JRubyPositionManager.java:156)
at org.jetbrains.plugins.ruby.jruby.debug.JRubyPositionManager.getSourcePosition(JRubyPositionManager.java:51)
at com.intellij.debugger.engine.CompoundPositionManager.getSourcePosition(CompoundPositionManager.java:51)
at com.intellij.debugger.engine.ContextUtil.getSourcePosition(ContextUtil.java:63)
at com.intellij.debugger.impl.DebuggerSession$MyDebugProcessListener$2.compute(DebuggerSession.java:462)
at com.intellij.debugger.impl.DebuggerSession$MyDebugProcessListener$2.compute(DebuggerSession.java:460)
at com.intellij.psi.impl.PsiDocumentManagerImpl$3.run(PsiDocumentManagerImpl.java:298)
at com.intellij.psi.impl.PsiDocumentManagerImpl$4.run(PsiDocumentManagerImpl.java:321)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:695)
at com.intellij.psi.impl.PsiDocumentManagerImpl.commitAndRunReadAction(PsiDocumentManagerImpl.java:317)
at com.intellij.psi.impl.PsiDocumentManagerImpl.commitAndRunReadAction(PsiDocumentManagerImpl.java:296)
at com.intellij.debugger.impl.DebuggerSession$MyDebugProcessListener.paused(DebuggerSession.java:460)
at com.intellij.debugger.engine.DebugProcessAdapterImpl.paused(DebugProcessAdapterImpl.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.intellij.util.EventDispatcher.dispatch(EventDispatcher.java:87)
at com.intellij.util.EventDispatcher.access$100(EventDispatcher.java:33)
at com.intellij.util.EventDispatcher$1.invoke(EventDispatcher.java:64)
at $Proxy84.paused(Unknown Source)
at com.intellij.debugger.engine.SuspendManagerImpl.notifyPaused(SuspendManagerImpl.java:306)
at com.intellij.debugger.engine.SuspendManagerImpl.b(SuspendManagerImpl.java:299)
at com.intellij.debugger.engine.SuspendManagerImpl.voteSuspend(SuspendManagerImpl.java:318)
at com.intellij.debugger.engine.DebugProcessEvents$1.contextAction(DebugProcessEvents.java:412)
at com.intellij.debugger.engine.events.SuspendContextCommandImpl.action(SuspendContextCommandImpl.java:62)
at com.intellij.debugger.engine.events.DebuggerCommandImpl.run(DebuggerCommandImpl.java:44)
at com.intellij.debugger.engine.DebuggerManagerThreadImpl.processEvent(DebuggerManagerThreadImpl.java:148)
at com.intellij.debugger.engine.DebuggerManagerThreadImpl.processEvent(DebuggerManagerThreadImpl.java:36)
at com.intellij.debugger.impl.InvokeThread.run(InvokeThread.java:135)
at com.intellij.debugger.impl.InvokeThread$WorkerThreadRequest.run(InvokeThread.java:52)
at com.intellij.openapi.application.impl.ApplicationImpl$5.run(ApplicationImpl.java:329)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
at com.intellij.openapi.application.impl.ApplicationImpl$1$1.run(ApplicationImpl.java:125)
[ 166036]  ERROR – lij.debugger.impl.InvokeThread – IntelliJ IDEA 9.0.2  Build #IU-95.66
[ 166036]  ERROR – lij.debugger.impl.InvokeThread – JDK: 1.6.0_18
[ 166036]  ERROR – lij.debugger.impl.InvokeThread – VM: OpenJDK Server VM
[ 166036]  ERROR – lij.debugger.impl.InvokeThread – Vendor: Sun Microsystems Inc.
[ 166036]  ERROR – lij.debugger.impl.InvokeThread – OS: Linux
[ 166036]  ERROR – lij.debugger.impl.InvokeThread – Last Action: Debug

So, the problem to me seemed to be something wonky with IntelliJ.  I e-mailed Jetbrains, explaining the symptoms and the above stack trace.  This morning, I was pleased to find an e-mail from Serge  at Jetbrains.  He suggests disabling the Ruby plug-in that I have installed.

BINGO!

Worked like a charm.  Problem goes away, and in less than 12 hours since I asked for help.

MapList

Thanks to the MapView, it’s drop dead easy to put Google Maps into your application.  There are lots of posts out there how to do it.  Interestingly (to me anyway), when I did a quick search of the Android developers mailing list, I was surprised to see that a lot of people had the same problem:  basically, when you look at your MapView, you end up with a grid of white squares.  It kind of sucks.  There are a lot of blog posts and articles out there on how to fix this problem, but this one is for me, and to help me remember it.

The trick to fixing this is setting your Google Maps API key.  Note the layout below:

   1: <?xml version="1.0" encoding="utf-8"?>


   2: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"


   3:     android:id="@+id/mainlayout"


   4:     android:orientation="vertical"


   5:     android:layout_width="fill_parent"


   6:     android:layout_height="fill_parent" >


   7:


   8:     <com.google.android.maps.MapView


   9:         android:id="@+id/mapview"


  10:         android:layout_width="fill_parent"


  11:         android:layout_height="fill_parent"


  12:         android:clickable="true"


  13:         android:apiKey="Your Maps API Key"


  14:     />


  15:


  16: </RelativeLayout>

hotel-key

In particular, pay attention to line #13.  What you have to do is create a Google Maps API key, and then paste it in there.  That’s simple.  How do you do that?  Well it’s simple too, but not as simple as it could be.  The first thing you need to do is to sign your application.  This isn’t a big deal, you have to sign your application before you can publish it anyway.  Android will NOT install an application otherwise.

So, it seems we have two steps here:

  1. Sign your application
  2. Use your signed application to get a Google Maps apiKey.

Generate a private key.  Keep this safer, as if it were the Holy Grail.  Lose this, and as far as the public is concerned, you’re locked out from your own application – you will not be able to update it.  The image below will show you the steps to go through

    "C:\Program Files (x86)\Java\jdk1.6.0_19\bin\keytool" -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -validity 10000

keytoolsample

Once you have that done, build your application (in release mode).  I leave this as an exercise for the reader.

Now that you have your application built, you need to sign it.  This is where jarsigner comes in:

jarsignerAnd the final step is to zipalign your  APK.  You have to do zipalign last.  Basically, you do zipalign for performance reasons.  If you want to know more, RTFM.

C:\android-sdk-windows\tools\zipalign -v 4 HistoricalBuildings-unalign.apk HistoricalBuildings.apk

zipalign

Now, of course, both Eclipse and IntelliJ will handle these steps for you.  But where is the fun in that?

Yesterday I was at TechDays 2009 in Calgary for the day (well, the morning really).  I wasn’t there as an attendee, but as a speaker.  Thanks to everybody who came out to my two talks, the first one on an Introduction to ASP.NET MVC and the second one on SOLIDifying your ASP.NET MVC Application.  There were a few hiccups along the way:  as usual, I fell victim to the Technical Presentation Time Dilation Syndrome (i.e. ran out of time) on both talks.  I guess I’m just to long-winded for my own good.  As well, because I was running a EAP of Resharper 5, I had some Visual Studio 2008 issues – namely VS2008 would hang on me from time to time.  Note to self: maybe don’t use the bleeding edge tools in a talk.  And I really should break myself of wanting to type all the code – using snippets would really save me time.

Two things that suprised me:

  1. That there was still that much interest in ASP.NET MVC intro talks.  I just figured that everybody knew/knows about it.  Or maybe I just spend to much time with guys who have drunk the ASP.NET MVC Flavor Aid.  Either way, I think that there were some in the crowd that will convert from WebForms to ASP.NET MVC.
  2. I asked how many people wrote unit tests or developing their software using Test Driven Development was the number of people who didn’t raise their hands.  While I didn’t expect the majority of the crowd, I did expect a lot more people than I saw.  Maybe it was a quiet crowd, and people didn’t feel like saying they wrote unit tests.  Maybe I live in a bubble, and my perception of what is actually going on in the .NET world is skewed (that is to say, perhaps writing tests is the exception rather than the rule).  It did kind of make me a bit concerned, as I truly believe that TDD does help one write better software overall.

Anyway, here’s to hoping that TechDays 2010 will stop off in Edmonton.  And hopefully have a track that will focus on developer fundamentals, like TechDays had in Toronto and Vancouver.

Out of intellectual curiosity, I sparked up MonoDevelop and decided to see what would happen when I tried to compile the ASP.NET MVC source code. I figured that it would Just Work.  After all, I can use the .NET compiled assembly with no problems on Mono, so there really shouldn’t be any problems trying to compile the code.  Bad news is that there is one minor glitch.  Good news is the glitch is easy to work around and has already been fixed so it shouldn’t be a problem for future version of Mono.

When you compile, here is what you get:

Compilation failed: 1 error(s), 0 warnings

/home/tom/Projects/MVC-MS-Pl-original/MVC-MS-Pl/Mvc/FormCollection.cs(25,6): error CS0246: The type or namespace name `FormCollectionBinder’ could not be found. Are you missing a using directive or an assembly reference?

Build complete — 1 error, 0 warnings

So, this kind of surprised me.  Looking at the code, I did see the FormCollectionBinder in the code, it’s an embedded class within System.Web.Mvc.FormCollection, check out lines 68-88 below:

   1: /* **************************************************************************** 
   2:  * 
   3:  * Copyright (c) Microsoft Corporation. All rights reserved. 
   4:  * 
   5:  * This software is subject to the Microsoft Public License (Ms-PL).  
   6:  * A copy of the license can be found in the license.htm file included  
   7:  * in this distribution. 
   8:  * 
   9:  * You must not remove this notice, or any other, from this software. 
  10:  * 
  11:  * ***************************************************************************/ 
  12:  
  13: namespace System.Web.Mvc { 
  14:     using System; 
  15:     using System.Collections.Generic; 
  16:     using System.Collections.Specialized; 
  17:     using System.Diagnostics.CodeAnalysis; 
  18:     using System.Globalization; 
  19:     using System.Web.Mvc.Resources; 
  20:  
  21:     [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable", 
  22:         Justification = "It is not anticipated that users will need to serialize this type.")] 
  23:     [SuppressMessage("Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers", 
  24:         Justification = "It is not anticipated that users will call FormCollection.CopyTo().")] 
  25:     [FormCollectionBinder] 
  26:     public class FormCollection : NameValueCollection { 
  27:  
  28:         public FormCollection() { 
  29:         } 
  30:  
  31:         public FormCollection(NameValueCollection collection) { 
  32:             if (collection == null) { 
  33:                 throw new ArgumentNullException("collection"); 
  34:             } 
  35:  
  36:             Add(collection); 
  37:         } 
  38:  
  39:         public IDictionary<string, ValueProviderResult> ToValueProvider() { 
  40:             CultureInfo currentCulture = CultureInfo.CurrentCulture; 
  41:  
  42:             Dictionary<string, ValueProviderResult> dict = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase); 
  43:             string[] keys = AllKeys; 
  44:             foreach (string key in keys) { 
  45:                 string[] rawValue = GetValues(key); 
  46:                 string attemptedValue = this[key]; 
  47:                 ValueProviderResult vpResult = new ValueProviderResult(rawValue, attemptedValue, currentCulture); 
  48:                 dict[key] = vpResult; 
  49:             } 
  50:  
  51:             return dict; 
  52:         } 
  53:  
  54:         public virtual ValueProviderResult GetValue(string name) { 
  55:             if (String.IsNullOrEmpty(name)) { 
  56:                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name"); 
  57:             } 
  58:  
  59:             string[] rawValue = GetValues(name); 
  60:             if (rawValue == null) { 
  61:                 return null; 
  62:             } 
  63:  
  64:             string attemptedValue = this[name]; 
  65:             return new ValueProviderResult(rawValue, attemptedValue, CultureInfo.CurrentCulture); 
  66:         } 
  67:  
  68:         private sealed class FormCollectionBinderAttribute : CustomModelBinderAttribute { 
  69:  
  70:             // since the FormCollectionModelBinder.BindModel() method is thread-safe, we only need to keep 
  71:             // a single instance of the binder around 
  72:             private static readonly FormCollectionModelBinder _binder = new FormCollectionModelBinder(); 
  73:  
  74:             public override IModelBinder GetBinder() { 
  75:                 return _binder; 
  76:             } 
  77:  
  78:             // this class is used for generating a FormCollection object 
  79:             private sealed class FormCollectionModelBinder : IModelBinder { 
  80:                 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
  81:                     if (controllerContext == null) { 
  82:                         throw new ArgumentNullException("controllerContext"); 
  83:                     } 
  84:  
  85:                     return new FormCollection(controllerContext.HttpContext.Request.Form); 
  86:                 } 
  87:             } 
  88:         } 
  89:  
  90:     } 
  91: }

The version of Mono 2.4.3 I have doesn’t compile the class FormCollection because the FormCollectionBinderAttribute is inside the FormCollection class.  This is the bug, and it has since been fixed.  Easy ways to get around this:

  1. Just use the binary assembly from Microsoft for ASP.NET MVC.
  2. Build your own Mono with the fix included
  3. Move the code for FormCollectionBinderAttribute class outside of the code for the FormCollection class.

Just a heads up that TechDays Canada 2009 is happening in Calgary next week on November 17 and 18.  Yours truly will be there for the whole morning of November 18th talking about ASP.NET MVC and SOLID (note that this is not the same SOLID talk from the DevFundamentals track at TechDays Vancouver and TechDays Toronto).  If you happen to be there, don’t be afraid to come on by and say hello.

Well, don’t let the name of the post fool you – the next EDMUG event is in November, not October,  November 4th, to be exact.  I’ll repeat the e-mail I got with the details:

Date: November 4th
Time: 5:30pm doors open, 6:00pm event starts
Location: Edmonton Room in the Stanley Milner Library
Event Title: Practical Automated Testing Dojo

As we may have eluded to in recent newsletters, we’re going to try some new style events for this year’s schedule.  In the past the lecture presentations that we’ve held have provided great content in an easily accessible format.  They also seem to have left attendees wanting for more practical and hands on exposure to the technology being discussed.  This event will be the first of those new formats that will allow you to get started with that practical experience while still receiving some guidance.

How the Dojo event will work:

At the start of the meeting (6pm in this case) we will provide a brief introduction talk on Automated Testing.  This will take up no more than 15-30 minutes and is not intended to be an in depth review of the practices involved.

After the introduction a number of volunteers who are well versed in Automated Testing will form breakout teams which attendees will be free to choose from.  Those teams will spend the majority of the remaining event time (1.5hrs plus) working through real world examples of how to write automated tests using different tools and different styles.  While there will be one person who can provide guidance, we are encouraging all attendees to spend time pair programming, watching and engaging in questions with the entire group.  Attendees should also feel free to move from one team to another as the content, styles and experiences may be different.

What, you ask, will the attendee be responsible for?  Well, our hope is that you will feel inclined to bring questions about Automated Testing and a desire to interact and learn with and from the rest of the community.  If you can, please bring your own laptop.  There will be some laptops available but they will be used in pair (or more) programming scenarios only. We will be providing a sample code base that needs many different kinds of tests added to it.  If you want the code at the time of the event, please bring a USB drive.  For those that don’t we will provide the code for download from the Edmug website after the event.

As this is our first event of this style, we are going to treat it as a learning experience and apply those lessons to the coming events.  As always, we encourage you to provide us with any feedback that you can at info@edmug.net

The Edmug Team

www.edmug.www

So, with that out of the way, it’s a pretty loosy-goosy format.  If you are going, is there anything in particular that you would like to see or do?  Some code you would like help with?  Need a laptop?  I will be there, and more than willing to help out with your questions and figured that it can’t hurt to find out in advance some specifics.  Feel free to respond to me either via comments here, or by e-mail (tom at opgenorth dot net).

At the end of my talk on Git at the Edmonton Code Camp, somebody asked if I would put the links to the various git resources up on my website.  Here they are:

There you go, enjoy, and be distributed.

One question that has been bouncing around in my mind is what, exactly, does one have to do to be considered Agile?  Let’s look at the Agile Manifesto:

Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan

That is, while there is value in the items on
the right, we value the items on the left more.

Sounds pretty simple.  I notice that there are twelve Agile principles:

Our highest priority is to satisfy the customer
through early and continuous delivery
of valuable software.

Welcome changing requirements, even late in
development. Agile processes harness change for
the customer’s competitive advantage.

Deliver working software frequently, from a
couple of weeks to a couple of months, with a
preference to the shorter timescale.

Business people and developers must work
together daily throughout the project.

Build projects around motivated individuals.
Give them the environment and support they need,
and trust them to get the job done.

The most efficient and effective method of
conveying information to and within a development
team is face-to-face conversation.

Working software is the primary measure of progress.

Agile processes promote sustainable development.
The sponsors, developers, and users should be able
to maintain a constant pace indefinitely.

Continuous attention to technical excellence
and good design enhances agility.

Simplicity–the art of maximizing the amount
of work not done–is essential.

The best architectures, requirements, and designs
emerge from self-organizing teams.

At regular intervals, the team reflects on how
to become more effective, then tunes and adjusts
its behaviour accordingly.

The agile principles are interesting, because in a lot of ways I can see advocates of other methodologies (BDUF) saying the believe in the same thing.

Asking amongst some peers, and there didn’t really seem to be a concise definition of Agile and what you need to do to call yourself.  I’ve seen some places that will suggest that they are Agile because they stand up at meetings (or a manager wanders around once a day), avoid documentation, and have a meeting every three or four weeks that they call a “retrospective”.  So, does anybody care to offer up their thoughts on what one needs to do to be considered Agile?  I have my own thoughts, but figured I’d save them for a later blog post.

Every developer, no matter how experienced, has to dig in and fix bugs.  This is, in my experience, the typical cycle:

  1. bug is reported
  2. bug is assigned to developer
  3. developer thinks the bug is fixed
  4. developer marks bug as resolved
  5. tester checks to see bug is fixed, but it isn’t.
  6. tester reopens bug, assigns it back to developer
  7. back to step number two.  Repeat until developer (or tester) climbs to the top of a 307 foot administrative building with high-powered rifles to demonstrate USMC-worthy marksmanship.

Now, even if you aren’t into the whole Lean Software development philosophy (i.e. eliminating waste), you can probably appreciate that it can be pretty wasteful of time and patience every time that #6 happens, so please indulge me as I elaborate on some of the finer points of bug reporting.  Now, where I say “bug reporter”, I typically mean somebody who is in a QA role – their job is to find bugs and report them.  This doesn’t always have to be the case though.

If you check out most open source projects, you will often find rules/guidelines for reporting bugs.  In the case that doesn’t exist then perhaps the following might be of use: When you log a bug, be explicit, and give lots of details.  Don’t be lazy.  If it’s hard to duplicate your bug, then odds are it either won’t get looked at, or won’t be fixed properly.  And when it doesn’t get fixed properly, there will be a lot of churn.

At the very least, when reporting a bug you should provide:

  • A detailed description of the problem.  Note the emphasis on problem.  Odds are you don’t have the solution, so don’t bother.  Let the programmer figure out the solution.  For example:  Using version 3.1415 of the application on 28-July-2009, I was expected a date to be calculated a certain way based on some values.  The application didn’t crash, but the correct date was not calculated.
  • What you expect to happen.  If you have some sort of formal spec, repeat it here, and cite how to find the spec.  i.e.  According to Page 1054, in section 1095.4.3.2 the new date is to be calculated as follows :  add the value of  ((a – b)- 10) /2 (rounding down) to the date Y for a new date of Z.
  • What actually happened.  i.e.  Using these values a=300, b= 150 and Y of 1-Sep-2009 I expected that the new date Z should be 2-Oct-2009
  • A step-by-step description of HOW to duplicate the bug.  This means explaining in excruciating detail HOW the programmer can duplicate what your reporting, i.e.
    • Go to the URL http://myproblem.com/is/here
    • Click on the text box next to the label “Value A:” and enter a value of 300
    • From the drop down list by “Value B:” and click the value 150 from the drop down list
    • Use the tab key to navigate to the “Calculate new date” button.
    • Hit Enter
    • The text box by the “New Date:” label now has the date of 4-July-1943.  I expected 2-Oct-2009.
  • How the developer can get a hold of you.  This comes in handy when for some reason the developer can’t duplicate your bug or doesn’t understand what you were doing.

When the developer flags the bug as resolved and it turns out not to be fixed, don’t just re-open the bug with curt “This is still broken”.

Ah, but now aren’t I the smug developer – shifting my inability to quickly resolve a bug to the poor reporting capabilities of my tester.  I’m pretty ungrateful too.  I mean, somebody took the time to test out my application, and then enter a bug like “I tried to calculate the new date and it didn’t work.  Please fix”.  Well, fear not – there is a lot developers should be doing as well, but that is the subject of a later post.

Of course, the key part in all of this is COMMUNICATION.  Don’t be afraid, as someone reporting a bug, to actually talk to the developer.  Nothing really beats face-to-face communication (or a phone call) if things seem unclear. Odds are you won’t have an empty whisky bottle thrown at you.  Most likely the personal grooming standards of the developer will be higher than that of a middle age serf during the Black Plague.  In theory, as a tester, you’re on the same side as the developer trying to fix the bug.

Well, it’s coming up on fall, which is traditionally the time of year for the Edmonton Code Camp.  It seems that there is still a spot or two left for speakers, so if you’re in Edmonton why not think of something programmy and give a talk.  Doesn’t have to be .NET – anything that is related to software development will do.

Anyway, I’ve put my name down for a talk at ECC.  There are several options available for me and I’m not sure which one to go with.  So, I figured that perhaps a straw poll would help me decide.  Feel free to add a comment about which topic you’d prefer:

  1. Intro to ASP.NET MVC.  This wouldn’t be my own presentation.  This will be one of the sessions at TechDays in Calgary (this November). 
  2. Introduction to git.  Git is an open source, distributed version control system.  I’ve been dabbling with it off and on for the past little while, and am growing rather fond of it.
  3. Introduction to programming on Android.  Again, another thing I’ve been dabbling in for the past couple of months.  Given that the talks are only about an hour or so, this might be a bit rushed, but could still be of interest.

Personally, I’m leaning more towards #2 or maybe #3.  What do you think?