During my lifetime (so far) of programming I've worked on a many projects that were built around or including external libraries and components. These are packaged units of software purchased from a vendor for a specific purpose. However, no matter how useful the software claimed to be, the specific purposes these packages were designed for never quite matched the specific purpose we were attempting to apply them to.
Never having been directly involved in these purchasing decisions I can only imagine the reasons that led to them. I suppose it must have seemed like the easy way out. Instead of building up expertise in a particular domain, you could just buy that from someone else, plug it into your project, and away you go. The costs of these libraries were minuscule compared to the cost of the expected effort that would have gone into rolling our own. And no matter how many times I'm certain this all must have seemed the truth, the reality was far from it.
Because the software never actually did exactly what we wanted it to. Maybe 70 to 80 percent, sure, but never all that we wanted and so we had to compensate for what it did not do. Now, this would not have been such a big deal if the package was designed for extensibility from the beginning, but not many were, and even those that were often allowed extensions only in areas we cared not to go. So, in order to actually get what we wanted we had to work around the flaws ourselves.
Usually, this lead to a lot of trial and error, building advance frameworks to augment or encapsulate the purchased piece, that often solved many of the shortcomings, but never quite all of them, and certainly not the most critical. Eventually we would reach the conclusion, over many months, that the only plausible way to achieve our goal was to modify the actual source code, of which we did not have.
Now you might think that we ought to have abandoned ship at this point, to just take our lumps, learn from the experience and move on. We would most certainly have gained enough knowledge to understand exactly what we wanted and would have been able to build it ourselves. That might have even been true in some cases, but not entirely practical. As the project evolves you only learn about its true cost as you forge onward, only aware of any additional costs after you are so deep in that backing out still seems more costly than plugging ahead. Of course, you never really appreciate the full cost until much later, and by then it is just too late, you've used up a year or two and it is time to ship your product.
Of course, if you flash enough money you can convince any vendor to turn over the source code, provided you are not going to resell it, etc. And that's usually what happened. We'd pay handsomely for the rights to modify the code, and we would do it, fix what we did not like, add what we needed and be done with it. Our product would ship. We'd have a party and then relax for a few days. And then we would hear about the big dreams for the next version, the new features and purchases already made.
I suppose that's why I sort of chuckle anytime someone talks about reusable software components. Because, it's mostly a myth. It only ever works in misguided wishes and dreams.
Software is only truly reusable at the source code level. Read it, learn it, write your own.