Most software projects start with an architecture. And most architectures are “stacks” as in “this is what our stack looks like.” This is where middleware, tools, languages and the like get decided. Two interesting things happen here.
The first is the “platform wars.” Vendors of middleware and tools are very interested in which stack gets adopted, since that is what generates their revenue. As a result they and their “ecology” (the other vendors who are dependent on the platform) promote the virtues of their “stack” over the other available options. By the way, there aren’t one or two “stacks” but there are some families of stacks, for instance Java and .NET have each engendered stacks, but there are variations on stacks due to databases, or functional components such as ESRI’s ARC GIS or Primavera’s Project Management Suite. The result of these wars is to be very exclusionary. Once you select J2EE you won’t be hiring a lot of .NET programmers.
The second interesting thing is “stack dependencies.” The stack looks so neat. You pretty much accept the whole thing. One of the things that caused it to win over the other stacks was “integrated functionality.” However, it’s this integration that causes lock-in and all kinds of other problems. Maybe you’ve selected .NET and ADO.NET as part of your stack. Now you probably have MS SQL, and initially it’s not a hard dependency, but you start to rely on the integration and pretty soon you’re locked in. This tight integration within a stack actually gets in the way of integration across stacks (between your applications).
Now, I’m not suggesting you build applications without middleware tools or languages (that’s even too good for me to believe). What I am suggesting is in as many places as possible your stack says “Don’t Care.” As in “I don’t care what you do in this part of the stack.” If you follow through with this you’ll get flexibility at a pretty low premium.