Friday, July 30, 2004

Java Annotations

Check out the new functionality in the Java "Tiger" release. Looks like the major .NET languages and Java language oriented functionality are going to be walking lockstep for the forseeable future. Though my professional emphasis has moved to the .NET side of "the fence", it's good to see Java moving along in positive directions. The originally simplicity of the Java language was probably an over-reaction to what happened to C++ in terms of language complexity and the expertise needed to use the language effectively.

Competition is good! Java kicked Microsoft out of it's slumber with respect to development environments that are both powerful and productive. Now hopefully .NET is going to kick Java along to be even more productive, have better IDEs and get better on the GUI/startup performance front.

When reading about the Tiger functionality, the term "annotations" jumped out as it was unfamiliar at first. It's an equivalent to the .NET attribute concept and it seems a more appropriate term to use. The term "attribute" can be confused with fields/properties when someone is not familiar with the .NET context of it's meaning.

Tuesday, July 20, 2004

Overly Pedantic

Today my brain had a situation where it looped continuously making a decision whether to email a customer on their wording in an email. I got stuck for a few minutes at the keyboard before deciding to stop being a pedantic developer type being overly concerned with semantic correctness. The problem was that a customer asked for a handy feature addition which would save them lots of copy/paste keyboard time. It was a good idea for additional functionality, but the email request boiled down to "can this be fixed?". This is what got my brain in a loop. Fixed? What's broken? It works just as intended and requested, my developer's brain replied internally. Sometimes, the attributes that make a good developer/programmer aren't so good when applied to dealing with customers. Maybe we all need "Intellisense for the brain" to help us along our wayward semantic travels?

Sunday, July 18, 2004

Debugger.IsAttached

The System.Diagnostics.Debugger class provides a handy means of interacting with an attached debugger and to determine whether a debugger is present. The Debugger.IsPresent property can be used to alter program behaviour if you are in a debugging session. After adding unhandled exception processing to an application, the Debugger.IsPresent provides a means of stopping the generation of an application error dialog and just letting the exception through to the debugger when programming. I typically combine an #if DEBUG pre-processor check with a Debugger.IsPresent check so that release mode executables always bring up an application error dialog for "unhandled" exceptions but debug mode executables let the debugger do it's work if it's there.

Saturday, July 17, 2004

Unhandled Exception Reporting

I recently included unhandled exception processing in a Windows Forms application to help fault find some problems. Unhandled exceptions were processed by bringing up a user friendly message and giving the user option of emailing an error report to a support email address. The error report is transferred as a zip file containing a bunch of useful information including stack trace and trace/log file. Have a look at this Code Project page for an example of "unhandled" exception processing.

The functionality worked like a charm. A few hours after the new application version was deployed a error report was received on the support email address. The stack trace and associated trace log contained enough information to identify what the problem was and fix it. It's satisfying to be able to resolve a problem within a few hours of a customer experiencing the problem.

Monday, July 12, 2004

Null Checks/Plumbing Code

Brad Abrams posted on the NullReferenceException or ArgumentNullException question. For me, it's one of those "close call" questions. The ArgumentNullException gives an immediate and clear indication that the method at the top of the stack trace has been called incorrectly. On the other hand, the stack does provide heaps of information on the cause of an exception and why perform a double check (by the app code and the automatic null checks the clr performs)? My general conclusion would be to enforce it (in FxCop or similar) on the public methods of public classes in a DLL.

The PrintValue method example Brad used brought to mind the recent discussions on AOP on Eric Gunnerson's blog. The theme that relates the two posts is the entry of what I would call "plumbing source code". Plumbing source code is repetitive code that needs to be entered into a variety of locations in source code and can't easily be separated out using standard methods or templates (C# 2.0). Examples of categories of plumbing code are listed in my recent post on AOP. Argument null checks are another form of source code that falls into the plumbing category.

I feel that there is a need to improve .NET developer productivity by minimizing plumbing code but still retaining performance and gaining in the maintainability area. Performance can be retaining by (say) limiting what the developer has to type to an attribute declaration but still having the resultant IL include the appropriate plumbing code. The attribute makes it clear what IL pre/post processing is being performed during the compilation of the code which assists in code readability. The plumbing code definition can then be supplied in one location rather than every instance that a plumbing code template is required.

Source code generation based on attribute definitions would be one way of achieving what is being described here, though I would prefer functionality that is built in at the compiler level. Darren Oakey, in his comments on the Eric Gunnersion AOP post, mentioned the C/C++ pre-processor functionality intent being more useful than advanced AOP techniques. My interpretation of the comment was the need for something in between the mess that pre-processor functionality can initiate and the conceptual complexity of an AOP implementation.

This throught process brought back some memories of a C# compiler extension that generated additional IL code in methods based on attributes. I spent around 15 minutes in Google land trying to find a web page to associate with my vague memory. It's frustrating when you've got paid work to do, but just want to find that tiny information needle in the proverbial haystack. Eventually I found what I was looking for. It's just a matter of getting the right combination of words that reduce the result space to something manageable!

ResolveCorp make a product called Extensible C# that generates "inline" IL code in methods based on attribute declarations on the method and it's parameters. Coincidentally the example showed on the products page is the null check plumbing that started me off on this post. Though I liked the Extensible C# concept a lot, it's never been pursued because it's the sort of functionality that needs to be in the core compiler support from a maintenance perspective.

My conclusion is that there is a need from a variety of areas to automate plumbing code based on attribute definitions in the .NET languages. Hopefully Microsoft can look into these areas. Actually that brings to mind, ObjectSpaces and WinFS. Surely the application code that reference these APIs is a prime candidate for the functionality discussed here?

Paste Special

Just a thought: I seem to use "Paste Special ..." and then select "Unformatted Text" so often it really should be as much of a standard keystroke as Ctrl-C for Copy and Ctrl-V for Paste. Ctrl-T for Paste Unformatted Text maybe?

Sunday, July 11, 2004

Firefox

Because of all the recommendations to stop using Internet Explorer, I decided to give Firefox a go. There were no problems getting it downloaded and working. The download was 4.7MB and allowed the existing IE settings/favourites to be automatically imported. What I particularly like about Firefox is that the rendered pages look pretty much identical to the equivalent web page rendered in IE (so all the pages designed with IE in mind look like they're "supposed to". It also includes tabbed pages for web browsing. Tabbed web pages are such a natural for web browsing, I really don't understand why all browsers don't have it as standard functionality.  I'll be using Firefox as my primary browser for the next few weeks and see how things go. So far, it "just works" and is a wonderful example what open source software can be at it's best.

Tuesday, July 06, 2004

Vendor PC Annoyance

In supporting customers recently, I've been getting the customer to request help using Remote Assistance. Once the customer gets the request process down (and UPNP routers are being used or a VPN is involved), it's easy to see what they see and diagnose the problem. An attempt to do this today was foiled by the default Windows XP setup on a Dell PC. Rather than leaving the "Help and Support" option on Windows XP alone, they decided to tailor it to be Dell specific. You can get to the Remote Assistance request links from the Dell specific user interface, but try getting the average customer/user to find something like that over the phone when you've never seen the Dell specific screen before!

Vendor's shouldn't change the content/location of standard functionality items like the Help and Support screen. Adding a new menu option would be fine. A relative got a Hewlett Packard PC a few years back (Win98 timeframe) and everything was tailored to be "HP-oriented" with a gazillion applications and windows appearing when the thing was first booted. Most of these vendor supplied apps were crappy, non-standard or pushing the user to buy some more software and/or service. Vendor tailoring of the OS setup gone mad!

Monday, July 05, 2004

VS.NET Addin Weirdness

Recently I experienced some weirdness in the Visual Studio.NET 2003 source code editor. The problem only occurred when editing C/C++ files and consisted of symptoms like being unable to select a large block of text with the mouse and popup dialogs appearing but not being able to retain keyboard focus. Fortunately, this resulted in a strong sense of deja vu and the VS.NET add-in list was checked for recent changes. The recently installed Xheo licensing package had also installed a VS.NET add-in. Disabling the add-in made the C/C++ editing weirdness disappear immediately.

The add-in was quickly identified as the cause of the problem, because I had similar problems with the Active Reports.NET integration into Visual Studio.NET 2003 a number of months back. Unfortunately at that time, I spent around a month with weird editing hassles in C# code. It was a frustrating time and cost me in terms of productivity (C# Intellisense and syntax color coding kept going screwy). It made me realize how important intellisense was to my programming approach these days when it was suddenly "taken away" (like Chris Sells said it's like crack for programmers - or was it Don Box?). Eventually I figured out that Active Reports.NET was the culprit and not VS.NET as originally thought.

Changing the .licx file entry to just:

DataDynamics.ActiveReports.ActiveReport, ActiveReports

resolved the problem. You can search Data Dynamics knowledge base and forums for licx and license for details.

Note that both the ActiveReports.NET and Xheo licensing products are very useful software components, so don't let this post deter you from investigating their use. The purpose of the post, is that if you are you experiencing instability in VS.NET that isn't a known VS.NET problem then check your add-ins.

This brings up the question of add-ins and how they should be implemented. The more apps that support add-ins developed in managed .NET code the better. It's just easier than dealing with the COM crap and can provide a level of protection from the add-in screwing up the app proper. Apologies to any COM afficionados, I just never got into COM because of all the hoops you had to jump through to get things done. It also seems that .NET APIs tend to make more sense (a generalization of course) - maybe because the programmers have to worry less about the plumbing which makes it easier to think through the higher level API concepts.

Thursday, July 01, 2004

AOP and .NET

Eric Gunnerson asked for example code on what scenarios developers would use AOP for. Aspect Oriented Programming is another one of those software development areas that I'd love to know more about if there was spare time to look into it and experiment more. It looks promising, but it also looks like it is a potential nightmare with respect to understanding what a given piece of code does at runtime.

Taking a "requirements" driven approach, the following shows what I'd love to be able to do in the .NET development environment from a "plumbing" perspective. By plumbing, I mean boiler plate code that is repeated through out the source code. This boiler plate code is needed to get things done but sometimes hides the real application code. This applies equally to manually entered boiler plate code or the code generated equivalent. My perception is that AOP would be best suited to the implementation of this repetitive boiler plate code in an efficient manner. One of the .NET projects I'm currently working on implements the following areas of functionality using attribute based programming:

  • Object Persistance - Properties
  • Object Persistance - Query Methods
  • Authorization defined at the class member level.
  • Tracing (i.e. programmer level logging)
  • Audit functionality defined at the class member level (i.e. application level logging of who made what object changes when)

All of these functionality areas could benefit from AOP style functionality which leverages both the attribute information and the specification of boiler plate code in one location in a source code project. Check out the following contrived example. Forget about the "made up" syntax used in this example code, the important part is the functionality need that is inherent in the example: 

[ Persistable ]

public class Person

{

    private string address;

 

    [ Persistable ]

    [ DenyRead( typeof(Guest) ) ]

    [ AllowWrite( typeof(Administrator ), typeof(Manager) ) ]

    [ LogWrite ]

    public string Address

    {

        get { return aspect( ref address ); }

        set { address = aspect( value, address ); }

    }

 

    [ Query( typeof(BlogPost),

        "select ref(b) from BlogPost b where " +

        "b.Poster.OID = @this and " +

        "b.DateCreated >= @start and b.DateCreated <= @end" ) ]

    [ TraceEntry ]

    [ DenyExecute( typeof(Guest) ) ]

    [ LogExecution ]

    public List<BlogPost> GetPosts( DateTime start,

                                    DateTime end )

    {

        return aspect;

    }

}

 

The [ Persistable ] attribute marked on the class would result in the class automatically including members to support the persistance of the object in something like ObjectSpaces. Marking a property as [ Persistable ] would automatically insert code which surrounds the get/set methods so that the object persistance mechanism is invoked transparently. The series of Allow/Deny attributes in the example code would result in the insertion of code that checks the user roles defined in the attribute parameters. If that user role isn't allowed to perform the action (get the property value, set the property value, execute the method) then an exception is thrown. Applications could check the type metadata to identify whether a user interface should allow the actions in the first place. The exceptions would only be thrown if the UI ignores this metadata.

The Query attribute is a means of defining a query to issue to persistence mechanism to get back a result object or list. The TraceEntry attribute functionality is the venerable programmer logging "aspect". The LogWrite and LogExecution attributes are oriented towards Auditing needs i.e. your application needs to log who retrieved a list of blog posts for that person and when they did it.