I was in a cross-team meeting a couple of weeks ago, and someone said something unintentionally hilarious.
They were discussing how they were putting their SOAP service endpoints in a properties file that lived outside of the Portlet WAR. This would be loaded from a "known" directory. The problem, they explained, was that this didn't follow any kind of standard; the existence and location of external properties files is specific to a certain deployment configuration. "What if we want to move this from Liferay and deploy it on WebSphere?" they asked.
"You'll have to make some changes to the application," I explained. "The WebSphere environment will probably dictate some other -- possibly similar -- mechanism for external properties. You'll need to change your code to use that."
The guy from the other team looked somewhat pained and earnestly offered, "We want to stick with JSR-286 so that our Portlet will be portable to a different Portlet container."
That's not going to happen.
OK, it could happen, but only if your Portlet does nothing interesting. A real, useful Portlet will need to initialize itself, use libraries and interact with the user model. You can't do these things consistently across versions of Liferay; how could you possibly expect to do them across different Portlet environments? The answer, of course, is a lack of real-world experience with Portlets.
It appears that there are two approaches to portability when implementing a Portlet.
1) Forget portability. This is my preferred and recommended approach. Go ahead and hook into whatever helpful features are provided by your Portlet container; freely use proprietary APIs and configuration. In fact, if you have an open-source container like Liferay, so ahead and modify it to suit your needs. Don't think of the Portlet container as infrastructure as much as a component. You might want to consider infrastructure generic and keep it so, but the Portlet container is heavily integrated -- consider making it part of the application.
2) Plan for porting. If you really want to make your application portable, put abstractions around all proprietary interfaces and objects. Need a user object? Make your own and populate it from Liferay's. That way, only a small part of your code references Liferay-specific classes. Take care to put all of this adaptor code in a single place. You'll still have porting to do, but it will be localized.
Honestly, I can only think of two reasons why you'd want to bother with this approach: either you are planning to sell your application to people with different Portlet environments, or you're developing your Portlet before you are certain which platform it will be deployed on. The latter scenario is just poor project planning. The former makes more sense. In that case, having a "Platform Abstraction Layer" in the form of a JAR file could be a great way to have different versions for different platforms.
Whatever the case, don't delude yourself that adherence to JSR-286 will not guarantee portability; the standard Portlet API doesn't fill in enough implementation detail to cover what you need to do -- unless a "Hello World!" Portlet is your goal.