Closed Minds, Open Source: Software Cycle Prejudice

Most economic theories are merely dogmatic prejudices which become meaningless in the real world. Nothing stifles our economy more effectively than attempts to apply any single economic theory to everyone in all cases. Instead, real economies must be driven by a combination of compromises struck between opposing forces. Ultimately, it is hard to prove that any one economic theory works to the exclusion of all others. But one can see that there are moral differences between theories.

To illustrate this point, I’ll look at various software release cycles, and see how they are affected by prevailing economic theories. I’ll start by defining in a very general way what we mean by a software cycle. Software products are shipped in cycles. A typical cycle would include at least one iteration of the following pattern: outlining new features, fixing bugs, testing new code, then shipping the product. The next cycle would repeat the same process.

Overview

The economic theories discussed in this article are:

  • Free market economies: Here companies compete against each other for market share. In a Darwinian world, only the strongest can survive.
  • Free software: Here people create software for free, and only the needs of users determine which software will thrive.
  • Monocultures: In these markets one company has a monopoly, and no real competition exists. For the purposes of this article, any company that has a 90 percent market share in a particular area will be considered to be a monoculture.

Here is how software cycles are dictated by these economic theories:

  • In free market economies, we are told that economic pressures drive release cycles: Products must ship at certain dates and times to bring in needed revenue, and feature sets bend to conform to schedules.
  • The free software movement, on the other hand, does not have the same economic pressures. It is not forced to ship on a particular schedule, nor are its features sets dictated by economic pressures. Instead, free software ships when a product is ready, and feature sets are dictated by demand, not be enforced schedules.
  • Monocultures, because they exist in a world without competition, can work on the same wide open schedule as the free software movement. They ship when they are ready to ship, and they contain the features that the monopoly deems important or useful.

What does all this tell us about open source software, free software and the free market? Seemingly unquestioned conventional wisdom says that unfettered free market competition is the best possible system because it creates the greatest good for the greatest number of people. It is the best way of motivating people to create both products and wealth. All other systems are supposedly doomed to failure by definition.

Since neither Microsoft nor the free software movement participate in a free market, what does their success say about this economic theory? How much of what we believe is simple prejudice, and how much is founded on events that take place in the real world?

New Features in JBuilder 2005 Part II

The debugger has added a new view to make it easier to look at the values of common collections like List and Map. This viewer displays the selected object as an array. To use this custom viewer, right-click a Map or Collection object in the Threads, call stacks and data view or the Data watches view. Choose Show Custom View, then toArray(java.util.Collection). The object is displayed as an array.

 

The toArray() view of a List in the Thread view.

The debugger also has a new feature: Quick Step Into. The Run|Quick Step Into command steps directly into the first parameter in the method signature, rather than stepping through the called method. This is also a button on the debugger toolbar.

Debug Ant build files!

Each version of JBuilder adds more and more support for Ant. Two of the most exciting features of JBuilder 2005 for heavy Ant users is the promotion of build files to full blown designable artifacts and the ability to debug Ant build files. When you select an Ant build file in the editor, you see a property view on the right-hand side, just like the other design artifacts in JBuilder.

 

Ant build file properties have a property editor now.

You can also debug Ant build files now. Click in the left-hand margin (just like a Java source file) and select Debug from the right-click menu on the build file. The Ant debugger shows the current line being executed along with a view of the build file with the current line highlighted.

 

The debugger provides lots of feedback while debugging build files.

Help Search

One of the welcome productivity enhancements in JBuilder 2005 is a greatly improved Search tab in the help files. The left-hand pane offers a wide variety of options to search within the extensive help documentation.

 

JBuilder’s Search for help has greatly improved.

Designer Changes

The entire design surface for Swing and Micro development has changed in JBuilder 2005. The component palette now appears on the left of the design surface (rather than the top) and features a new compartmentalized palette.

 

The visual designers have been updated.

You can now perform an incremental search for a component name at the top of the palette. This makes it much easier to locate a component if you know its name but can’t remember what tab where it resides.

Refactoring

Refactoring quickly becomes a must-have feature for developers, and if you must use an IDE for any time that doesn’t support it (i.e., any non-Java IDE), you sorely miss it. JBuilder has always had strong refactoring support, and it has just gotten better in JBuilder 2005.

Improved Refactoring Menu Structure

All refactorings have now moved into their own menu structure, and context sensitive refactorings appear in the right-click sub-menu in the editor.

New Refactorings

You can rename refactor class names when working in a deployment descriptor file. To do this, right-click the name of the class you want to refactor, choose Refactor To Class, and enter the new class name. When you complete the refactoring, JBuilder will rename the class in all locations it is used and referred to, including deployment descriptors.

Distributed refactoring

JBuilder now records completed refactorings for the current project. You can add this history to the project archive, making the history available to other projects and libraries that were not available in the initial refactoring. You can use the history to easily update projects that depend on refactored external APIs, SDKs and libraries. This feature is called distributed refactoring. To use distributed refactoring, you must first add the refactoring history to the depended-upon project or library’s archive. When you open that depended-upon project or library archive from the dependent project, you can then review all refactorings with the Refactoring History. You will first refactor your project globally so that all files in the project are updated to the new code symbols. You can then use ErrorInsight to refactor any remaining instances of out-of-date code.

Adding the Refactoring History to the Project Archive

You can add the refactoring history to the project archive, so that others who view your project can see what refactorings occurred. They, in turn, can use the Pending Refactorings and Refactoring History dialog boxes to update their code. To do this, choose the Archive Builder (File|New|Archive) for the type of archive you wish to create. On the Specify Refactoring History To Provide page, choose one of the following options:

  • Select the Do Not Include Refactorings option if you do not want any refactoring history added to the archive.
  • Select the Include Content Related Refactorings to add refactorings only in classes that you are adding to the archive. You can use this option if not all classes are being added to the archive.
  • Select the Include All Refactorings to add all refactorings for all classes to the archive.
Refactoring History

The refactoring history is displayed in the Pending Refactorings and Refactoring History dialog boxes (Refactor|Pending Refactorings or Refactor|Refactoring History). Pending refactorings are refactorings in the depended-upon project or library that have not yet been applied to the current project. The Refactoring History dialog box displays a list of all refactorings that have occurred in the current project or in projects or libraries that this project depends on. You can see refactorings that might impact your code and then choose to invoke those refactorings to update your code. You can then choose a refactoring with the Refactor button and invoke that refactoring on your code.

Refactoring to an Existing Symbol

Once you’ve determined that your code is out-of-date, you can refactor your code to an existing code symbol. To do this, you can:

  • Open the Pending Refactorings dialog box (Refactor|Pending Refactorings) and choose a refactoring to invoke, or
  • Open the refactoring history (Refactor|Refactoring History) and choose a refactoring to invoke, or
  • Click the ErrorInsight icon in the gutter next to the outdated symbol and choose the Refactor To command
JDK 5.0 Refactorings

JBuilder now supports JDK 5.0 refactorings that update code to use JDK 5.0 language features. The following refactorings for JDK 5.0 code are supported:

  • Foreach refactorings: Foreach refactorings refactor existing loops to JDK 5.0-style enhanced loops. You can refactor the following types of loops:
    • Array traversal
    • List traversal
    • Iterator for loops
    • Iterator while loops
  • Auto(un)boxing refactorings: The autoboxing and auto-unboxing features in the JDK 5.0 allow you to easily convert between primitive types and their Object-based counterparts.
  • Generics refactorings: JDK 5.0 introduces the use of Generics. Generics add compile-time type safety to the Collections API and eliminate casting. In JDK 1.4 and below, an Object would need to be cast to the appropriate type before usage. With Generics, the need for casting is eliminated.

Here is an example of the Introduce Generics refactoring. Here is a method that iterates over a list of Employee objects, calling an applyRaise() method for each:

Code that Applies Raises


    public void raiseSalaries(List emps) {
        for (int i = 0; i < emps.size(); i++) {
            ((Employee) emps).applyRaise(5);
        }
    }

Now, I’ll apply JDK 5 refactorings for three things:

  • Change the list to Generics
  • Auto-unbox Employee objects
  • Use a foreach loop

For each of these refactorings, I select the code in question and invoke the refactorings.

 

The Introduce Generics refactoring dialog.

The resulting code has changed to this method:

Refactored Code that Applies Raises