A site devoted to discussing techniques that promote quality and ethical practices in software development.

Sunday, April 12, 2009

Dissection of an amateurish COM business solution

There is a company which should remain nameless specialized in enterprise business application managing inventories, purchasing, work order, etc. the typical business operations. This blog post is to dissect this solution to demonstrate the:
  • superficiality of this company in the COM technology
  • wrong choice of architecture.
The dissection does not require access to source code because they are using COM, a industry wide interop standard that requires publication of the interfaces specification. This post will show you the free tools you need to see the laughable implementation. I will also offer integrator advice on controlling the rogue COM programs in future posting.

Program structure

The actual names of the programs are also altered to save the embarrassment. This program uses executables gratuitously and was first described in my previous post. It has a controller program, much like Windows Explorer, that can launch their business applications. Each business application, fictionally called M100, M200, M135, M500, etc are COM local servers allowing the controller to communicate with it and to allow inter-application communication.

The program uses Delphi3 and this is an important fact as it will become obvious. Naturally, they all have the Delphi's COM Server bug which can be observed using Process Monitor.

Their technical lead/designer knows this much that each application must implement a common interface, called IXyzApplication in order to meet the above stated objectives. But it is shown below that their modus operandi is not only naive and amateurish showing complete lack of understanding of COM but also their developers lack proper training and mentoring. In reality they have failed to meet the objectives to implement a common interface.

To dissect this program you will need to use the free tool called OleView, which is part of Visual Studio of any version or can be download from Microsoft.

The analysis

With this enterprise business application installed, it is time to use the OleView to examine the implementation defects. If you expand the interfaces tab and scroll down until you see the IXyzApplication, you will not be encountering just one entry of IXyzApplication but you will see at least 130+ copies of this interface. If you click on each IXyzApplication, the right hand pane will tell you the server supporting this interface, its type library and the COM identity.

In fact, the reason there are so many IXyzApplication is because each one of them:
  • has unique IID, thus making them unique; the name is only for human consumption and essentially irrelevant.
  • each one of them is supported in their individual business application.
In effect, they should rename the IXyzApplication to IM100Application, IM120Application, IM500Application etc to be precise.

This laughable situation is not caused by the the developer's fault but a management's fault; management has failed to provide technical leadership of sufficient caliber to guide their developers and to review their work. Their technical leaders also fail to provide structural infrastructure to allow their developers to implement this interface in their business applications; their current implementation also publishes unique IXyzApplication interface as well as implementation in each business application.

Obviously, to the management, it does not require much training to use Delphi3 IDE that so easily can produce a COM application with several keystrokes. Wow, could this be the silver bullet that has eluded Frederick Brooks [BROOK]? Don't think so and will be unveiled.

Furthermore, to their untrained technical leaders with only superficial understanding of COM, the Controller can talk to their business applications and that they are all named as IXyzApplication in each application. So isn't that fine? Not quite.

Using the OleView, we can disassemble the registered type library into IDL, Interface Description Language, to see a much clearer definition of the IXyzApplication. Here are the points to be noted:
  • IXyzApplication is derived from IDispatch interface
  • IXyzApplication is declared as dual interface
  • IXyzApplication has distinct guid for the interface.
For the moment we will forget some of the more ambitious ones, which violate more COM practices. Drilling into their COM characteristic further and comparing several IXyzApplication you will also noticed that:
  • The same method name can have different method id's in different business applications.
  • Some IXyzApplication's have different set of methods.
  • Some IXyzApplication has more methods.
  • Some has a different method in a method id that is used by others.
In other words, these developers only believe using the same interface name is all that is required. They obviously has no basic idea of COM and they are poorly served by their incompetent technical lead/architect in not providing a single definition of IXyzApplication with which they can implement it. They have no clue on the concept of implementing an interface and publishing an interface.

Digging around the installation area and using OleView reveals that they appear to have interfaces publishing DLL that they could and should include IXyzApplication there. For some unknown reason they did not. Perhaps that is out of the ordinary task supported by the IDE and that they cannot handle this.

Standing back from this problem, one wonders how the controller can communicate to all these business applications each with a unique IXyzApplication interface? The answer further illuminates their total ignorance of COM.

In order for the controller to work and for business applications to talk to another one via the 'IXyzApplication', they are not using IXyzApplication but using the following technique:
  1. They are actually using dispinterface via the IDispatch interface, the base interface of IXyzApplication.
  2. They are using a language/framework that does not cache the method id.
Reason 1) is supported by the fact that there is only one definition of IDispatch belonging to Microsoft but there are at least 130+ 'IXyzApplication'. In order words their declaration that their interfaces supporting dual is incorrect or at least superfluous.

Even allowing the client/server to be using IDispatch calls, the haphazardly assigned method ids and missing ones would have play havoc to client that caches the method id.

The only reason that their Delphi solution works is because Delphi does not cache the method id at compile time, unlike those using Microsoft Foundation Class/ATL or Visual Basic 6. Using cache id is perfectly acceptable because COM spec demands the consistency in method id assignment and there is only supposed to be one and only one IXyzApplication. Basically Delphi will call IDispatch::GetIDsOfNames() followed by IDispatch::Invoke() to call each IXyzApplication methods.

Using this inefficient dynamic technique ignoring the COM interface specification is the only way to deal with a haphazardly assigned method ids.

While the solution 'works' albeit in a very tightly coupled to a particular tool that happens to use an inefficient implementation, it means that it has completely destroyed the benefits of an opened industry-wide interop standard, such as COM.

It fails to use a more efficient call mechanism, such as v-table call supported by dual interface that the IXyzApplication has adored with. It cannot possibly use IXyzApplication because which one is to be used? There are 130+ IXyzApplication. The management of this company does not understand the fundamental of COM; it is not the name that matters in COM; it is the guid. If the guid is the same, then it must be the same interface regardless what you call it. Their mistaken belief produces such a laughable solution.

Secondly, it fails to support interop in a wider sense supported by COM. Their action prevents their customers from writing custom controller or to interop directly to those business applications in other tools than Delphi; COM is a language and tool neutral interop technology. However, there is a way to do this without using Delphi as a client and that is the subject of a future post.

As a result, the customers are the poor losers in this sad affair. If this software is a car, some form of medicine or financial instrument, I am sure the company responsible for this will be prosecuted for misrepresentation of the facts or producing unsafe product. But in software, this is masqueraded as innovation!

The company has not found a silver bullet; they have only addressed incompetently the accidental part [BROOK] of software building as their product has demonstrated unequivocally.

Frederick Brooks, "No Silver Bullet - Essence and Accidents of Software Engineering", IEEE Computer, April 1987.

No comments:

Blog Archive