As I’ve explained in the first posting of this small blog series, we have been looking for an ideal web development stack for a new installable product. We looked at the most popular development stacks, platforms and frameworks before eventually deciding which one to use. I will try to summarize the pros and cons of the stacks we evaluated and explain how we’ve come to the final decision.

Photo of books about web development

We aren’t experts in all the different frameworks and platforms we evaluated and there are probably some details we got wrong. Feel free to correct us by leaving a comment. So without further ado, here are the pros and cons of the different development stacks in regards to installable web applications:

  • Java (including Grails and Spring)

    Java and the various frameworks such as Spring and the dynamic counterpart Groovy combined with the Grails framework qualify in many ways to be the perfect web development stacks for installable applications. The Java platform is very mature and has very good support for cross-platform and cross-database development. If you use frameworks such as Spring, you also benefit from the MVC pattern and from enterprise features and libraries. Java also isn’t going anywhere and it’s safe to say that Java will be available for the next 10+ years and probably a lot longer. Unicode support is also excellent, which is rare for cross-platform development stacks.

    However, one of the biggest drawbacks of this platform also made us decide against using Java: deploying Java web applications is complicated and scares the hell out of us. We wouldn’t feel comfortable having to support deployment scenarios with all the different available Java application servers out there, which you need to run a Java web application. The need for an application server such as Tomcat or JBoss is a serious disadvantage, especially if your customers aren’t experienced with installing and configuring such a solution.

  • Ruby on Rails

    Ruby on Rails is a modern and productive web development stack and framework. Using Ruby as the programming language of choice, it’s best known for the MVC architecture and the well-integrated ActiveRecord object-relational mapping system for database access. Ruby on Rails also emphasizes the convention over configuration concept, making it very easy to get started developing web applications. Rails also comes with reasonable support for multiple database servers, but is usually used with MySQL and PostgreSQL.

    Recent versions of Rails also improved the support for Unicode and UTF-8 encoding, making it more suitable for applications that are used by users from non-western countries. Rails is usually deployed by configuring a Mongrel cluster (which is easier than it sounds) and using a front-end web server such as Apache, nginx or lighthttp for static content serving and load balancing the different Mongrel processes. Although setting up a run-time environment for Rails applications is still a lot easier than for Java web applications, it can still be problematic for customers who have no experience with Rails and/or Unix environments.

    This leads us to the big problem with Rails: the support for Windows servers is miserable. Because most Rails applications are developed, tested and deployed in Unix environments, either for hosted web applications or in-house intranet applications, supporting Windows servers isn’t an important issue for the Rails team or developer community. However, if you are trying to sell an installable web application to typical companies, Windows servers are still extremely popular for internal application and workgroup servers. And if your potential customers are used to running Windows servers, you better make sure that your solution works flawlessly in this environment.

  • ASP.NET

    ASP.NET is a good choice for many installable web applications. It’s reasonable easy to deploy an ASP.NET web application on a Windows Server with IIS and most companies (and potential customers) already have such a server running as an internal application server. The Unicode and localization support is also top-notch and if this is one of your most important requirements, you should definitely consider going with this development stack.

    Another big plus for ASP.NET is the strong developer community with countless of blogs, books, websites and forums. The rich offering of user interface controls, libraries and development tools for the .NET platform in general and ASP.NET in particular by third-party vendors is also unmatched. However, ASP.NET also has its problems. ASP.NET Web Forms really encourages mixing application logic with the user interface code, which can result in badly designed applications and hard-to-maintain code. The abstraction in ASP.NET Web Forms that’s supposed to make web development easier for Windows desktop developers makes the development stack hard to debug and overcomplicates things.

    Experienced ASP.NET developers try to workaround these limitations by using patterns such as MVP or MVC. Especially Microsoft’s new ASP.NET MVC framework is an interesting alternative to Web Forms, as it encourages the separation of business logic, data access/validation and user interface code and makes it easier to build a maintainable application. This leaves us with the biggest drawback of ASP.NET: the lack of cross-platform support. Sure, there’s Mono, an open source .NET implementation that also supports ASP.NET. But while it’s definitely a nice option to have, it’s not widely used and I personally would not consider it to develop cross-platform web applications at this point.

  • PHP

    PHP is arguably the most used web development programming language, despite it’s many technical limitations and problems. The main reason PHP has become so popular is that it’s extremely easy to use and that it’s supported by virtually all web hosting companies. Developing an PHP application without using a decent application framework will most likely lead to an unmaintainable code base, however. The language itself, although explicitly designed for web development, doesn’t come with a (MVC) framework and doesn’t help with separation of concern in any way.

    One of the technical limitations is the lack of Unicode support. While most development stacks have quite good Unicode support by now, PHP’s support for non-western characters is still very limited and if you plan to support most server configurations and multiple databases, it’s basically non-existent.

    Luckily, there are quite a few available PHP frameworks to remove some of the mentioned limitations such as the Zend framework, CakePHP or CodeIgniter. Using one of these frameworks makes it a lot easier to write maintainable applications and also provides you with often needed functionality not found in PHP itself, such as a database abstraction layer.

    Of course, PHP also has its good sides. Applications written in PHP are very easy to deploy and work on most operating systems and server configurations. Even Microsoft is working hard to improve the PHP deployment experience on Windows and IIS, as many popular web applications such as WordPress are written in PHP. The great cross-platform, cross-database support combined with the ease of deployment and available frameworks make PHP a good web development stack, even though it’s not the best technical choice.

Having evaluated the above mentioned frameworks and having looked at the pros and cons of each development stack, we have come to the conclusion that PHP together with a lightweight framework such as CodeIgniter is the best choice for an installable web development stack, at least today. Yes, from a technical standpoint, PHP is less than great. The ability to easily deploy and run a PHP application on most server configurations, however, easily outweighs its limitations. One drawback that really made us think twice before deciding to go with PHP was the lack of proper Unicode support. Unicode support was originally a really important requirement to us, but we decided that we can do without Unicode support for a few more years until this problem will hopefully solve itself (with better Unicode support in PHP).

You might also be interested in our reasons to choose CodeIginiter as the PHP framework for our application. The great thing about CodeIgniter is that it’s a really simple framework. Although CodeIgniter only offers the most basic features and you have to implement advanced capabilities such as locale or authentication support yourself, this simplicity makes it really easy to understand the entire code base in a very short amount of time. So even in the unlikely case that we needed to fork this framework because the authors stopped supporting it, we could easily improve and add features to the existing code ourselves, something that is not really feasible with most other frameworks and stacks out there as they are often too complex.

Some months into development we are still happy with our choice. The application is coming along nicely and PHP and CodeIngiter have proven to be a solid development stack for an installable web application so far (of course, the real challenges come when customers deploy our application in many different hosting environments). Our choice of a development stack would most likely be different if we were building a hosted solution where we could control every little aspect of the server environment. But because our customers will have to deploy and host our application themselves, PHP and CodeIgniter are a great choice for us.

Now before you start your next big thing, make sure to consider all your options, as you cannot easily change platforms once you’ve invested a lot of time and resources.

Besides improving our flagship product SmartInspect, we’ve started working on a completely new product a few months ago. We aren’t ready to announce what it is just yet, but we will hopefully be able to share some early screenshots and more information in the coming weeks on our company blog. Our next product will be delivered as an installable web application. Similar to applications such as FogBugz or WordPress, customers will be able to download our application and install and host it directly on their servers. We decided to go with an installable version of the product first (instead of offering it as a hosted solution), because we believe that our target market still prefers to host their sensitive data themselves.

One of the first decisions we had to make regarding the product was to choose a development stack. This sounds easier than it really is: there are quite a few requirements that a development stack and platform has to meet in order make it suitable for an installable product. When you develop a hosted solution, you don’t have to care so much about things like ease of deployment, cross-platform support or support for multiple databases. Other requirements such as Unicode support are also a lot easier to implement if you can control every little detail of the run-time environment. So these are our main requirements for an ideal development stack:

  • Ease of deployment
    Because our customers have to install the application themselves, it must be very easy to deploy. The application will of course come with a convenient installer to setup a database, configure the initial settings and so on. However, a platform with complex dependencies should be avoided as it would cause endless support headaches and would make it much harder for customers to evaluate our product.

  • MVC framework
    We have been using different frameworks and patterns for web development over the years and we strongly believe in using the MVC pattern for building web applications. Our ideal web development stack comes with a solid and clean MVC framework to make it easier to build a maintainable application.

  • Cross-platform
    We fully expect that 80%+ of our customers will install our web application on a Windows server (those are still extremely popular for internal application and workgroup servers). However, to make it easier for us to offer hosted trials (or even fully hosted application instances), we also need the application to run on Linux machines. Linux support is also handy for customers with distributed teams who want to host our application on cheap dedicated Linux servers on the net.

  • Multiple databases
    Similar to the cross-platform requirement, our development stack of choice should support multiple databases. Many companies already have a preference for a certain database (because it’s already installed, maintained and backuped etc), so having easy-to-use support for multiple databases is a big plus. We initially plan to support MS SQL and MySQL only, but we might add support for additional databases such as PostreSQL in the future.

  • Support for Unicode and localization
    In an ideal world, every application would have great Unicode and localization support. In reality, though, many applications (and web frameworks) still have a lot of problems with non-Western characters, languages and locales. To make our application suitable for an international audience, good Unicode and localization support in a web framework is key.

  • Safe future and strong community
    Of course, the ideal development stack and platform has a strong and clear future. However, it’s not easy to tell which technologies have a safe future. Open platforms with a strong community certainly have better chances to survive in case the owner or original organization behind it loses interest.

I can already reveal that none of the evaluated platforms and frameworks met all our requirements. Some platforms make it really easy to deploy applications and have excellent Unicode support, but fail the cross-platform requirement at the same time. Other frameworks and stacks provide great cross-platform support, but have really bad support for Unicode.

If you are planning to build a web application yourself, make sure to read the upcoming second part of this series to learn about the pros and cons of the available development stacks and platforms (if you haven’t subscribed to this blog yet, here’s the feed). I will also reveal which development stack we have chosen and explain the reasons behind the decision.

12 Practical Tips for Building Bug-Free Software

By Dennis Gurock, February 3rd, 2009

Has your software bugs? Of course it has, every software application that’s out there has bugs and bug-free software is a myth. But it’s still possible to greatly minimize bugs, security problems and errors in your application by following a few simple tips and techniques.

Some studies claim that up to 40% of system failures are caused by software bugs and that common memory and concurrency related bugs account for 60% of system vulnerabilities and security problems. Even if it were less in reality, reducing software bugs in your application is the best way to increase the stability, reliability and security of your software.

During the development of our logging tool SmartInspect, we used many techniques to keep the quality of our product high and the following list contains some of the techniques we use. So without further ado, here’s our list of 12 practical tips for building bug-free software (or at least software with fewer bugs):

1. Code Reviews

Four eyes see more than two. That’s why you should let other developers review your source code on a regular basis. Pair programming on the other hand, a technique where two developers write code together for longer periods, isn’t for everyone and is often not needed. But complicated, critical or security related code greatly benefits from code reviews and will improve your code quality a lot.

2. Beta Tests

Beta tests play an important role with keeping your software’s quality high. Although it often doesn’t make sense to release beta versions for minor updates, major releases with many changes greatly benefit from tests by end-users and customers. You can test your software as much as you want, if you cannot control the execution environment of the final product, chances are high that end-users will have issues with all the different computer configurations out there. Also make sure that your software has reached a high quality standard before releasing it to beta testers. You don’t want to waste the testers’ time by letting them find and report bugs that you already know about.

3. Automated Tests

Automated tests like unit tests or automated GUI tests can be used to verify the functionality of application modules, application programming interfaces (APIs) and user interfaces. You don’t have to be a test-driven development wizard to make good use of automated tests. Using unit tests for key parts of your application can go a long way towards building more reliable software. There are tons of unit testing frameworks, web and GUI testing tools out there that you can utilize.

4. Logging

Using log files or live logging during development and production usage is a useful technique to identify bugs, find concurrency problems and fix the root cause of application crashes. Advanced logging tools are also able to log entire objects, trace threads and offer rich viewer tools to monitor your application. Instead of writing yet another basic logging framework, you should give a proven and advanced library a try. Many open-source and even some commercial offerings have been released over the years, including our very own .NET, Java and Delphi logging tool SmartInspect.

5. Error Reporting

To find and resolve errors and exceptions, you first have to know what kind of errors your users and customers are experiencing. Most trial users won’t get in touch with you to report errors. Instead, they will just uninstall your application and test a competing product. To make error reporting for end-users easier and more useful to you, you should add automated error and exception reporting to your software. Desktop applications should show a friendly dialog offering the user an option to send an error report back to the developer every time an unhandled exception occurs. Hosted web applications can automatically send or log an error report without user interaction. Error reports should contain all the information you need to identify problems, including error messages, call stacks, version numbers and log files.

6. Customer Feedback

Similar to error reporting, you should make it as easy as possible for your users to provide feedback. In SmartInspect, for example, we have buttons in the menu and toolbars to send feedback and questions. You can also use a quick (optional) survey when a user uninstalls your application. Such a survey should only have a few questions and ask for a reason the user uninstalled your software. If a lot of users report that they uninstalled your software because of stability problems, you will know that your application isn’t as high-quality as you have thought.

7. Use Proven Code

You should build the core functionality and main features of your applications yourself, because only then are you able to easily and quickly modify and improve it. But for some parts of your application, reusing existing and proven code might make sense. For example, it would take years to build a stable, easy-to-use and feature-complete reporting engine if you have a need for it. In such cases it’s often better to use existing code, either from internal libraries, third-party companies or open source solutions if the license permits this. However, using a lot of third-party code can also have its downsides. It makes upgrades to new versions of your development platform harder, increases your dependencies on other people’s code and will most likely introduce bugs that are hard for you to fix, as you are not familiar with the code.

8. Dedicated Testers

If possible, you should have dedicated testers in your organization for quality assurance. In fact, you should probably have lots of them. For simple standard applications, one tester per developer is a good rule of thumb. For applications that are complicated and time-consuming to test, two or more testers per developer are more applicable. Many small organizations cannot afford dedicated testers. If this is the case, developers should test each others’ code. It’s important that others test your code and functionality, because general wisdom says that developers do a really bad job at testing software and functionality that they wrote themselves.

9. Virtualization

To test your software on all supported operating systems and software combinations, you can use virtualization tools such as VMware or Virtual PC. Besides allowing you to test your software on all kinds of configurations, you will save a lot of time because you can easily copy, share and reset the virtual machines. It’s a good idea to create a few base images for all the operating systems you regular test on and put them on a file server. When you need a new configuration to test something, you can then start with one of your base images without first installing the operating system, drivers and required software.

10. Design Your Software

Many software quality problems are caused by badly designed class hierarchies, inaccurate interfaces, wrongly understood requirements and resulting workarounds. That’s why you should design and plan key parts of a module or application before writing the first line of code. You should also refactor your code as needed if requirements change during the lifetime of a software application. Also make sure to update any documentation or specification you have, because there’s nothing more useless than outdated documentation.

11. Use a Good Debugger

If you use an IDE like Visual Studio, Eclipse or Delphi, you already have access to a powerful debugger that you should make use of. But with some programming languages such as PHP, Python and Ruby, many developers aren’t using a debugger but rely solely on print statements and logging. While logging is certainly useful (see above), it’s not a complete replacement for a debugger. Do yourself a favor and get a good debugger for your development platform that you can use to step through your code, set breakpoints and inspect variables. There’s a good debugger for almost every platform and language out there.

12. Debug and Strict Options

Many development environments allow you to enable special debugging options such as range checking, overflow checking and memory corruption checking. Such options should be enabled during development and sometimes even while testing your software, as it makes identifying some complicated bugs a lot easier. Most dynamic languages like Perl or PHP also allow you to enable certain rules and warnings to enforce variable declaration before using them. This is especially useful if a language is case-sensitive and it’s easy to make typos.

The above mentioned tips won’t make your software magically bug-free, but they allow you to make your software a lot more stable, reliable and usable if used correctly. And on top of it, they will make you a better developer, too.

This article is based on a posting I previously published on the Gurock Software blog. As the tips are still relevant I decided to republish it here.