Generics are officially supported in EJB3 by Oracle WebLogic 10.3.2 (http://download.oracle.com/docs/cd/E11035_01/wls100/ejb30/implementing.html), but this support come with many bugs that can make you spend a lot of time with strange errors like this:
To better understand the issue now let's look at a very short example taken from a real production case. In this example we have a normal class hierarchy that implements the Generic Repository Pattern with EJB3. Many details are omitted here, including the usual JPA life cycle methods that are part of the Repository, and the injection of 'EntityManager' in JpaRepository.
In any case these classes should be deployable as an EJB3 Module (you can download the complete working Maven project here):
Among others here we have used Oracle's suggestions (http://download.oracle.com/docs/cd/E11035_01/wls100/ejb30/implementing.html # wp1129878) regarding the use of generics on EJB3, creating a "useless" interface "ApplicationContextRepositoryLocal" that is implement by the Bean class instead of directly implementing the generic interface.
Enabling fast-swap for fast development we have three types of problems.
which is implemented by:
But in the example code:
a) The method getEntityManager is not part of the business interface, but only of the internal implementation of the Bean
b) It is also declared "protected abstract" in the superclass class Bean!!
Obviously these generated classes cannot be compiled (you can't decrease the visibility of a method):
<Compilation Error> ApplicationContextJpaRepository_hskm2o_Impl.java: The inherited method JpaRepository<ApplicationContext>.getEntityManager() cannot hide the public abstract method in ApplicationContextJpaRepository_hskm2o_IntfThe solution to this problem is:
the generic return value is lost and the previous generated method is unable to compile the EJB, because in the skeleton code we have:
but because "__bean" is declared as a "ApplicationContextJpaRepository_hskm2o_Intf" we get a compile-time error (we can not assign an Object to an ApplicationContext without casting) at deploy time:
<Compilation Error> ApplicationContextJpaRepository_hskm2o_ApplicationContextRepositoryLocalImpl.java: Type mismatch: cannot convert from Object to ApplicationContextThe solution to this problem is something that go against what we read on Oracle's documentation
"Never have a hierarchy deeper then 3, included Object, in your bean implementation class"
In this example is enough to eliminate the MusicStoreJpaRepository and let the bean to directly implement the generic JpaRepository and the interface is generated correctly.
Fast-Swap is a great enhancement for enterprise developer but it's still buggy. I think that the problem rely inside the fact that an application using it has a different classloader, the "com.bea.wls.redef.RedefiningClassLoader", which is buggy also in Web components. Here is unable to read debug symbols from the .class files and when you enter in a debug session you are unable to declare breakpoint on arbitrary lines, only methods (which are a part of the class which is never lost, of course !!).
To avoid this annoying bug you can enable fast-swap in the ear and disable it on web-modules
I don't know why, but this way the classloader use is the good old ChangeAwareClassLoader but the fast-swap still works.
All of these problems have a single, simple conclusion that goes against one of the most interesting new feature of WebLogic 10.3:
"Fast Swap is buggy !!!! Long life Fast-Swap"
With these simple advise you can work great with it, and be really more productive in your development life-cycle.
If you want to see what is really going wrong in your EJB instead of useless IOException, then raise your log level to DEBUG and then enable these two debug flags DebugEjbCompilation and DebugEjbDeployment, both of them from the Admin Console.
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/issues/known_resolved.html # wp1174792 (search CR366512 and CR369221) we can find something regarding generics and EJB3, but is unrelated to those analyzed here http://weblogic-wonders.com/weblogic/2010/06/21/ejb3-weblogic10-3-and-generics-issue/
Unlike Oracle's fast-swap, this feature already present from WebLogic 8.1 works perfectly with generics and class hierarchies, but there is not yet found a productive way to use it on Maven.