Shai from LWUIT fame has a very interesting post on J2ME device fragmentation. I wholeheartedly agree with what he says: portability across devices was certainly an issue in the early days of J2ME and probably still is when developping demanding games.
But for other applications and modern phones (i.e. MIDP 2.0, which was released in 2002), portability is in my experience mostly a matter of careful programming and careful reading of the specifications. There are also a few well-known implementation bugs which are quite widespread and thus easy to spot.
During my first two months at Goojet, I was able to refactor the existing J2ME application in a way that completely avoids any code preprocessing yet is quite reasonably featured (it's an HTML browser!) and runs smoothly on a large number of phones.
The so-called "porting solutions" that are offered in the J2ME world are, from my experience with one of them, built on bugs on very old phones that no more exist in the wild and are now more urban legends, or pretty bad programming practices from people that did not take the time to carefully understand the specs or even the Java programming language.
One noticeable exception however is J2ME-Polish, but it's a lot more than a porting solution since it offers higher-level UI widgets and a nice build system. This last point is important, since you may need to have several sets of resources (e.g. icons) for the main screen size families, running with the same code. And J2ME-Polish is also open-source, meaning it can't hide bad code behind a proprietary closed-source licence.
The portability hell still exist though when you want to sign a J2ME application so that it can access some of the sensitive J2ME APIs such as SMS, network, camera, etc. There is no common set of root certificates you can rely on to sign your application, and the MIDP spec weirdly states that a signed application whose certificate can't be verified must not be installed, whereas an unsigned application can be installed but warns the user for every sensitive operation.
The result is that you need to know what root certificates are on what phones to either provide a signed application if you know it can be verified, or an unsigned application if you don't know what certificates are installed on the phone. Weird...