CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Peter's Gekko

public Blog MyNotepad : Imho { }

June 2008 - Posts

  • VisualSVN and TortoiseSVN

    Almost holiday time, time to tidy up all work. Recently I moved to Tortoise SVN for all my source control needs. Getting that to work was not that difficult, but to keep it up and running for my set of Visual Studio solutions took a little more effort than I had hoped. The enormous amount of "hidden" files tools like Resharper, nHibernate and VS itself leaves on your disk takes a lot of maintenance. Tortoise SVN has an an exclude files list, this kept growing and growing. Did you know there are CACHE, cache and Cache files ? (Yes you can use expressions in the exclude list) Things got worse when a deployment project was added. Switching from a debug to a build version was enough to get in an endless number of requests for a cleanup and "X is not a working copy directory" error messages.

    Instead of diving deep into SVN configuration I gave Visual SVN a try. This is an add-on for Visual Studio which integrates subversion into Visual Studio. Its is a commercial product. A 30 day full functional trail and $49 for a license. With the current Euro-Dollar exchange rate the ROI was almost instantaneous.

    Visual SVN requires the latest Tortoise SVN to be installed. TortoiseSVN has a built in "check for updates" and considered itself fully up to date at version 1.48. The VisualSVN setup didn't go for less than 1.50, thank goodness the link built into the setup started the required update. After a reboot (due to the windows shell integration of TortoiseSVN) Visual SVN installed without a glitch in both Visual Studio versions it found on my machine, 2005 and 2008.

    Visual SVN takes a more subtle approach than Tortoise SVN. In TSVN I just submitted the whole folder to a repository and set the files to exclude in a filter. With VSVN you submit a solution to SVN from a VS (context) menu. VSVN will create the repository for you and submit just the needed files. No more, no less. End of filter hell. End of working folder hell.

    Before creating a nice new clean repository I had to get the code out of the existing messed up one. This took a little effort. You can copy or move sources under SVN control around. The good thing is that SVN will keep track of the underlying repository. The bad thing is that the way to get rid of this repository binding is well hidden in the docs. To un-version a source you have to export it to itself. In the context menu select Tortoise SVN | Export. When prompted for a directory pick the source directory itself. SVN will prompt "Do you want to make this working copy unversioned?". A confirmation will free the source by removing the svn information.

    VisualSVN works very well together with TortoiseSVN. You can view and do everything from both Visual Studio and the Windows Explorer with SVN.

    No big difference. What I like far better in VS are the overlay icons. They a far more subtle than the default Tortoise SVN ones. And they update immediately after a status update. In the Windows explorer they really lag behind (on my Vista machine). Displaying the right icons often requires reopening the explorer window.

    That's it, another improvement of my toolbox. And all sources ready for holiday.

  • SQl server reporting services versions, Visual Studio versions and asp.net versions. Gotcha.

    Reports are not my favorite part of an application. But to may an end user the reports are the most valuable parts of the system. They are a well presented and clear overview of hours, even days, of work behind the keyboard. So taking good care of the reports is important. A part of my personal dislike is caused by the tools. Crystal Reports was a sheer nightmare. MS Sql Reporting services (RS) is far better but is still a little pale compared to the rest of my toolset.

    Visual Studio 2008 looks like the ultimate environment. In case you are working on an .net 2.0 project that's just a project setting. Net 1.x is a different story, I have a virtual machine to handle that. Alas for reporting services it's a different game. At the moment VS 2008 cannot create or import reporting projects. Period. But the situation is a little more complicated than waiting for the service pack. Let's investigate.

    RS is part of an MS sql server installation. To the report consumers RS is just a web site. In a default install this web site is an asp.net application which runs in IIS on the sql server machine. The RS web app stores all report data in an own instance of sql server. That scenario is not acceptable for a lot of organizations. The RS web site will live in the DMZ but a database server should be far away behind a firewall. Thank goodness the data for the reports do not have to live in the same db server as RS. They can be anywhere, in any format. All the report needs is a connection string. As the RS database is only used by the web app on the same machine there are a lot of ways to hide the db server to the outer world. All interaction, including uploading reports, is done through the web site.

    So setting up RS requires another sql server license. As far I have read al the docs it could be possible to set up RS in such a way that it will use a database on another server. But as configuring reporting services is tricky enough as it is I have skipped this option.

    RS is a part of several sql server versions: sql 2000, sql 2005 and sql 2008. Installing sql 2000 will result in an asp.net 1.1 web application, installing 2005 will result in an asp.net 2.0 web application. I am not sure about 2008, that's well hidden in the docs. As moving to another version of a database server is a far bigger step than moving an application to another .NET version I don't have any hand on experience yet.

    We experienced quite a gotcha when we upgraded a web application to asp.net 2.0. All went well until we arrived at the RS part. The server is an old reliable Windows 2000 server with sql 2000 RS. The main problem is that Windows 2000 cannot run two different asp.net versions (2.0 for the application 1.1. for RS 2000) in the same web site. That takes server 2003. So upgrading the app requires upgrading either the RS to 2005 or even the complete OS to 2003.

    Another gotcha is in the report definitions. It takes Visual Studio to create and edit report definitions. The existing reports were all built using VS 2003 and worked good enough on RS 2000. (Given the many little quirks I talked about in other posts). VS 2008 does not accept a reports project, VS 2005 does. But when importing the project it converts the report definitions. After that RS 2000 no longer understands the reports. RS 2005 does.

    Given all this we have several options

    • Dive into configuration hell
    • Stay with RS 2000. Which will require an upgrade of the server OS and we have to keep VS 2003 alive
    • Move to RS 2005. It is a big step to move to another DB server version. But as it is only on the web server that should be manageable. We have to keep VS 2005 alive. Or not move to 2008 yet.
    • Wait for RS 2008 and VS 2008 integration. Not an option, it should have been operational yesterday.

    My main problem with RS is that it ties my application to stricter versions of it's infrastructure than I had believed. I've been too naive again and any advice is more than welcome.

    Posted Jun 18 2008, 11:48 AM by pvanooijen with 5 comment(s)
    Filed under:
  • What really went wrong ? Check the inner exception

    In his recent overview on Exceptions Karl briefly mentioned the inner exception. By passing an exception to the constructor of the new exception, the exception passed in becomes the new exception's InnerException property.

    private void workWithFile()
    {
        try
        {
            // do something        
        }
        catch (FileNotFoundException ex)
        {
            throw new Exception("Cannot find the file", ex);
        }
    }
    Code using this method can catch the exception
    try
    {
        workWithFile();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    Now this exception caught here does not contain very much useful information. It would be interesting to know the name and location of the missing file. To get at that you have to inspect the inner exception.

    try
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        FileNotFoundException fnfEx = ex.InnerException as FileNotFoundException;
        if (fnfEx != null)
            Console.WriteLine(fnfEx.FileName);
    }

    Instead of discussing the design issues here (drop the catch in the method and just catch a  FileNotFoundException in the consuming code) I want to take a look on a situation in real life where the inner exception does tell the story.

    When initializing a sessionfactory in nHibernate a lot of things can go wrong and will throw an exception. My nHibernatemanger does not handle any of them, so my code will have to check. At first sight this might look OK

    try
    private void reportException(Exception ex)
    {
        Console.Write("* ");
        Console.WriteLine(ex.GetType().ToString());
        Console.WriteLine(ex.Message);
        Console.WriteLine();
    }
    
    [Test]
    public void CanReportOuterException()
    {
        try
        {
            INhibernateHelper nhh = GetNHhelper();
        }
        catch (Exception ex)
        {
            reportException(ex);    
        }
    }

    Running the code will not make me much wiser

    Also here the real information is in an inner exception. As each (inner) exception can have another innerexception my code is going to handle every inner exception it can find

    [Test]
    public void CanReportAllExceptions()
    {
        try
        {
            INhibernateHelper nhh = GetNHhelper();
        }
        catch (Exception ex)
        {
            while (ex != null)
            {
                reportException(ex);
                ex = ex.InnerException;
            }
        }
    }

    A stack of three exceptions turn up. Together they describe very well what really went wrong. In this case I misspelled the name of the mapping assembly.

    I have "misused" resharpers unit test runner to develop this code. In fact the result is much like the testrunner's report on handling an exception not caught by a test.

    [Test]
    public void CanCreateHelper()
    {
        INhibernateHelper nhh = GetNHhelper();
        Assert.IsNotNull(nhh);
    }

    Note that the runner lists the exception the other way round, starting at the most inner exception.

    Instead of delving though the stack of exceptions you could use the ToString() method of the exception. Which results in a bulky string including information on the inner exceptions and more. But this info is not as well structured and misses the type info of the inner exceptions.

    I'm not quite sure why nHibernate does wrap its exceptions this way, but what I have learned is to look inside.

    Posted Jun 10 2008, 11:10 AM by pvanooijen with 1 comment(s)
    Filed under:
  • The end of the era of magic (I want coaches, not wizards)

    Five years and one day ago I wrote my first blogpost. Blogging has done more to and for me than I could ever imagine so this celebration is worth a little rant on a subject which has changed most over these years.

    Five years ago I was still with one foot in the Delphi world. Delphi was at the time where the terms RAD and wizard were considered qualities of great value. These days saying these words alone is enough to light the flames. What has changed ? The essential part is imho that In Delphi the RAD designers and wizards were two way tools. You launch the wizard or drop something on a design surface and it will guide you to produce source code. You modify the source code and the wizard or the designer will pick up these changes in the next rounds. So it is you and the wizard working on a shared piece of code. Of course you can do horrible things with such tools, like dropping a sqlconnection directly on a form and all that. But you don't need wizardry to do that, the devil is in the developer himself.

    Arriving in the MS world I found wizards from a quite different guild. They didn't tell me what they were going to do, hid the result in invisible code and did not allow another round. The most hilarious one was "create compatible Guid" in (pre .net)  VB. It took me some time to realize that after every rebuild I of the COM server I had to re-import the typelibrary in the consuming (Delphi) application. Quite recently I encountered a comparable sorcerer when moving some machines to another domain. Trying to do this job as fast as possible I used the Windows migrate settings wizard. Which did work for a lot of things. But it never told me what it had actually migrated, and now once in a while somebody asks me "wtf happened to xxx?". Always surprising. The wizard did produce some messages but these were of the abracadabra kind, only comprehensible to members of the same guild.

    So looking back it is the end of the era of magic. (For those who only recognize starwars quotes, that is from my favorite cult series) Wizards are dead but in the next five years I would love to see the return of the coaches. Thank goodness all it takes to see some of that is refactoring with Resharper. And in VS 2008 the split view designing an aspx page is a RADical improvement.

    Posted Jun 04 2008, 11:51 AM by pvanooijen with no comments
    Filed under:
More Posts

Our Sponsors

Free Tech Publications

This Blog

Syndication

News