'''Claim:''' "MicroSoft COM/DCOM/COM+ is complex, difficult and hard to use." ----- See also: MicrosoftTransactionServer, ComponentObjectModel, DistributedCom, ComIsLove, ComPlus - ComIsNot - BarbiePrinciple, MathIsHard. ----- ''[Much of the following text was moved from TheMostComplexWhichCanBeMadeToWork. January 2000.]'' ----- '''The following is about DCOM, I presume:''' I spent the summer of '98 working with COM and found it to be very hard to work with. COM makes easy the part of distributed computing that was ''already'' easy - marshalling - at the cost of making everything else hard. Specific problems: * I never found a way to specify the network timeout, which defaults to something like 3 retries at 40 seconds each - a very long time. We had to add threads to take care of that, making the application much more complex than it should have been. * I found it difficult move a COM object from one machine to another. It's easy to move a reference, but you have to write code to move the actual object. Contrast with Java, where serialization makes it a breeze to move an object. * COM reference counting is clumsy and error prone. * COM is rococo, with new layers and capabilities added ad-hoc. It lacks a single rational, unified interface, and instead has at least 3 interfaces (raw COM API's, CCom classes, and ATL templates). What's worse, when working in one layer, you frequently are required to reach down into the lower layers. The layers have holes in them! I will freely grant that without enough training and practice, or if only I were smart, I could have worked past these problems. However, I spent six months working on this technology and never felt that I really *understood* what it was doing. That bothers me. Most other things I've learned (C, C++, templates, OOP, patterns, Java, assembly, etc.) didn't present that steep a learning curve. Investing in technologies that I understand is more than just wishing I were smarter - it also means that the applications I write are more likely to work. -- WayneConrad ----- ''Regarding comments from WayneConrad, above...'' * ''"COM reference counting is clumsy and error prone."'' Not an issue anymore. ATL does it automatically. COM+ handles it. * ''"COM is rococo, with new layers and capabilities added ad-hoc. It lacks a single rational, unified interface, and instead has at least 3 interfaces (raw COM API's, CCom classes, and ATL templates). What's worse, when working in one layer, you frequently are required to reach down into the lower layers. The layers have holes in them!"'' ----- I will always have a great deal of distrust of any technology that I can spend six months working with and still only feel like a user of the technology. If I can't understand what's going on under the covers, I can't possibly debug my code effectively using anything other than trial-and-error programming. I really hate releasing code when I've worked around a bug but I don't know ''how''. I always have the haunting feeling that it's still there, ready to bite me. When I said that COM has multiple interfaces, I used the wrong word - I should have said API's. It does have multiple API's, and that led to a lot of confusion on our part. Jumping up and down the level of abstraction, as you called it, was hard - I felt like I was having to learn and master 3 API sets at the same time. I'm positive I don't understand you when you say that having all COM interfaces derive from IUnknown "leads to a well architected system in which additional interfaces can be easily added all deriving from IUnknown." Having a common interface for all classes does nothing to get you a well architected system - all it does is get you a common interface. Well architected is something that comes from you designing a set of classes properly, not from a common base class. In Java, all classes are automatically derived from Object, but I've seen plenty of poorly architected code in Java. No language or pattern automatically gives you good design. -- WayneConrad WayneConrad said (in reference to working with COM): ''I really hate releasing code when I've worked around a bug but I don't know how.'' Wayne - I pulled this out and highlighted it, because my team has been faced with exactly this problem. We've had a lot of trouble getting COM components to work on test machines, even though they worked fine on development machines. Eventually, we get them to work on the test machines as well, but we rarely were able to identify the exact problem. Maybe once the problems are fixed they'll stay fixed, but who knows? -- CurtisBartley Of course we registered the components. Multiple times. (Handy tip I learned at MS - put RegSvr32.exe on the send-to menu). The components still didn't work. For one particularly problematical DLL written in VB, we resorted to completely scrubbing the registry of every entry (there were many) referencing the DLL. We eventually got the DLL to run, so the registry scrubbing may have helped, but we don't really know, which is the main point. -- CB'' I don't think the problem is COM, but Microsoft's COM libraries. FluxOsKit uses com and does so very cleanly, IMO. -- PanuKalliokoski ----- Quicker than putting the send menu, we just have RegSvr as the default app for DLL and OCXs for when you are registering a whole bunch for the fifth time. -- David Bowen ----- I don't understand why people are having this much trouble with COM. Forget DCOM, just COM. Well, personally, I've found that not only does AppWizard give you a big boost, but I read InsideCom. InsideCom is an amazing book. Unlike other technology how-to books, it takes you through the construction of the theory behind COM. It even examples the Handle/Body idiom and how to handle self-assignment properly. -- SunirShah ---- I used to be a profound follower of Mr Box's ComIsLove philosophy, but since discovering Java I've never looked back (and if I had to do COM again, I'd ditch my 100% pure principles and use VisualJ++ to build my COM objects. :-) I found Don's books (EssentialCom and EffectiveCom) to be the only books that really hit the nail on the head for me. Inside COM was okay, but the Brockschmidt book nearly killed me. :-) -- AlanFrancis ---- I wholeheartedly agree. I've put a few people onto COM here at work (scared to admit that in public in case the Java lobby stone me :-) and the article ''From CPP to COM''[1] by Markus Horstman and ''Essential COM'' are the only two things I recommend. Almost everyone has had panic attacks seeing my copy of the Brockschmidt book on my shelf (not MyLowestBookshelf :-). Once I show them the ten or so pages of the ''CPP to COM'' article, and they understand it, and I tell them they understand COM, they're more than happy to read the Box book :-) -- AlanFrancis ---- ''COM = COM+ = MTS.'' But is that really true? MTS provides transactions, doesn't it? Isn't that a terrible overhead for components that have no need of transactional semantics? Are COM components such as those in the Windows Media Framework (DirectShow aka ActiveMovie aka Quartz) also going to be run within MTS? -- NatPryce ''It is true. However what's not true is the common myth that all MTS does is provide transactions.'' ''The myth can be blamed on the naming of the technology, who's primary goal was originally to add transactional capability to ComComponents. However, MTS has always offered more than that (Security, FaultIsolation, LocationTransparency, etc.). Now in ComPlus, MTS is really no longer a separate entity. All that MTS offered on top of COM simply becomes another set of attributes for a ConfiguredComponent.'' -- DrewMarsh ''MTS is a wrapper, object pooler, transaction broker, and jack-of-all-trades for COM on NT 4.0 and prior. ComPlus is just a new name for MTS on Windows 2000, with some gratuitous API and nomenclature changes as well as a few possibly useful improvements. So ComPlus == MTS but both are supersets of, or enhancements on, plain COM. I'll take DrewMarsh's word for it that "MTS is really no longer a separate entity." I thought it still had its own object browser and API sets that don't apply to non-ComPlus objects, but I could be wrong.'' -- MarkSchumann ---- ''Such InProcessComponent''''''s are not often placed into MTS because it offers no advantage over a plain-vanilla configuration. While it '''is''' possible to set an MtsPackage to run as a library instead of a server, it offers no value other than the fact that you can see your components grouped together in a little box. ;)'' ''Such ComComponents do not require services such as transactions, security roles, and isolation. There '''is''' an overhead for running under MTS (check MicrosoftTransactionServer for details).'' -- DrewMarsh ----- For an opinion of a few years back: http://www.informationweek.com/689/89uwtb.htm ---- The easiest way to learn COM / DCOM (at least from a CeePlusPlus perspective) is to simply start writing ATL code and forget about the books. I also find I prefer some of MSVC compiler extensions for DCOM (such as its smart pointers) to their ATL counterparts. You can get a lot of reuse with ATL and you can get generic enumerators, universal delegators, parameterized SAFEARRAY wrappers and all kinds of stuff on many of the COM and ATL centric web pages. For what its worth, I was confused by the books until I just started writing code. -- RobertDiFalco ''I agree. There a lot of horrible COM books out there. And the fact remains: Many of them have never written production code. I also believe one should just start writing code in ATL. Just say NO to MFC! I also favor using the MSVC compiler extensions as they do more than their ATL counterparts. So I will usually use _bstr_t instead of CComBSTR. Yes, you can get a lot of reuse out of ATL, including even UI code. Thus, the advent of WTL, which should hopefully kill off MFC for good (at least for new development).'' -- sg ''which should hopefully kill off MFC for good (at least for new development).'' Amen. I hope Microsoft enthusiast and haters alike can join in with my mantra that MfcMustDie -- RobertDiFalco ''I also agree. The smart pointers are rather useful once you get used to their ctor and initialization syntax, which isn't that hard.'' -- MarkSchumann ----- A long time ago, when learning mainframe technologies, everyone I talked to said that "JCL is hard," that it's very difficult to learn. I learned it, and found it easy. You see, many people confuse JobControlLanguage (JCL) with the programs you can run using JCL, thinking that the complexity of the parameter requirements for all the programs they could possibly run were complexities "in JCL". COM is the same way: COM is easy. ''(And ComIsLove. ;-)'' But you can do many things with COM. Many of the things you can do with COM are difficult and complex. If you want to do something simple, doing COM instead of CORBA, RPC, or something else does '''not''' make it complex. -- JeffGrigg ----- Sounds like many of your problems with using COM are to do with how Visual C plus plus implements it. I have found it much easier to do COM stuff using BorlandDelphi. It's also easier to convert a DCOM multi tier system to a CORBA one with Delphi too. -- SteveEyles ----- I have never programmed in COM. However, a lot of my students have. In fact, for four years in a row, a group of students in the "senior project" course used COM in their project. These groups seemed to be at least as talented as our average student (the weaker students were scared away) but the groups had much more trouble than average. They worked on the project all year. By Christmas none of the groups had accomplished much, and usually only a couple of the students said they understood COM, but by May they all said they understood it and they had gotten half of their project finished. After four years of this, I had gotten skeptical of COM. This year (the fifth), when the group using COM gave a presentation in the beginning of November, I was astounded. They had done more than some of the groups had done by May! They had used C#, not C++, and were really programming on .NET rather than COM. -RalphJohnson ---- From having programmed in COM/DCOM for just over 5 years, I would list the following difficulties. * The security model is not well documented nor supported by installation tools. One must either provide a detailed list of steps going through OLEVIEW and DCOMCNFG or write a custom program to generate ACLs (access control lists) based on nearly undocumented APIs. * The versioning model is not consistent between C++ and VB (and not even followed by Microsoft). In C++, One can either add to an interface (without adverse affects) or derive a versioned interface. In the latter case, one must edit the undocumented IDL format. In VB, the issue is confused in that VB reuses the same name for the class and different versions of the interface (the names are differentiated through placement in the registry and different GUIDs) when one relies on Binary Compatibility. The VB alternative is the implements declaration used to define a new, independent interface. * Interface names are resolved differently when running locally under COM and remotely under DCOM. This can wreak havoc when one needs to provide backward compatibility from newer server code to older client code. Testing on one machine is not sufficient, one must build and deploy components to the server. * Reference counting does not appear to be an effective way to manage memory, even when smart pointers are used. Objects with bidirectional or circular links will not be deleted from memory. A client created object linked to a server created object will block the server object from being deleted from memory. * Component registration does not provide sufficient isolation between client and server. To register the server component on the client requires the component dependencies to be installed on the client as well. We had limited success in creating Proxy/stub files in C++, but never found out how to do them in VB. All of the above could have been eventually resolved, had Microsoft not lost interest in COM/DCOM in favor of .NET. ''COM and COM+ ''are'' being carried forward into .Net technologies. See ComIsLove'' ---- ''For an opinion of a few years back: http://www.informationweek.com/689/89uwtb.htm'' From the above-mentioned website: ''DCOM doesn't natively provide any way to interact with objects. Instead, it lets us interact only with a list of functions, the same way that Cobol or Basic always has.'' Silly me for thinking this, but, isn't that the whole ''point'' of object orientation? You know, that whole ''encapsulation'' bit? You're not ''supposed'' to manipulate objects ''directly.'' Interfaces is where it's always been. :) (For what it's worth, I had implemented the GCOM project, an open source, in-process-only COM implementation for Linux, and Project Andromeda for Amiga, Inc. under Fleecy Moss, which was based on GCOM. I also very much enjoy CORBA. It's tough for me to say which is better. But it ''burns me up'' when I hear inappropriate statements about COM or DCOM, no matter how much I feel the technology is inappropriate for some reason.) Also, if you ''truely'' want to learn what COM is all about, write your own implementation. It really isn't hard. In fact, ''do it in CeeLanguage.'' Literally everything will become patently clear then. ''If you want to do something simple, doing COM instead of CORBA, RPC, or something else does '''not''' make it complex. -- JeffGrigg'' Agreed. Being familiar with both CORBA and COM, I prefer COM for most programming tasks. CORBA is one of those things that is "just right" for when you have a heavy-weight problem to solve. CORBA's difficulty-vs-problem graph is a shallow line; simple tasks are complicated, but ''really'' complicated tasks are not much harder. This suggests the complexity of CORBA is all boilerplate, and that's very much true. COM is a steeper curve/line. Simple things are ''simple'' in COM. Complex things are more complex in COM, and complexity rises more steeply than with CORBA for a given project scope. Design and ProgrammingPatterns can alleviate some of the complexity, but there will come a point when CORBA is better than COM for the task at hand. For example, for ''plug ins,'' you simply ''cannot'' beat COM. CORBA can handle it, theoretically, and with much consternation, and in a completely non-portable way, because multi-language, in-process use-cases were simply never a consideration for the OMG committee. They took a very heavy-weight, Unix-process-bound point of view. COM, on the other hand, takes just the opposite approach. Memory management with COM isn't hard either (though it is runtime intensive). Here is the cardinal rule: ''NEVER use cyclic references.'' If you cannot guarantee this, then you're misdesigning your software. I would like to note that cyclic dependencies in module imports in most languages are equally impossible, yet ''they'' seem to get by just fine. They do so by expressing relationships with ''edge objects.'' This results in a forced decomposition of the cycle into a pure hierarchy, with the "relationship" object mediating the binding between the two. There are two real-world cases of this: Microsoft's proposed ''inner objects'' result in an unbalanced tree of references, and CORBA's Relationship objects (oddly enough, contained in their ''life cycle management'' standard!) produce properly balanced trees. Which method is better depends on context. Where COM does have difficulty over CORBA is the conveyance of ''exceptions'' (as distinct from ''errors''). For methods that return interfaces, this is easily solved by just returning an IUnknown that supports some kind of IException interface. This is ''no worse'' than C-style error checking. Alternatively, you can pass around an exception reference to each method that can potentially return an exception (this is the approach that CORBA's C-language binding uses). This is slower at run-time, but produces somewhat cleaner code that more or less works just like real exception handling. Kind of. But, for those methods that do ''not'' return an IUnknown of any kind, you're pretty much limited exclusively to using either HRESULT values or the explicit exception structure method. --SamuelFalvo ---- CategoryComponentObjectModel