Ted has been publishing a great series of articles lately about J2EE. What's particularly interesting about them is that much of the material has nothing to do with J2EE. (Then again, much of the best writing applies across technologies. Like Tim's book or Szyperski's book.) For example, this posting talks about the rise of component-orientation, which has replaced object-orientation as the New Hope of Reuse. One thing that Ted hasn't addressed yet (but that I hope he will) is how to succeed with a component-oriented philosophy.
I've always noticed that the first time I do anything, I do it wrong. I'm not even talking about software, although it's certainly true there as well. I mean the first time I do anything - buy a car, choose a printer, play golf. I've taken many approaches over the years, from just going ahead and doing it to attempting to do all the research right up front so I can make the perfect choice. The sweet spot - as it almost invariably does - lies somewhere in the middle.
For component reuse to be successful requires a certain amount of forethought. You have to try to figure out how the component is going to be used. You should also expect to be wrong, because you will. Get over it. In fact, plan for it. Then iterate your design - the knowledge you gain integrating it into other systems is a necessary piece of information without which it is impossible to get things right.
One of the more interesting implications for this is that versioning capabilities are important to understand. If you know there's going to be a v2, then you had better understand how to deploy it over v1. There are lots of strategies for doing this, and the CLR introduces a whole new set of capabilities, but as an industry we still don't understand how to solve this problem. I'd love to hear if anyone thinks the seminal work on this topic has been written - I'm not aware of it.