The EJB 2 spec was just too simple - this was the real problem :-). Because EJB 2 were underspecified, vendors were especially creative in proprietary extensions. The result was a relative "simple" ejb-jar.xml and often several, huge, proprietary, vendor specific deployment descriptors. Porting an application from one appserver to another was almost mission impossible. You had to map those vendor-specific extensions first.
Although EJB 3 is considered as simple, the spec standardizes lot more features, than it was the case in EJB 2. There is almost no room for vendor-specific extensions. At least, I never used any vendor extensions in my EJB 3 projects. In addition XML was entirely eliminated. You could specify whatever you want in XML, but you don't have to. What you get a are few annotated POJOs, without any additional configuration - so what can go wrong here?. I neven encountered any problems porting the applications between JBoss 4.X, Glassfish v1, v2, Weblogic 10 and even Websphere 6.1. What I ran to several times, however, were bugs, especially in the area of commercial application servers (which is actually funny). I encountered the following problems, lots of them are already fixed:
- Injection of Session Beans into Backing Beans, or injection between web container and EJB container in general (1.5 years ago - problem is already fixed)
- Injection of Session Beans into Interceptors (one commercial app server).
- Limitations of some JPA-providers, especially autoincrement, lazy loading behavior, polymorphic relations.
- Synchronization issues of complex, attached graphs of persistent objects
In EJB 3, however, there is a real issue with JNDI naming, which was fixed in EJB 3.1. Every application server uses its own JNDI-naming scheme. It is only a problem, if you are accessing remote beans via CORBA or RMI directly. Most application servers have reasonable and consistent naming patterns - like fully qualified remote interface names, so this problem can be very easily fixed with a ServiceLocator. Its actually the only problem with the spec regarding portability. A potential danger is the "mappedBy" attribute, which is not clearly defined by the spec. In the practice most application servers map it directly to JNDI.
Dependency Injection inside the container will work as expected - you do not have to configure anything in the default case because of Convention Over Configuration...
Classloading could be an issue if you are deploying many frameworks and libraries. It could become especially funny with AOP frameworks, which often rely on classloader tricks to be able to weave the classes at load time. In my projects I tried to reduce the amount of libraries and leverage existing JDK 1.6 stuff instead. So I never ran into classloading issues except come classic ones like Log4J or SLF4J. Funny enough the last time I had this problem with a plain WAR :-). Ironically: the heaviest classloading problems ever I encountered during Eclipse RCP development trying to properly integrate Hibernate and Log4J as plugin without Buddy-Classloading hack. ...Eclipse RCP is based on OSGI :-).
The problems were easily solved in few hours (if not minutes). In some projects we deployed the same EJB-JAR into different application servers in parallel (simple ANT-copy) - and ran the unit tests against different providers...
Security is pretty good standardized as well - with JACC. But even without this standard most application servers have similar, RBAC based security concepts. They (e.g. Glassfish, JBoss) support file, database and LDAP realms out-of-the-box.
EJB 3 is a multi-vendor abstraction, so it is leaky per nature. You shouldn't expect any miracles - but the portability of EJB 3 is comparable with the portability of a WAR. JPA is a bigger problem, because there are more qualitative differences between provider and their support of database proprietary features in particular. The real portability issue in the practice are not EJBs but the non-functional differences between different application servers (scalability, performance, administration etc.).
Actually from strategic point of view, EJB 3 are really interesting for product development - you are really independent of particular infrastructure provider.... There are even several, competing opensource EJB 3 containers available...(Glassfish, JBoss, Geronimo).