I think the only annotations geronimo itself has to pay attention to
are:
javax.annotation.Resource(s)
javax.annotation.security.* (maybe)
javax.ejb.EJB(s)
javax.persistence.PersistenceContext(s)
javax.persistence.PersistenceUnit(s)
javax.xml.ws.WebServiceRef(s)
there are some more I'm really not sure of but probably are taken
care of by the jaxws impl:
javax.xml.ws.WebEndpoint
javax.xml.ws.WebServiceClient
javax.xml.ws.WebServiceProvider
These last might require the appropriate sub-builder (web service
builder) to receive a ClassFinder from whatever's calling them.
I've mostly thought about how this interacts with NamingBuilders
rather than other stuff like the web service builders.
I'm not sure I understand what you are proposing, but I thought about
this and think we can do it fairly easily within the framework of
pluggable naming builders while also allowing the default
environments to be added to the environment correctly.
Some observations on who knows what and thus who should do what:
the module builder knows which parts of the ear are accessible to the
module, so it should construct a ClassFinder reflecting this access.
This can only be done after copying files out of the source into the
car location. If we can construct a classloader that reaches into an
unpacked ear that would be ideal, we wouldn't have to copy the j2ee
app at all then.
As part of this the module builder has to find all the component-
declaring annotations and reflect that in the ClassFinder if
appropriate (this is ejbs only, right? Or WebEndpoint as well?)
the naming builders each know what kind of (non-component-declaring)
annotations are relevant so they should look for them in the
ClassFinder provided by the module builder.
Only the module builder understands the schema for the spec dd, so it
has to add the xml for the annotations into the dd to make it
metadata-complete. So the naming builders have to return the found
annotations in some form the module builder can deal with.
A classloader that includes the contributions of the naming builders
should only be needed by the naming builder itself when it's
constructing the reference. It might not be needed even then.
--------------------
So here's how I see the interaction of the module builders and the
naming builders:
ModuleBuilder.createModule doesn't call naming builders.
ModuleBuilder.installModule copies stuff into the target and
constructs a ClassFinder, then calls NamingBuilder.buildEnvironment
with the ClassFinder. It stuffs whatever is returned back into the
spec dd at the appropriate location. The NamingBuilders add stuff to
the environment, so after this we can construct a real classloader.
NamingBuilder.buidEnvironment looks at the xml and extracts whatever
annotations are relevant for it and returns them: if also adds stuff
to the environment if appropriate (typically if it found something in
the xml or annotations)
ModuleBuilder.initContext calls NamingBuilder.initContext (although
this seems a bit fishy to me)
ModuleBuilder.addGBeans calls NamingBuilder.buildNaming which
actually constructs the references and stuffs them in a map at the
appropriate location.
I think it might be appropriate for the naming builder to make a list
of _all_ the stuff it will need to deal with including from the
original dd and return that: we can pass that in to the initContext
and buildNaming methods so it doesn't have to look at the xml again.
-----------------
The really nasty part of the spec here appears to me to be the
extreme overloading of the @Resource annotation. I think they should
have gone the rest of the way and said ejb and web service refs were
also resources. What I outlined above provides no good way to check
that all the annotations are handled by some NamingBuilder. This
might be OK. An alternative might be to have the ModuleBuilder
extract all the possibly relevant annotations and have the
NamingBuilders remove the ones they process. If there's anything
left at the end, something didn't get processed. At the moment I'm
not too worried by the possibility that something didn't get processed.
-----------------
At least the AbstractWebModuleBuilder is going to need to look at the
security annotations. I think the same ClassFinder that the
NamingBuilders use would work for this. We probably want to stash it
in the Module so it can be used whenever necessary.
I just started looking at this annotation stuff recently so it's
entirely possible I missed the boat completely.... don't be shy
about letting me know :-)
thanks
david jencks
On Feb 16, 2007, at 8:59 PM, Tim McConnell wrote:
Thanks for the info David. At times it's not obvious to me which
annotations have already been implemented as part of other projects
and which require Geronimo implementation changes. So I've been
keeping track of them on the wiki below. The ones with a red-X or
green-Checkmark in the far-right-hand column are those that I'm
assuming will require Geronimo changes. I'm working on the JSR-250
set now so if you if you have a chance to review and/or verify my
assumptions that would be helpful to me.
http://cwiki.apache.org/confluence/display/GMOxDEV/Java+EE+5
+Annotations
Thanks,
Tim McConnell
David Blevins wrote:
On Feb 15, 2007, at 9:25 PM, Tim McConnell wrote:
Hi David/Dain, I finally see what's going on here now--and it
really makes a lot of sense. I'm not so sure it's a bug with the
classloading process so much as it's just the way the current
code functions. I can't easily show a sequence diagram here but
can briefly explain. It appears the the "EarContext" for a
deployed EAR file is aggregated across successive calls from
EARConfigBuilder.buildConfiguration() to the installModule()
method on first the WebModuleBuilder class, and then second on
the EjbModuleBuilder class. This explains why ClassFinder was
working correctly in EjbRefBuilder (i.e. the deployed module's
EarContext had been fully aggregated) but failed for me in
AbstractWebModuleBuilder (i.e., the deployed module's EarContext
had not yet been fully aggregated).
That would explain a lot! Though, this does seem like an issue
that should be fixed. I know DJ isn't fond of some of the hacks
we've had to add in the builder process. Likely this may be the
straw that broke the camels back.
So, rather than fixing something that's not really broken in
AbstractWebModuleBuilder, the best solution in my view is to push
the Annotation processing out of the installModule processing of
the module builder(s) up into the configuration builder. This
would allow us to encapsulate the Annotation processing for
deployed EJB applications, Web applications, App Client
applications, and Connectors (not sure these would be annotated
though) into a single class: EARConfigBuilder. Additionally, it
would guarantee that we always have access to a fully aggregated
EarContext, and thus a fully populated classloader to pass to
ClassFinder. And finally, I think it would encapsulate most of
the Geronimo annotation processing except for Web Services. This
approach is somewhat in line with my original proposed plan for
Annotation Processing for Geronimo, it's just the conduit has
changed somewhat. Do either of you (or anyone else) have any
thoughts, comments and/or concerns ??
That'd be fine for Web modules and App Clients -- there are no
Connector annotations and EJB annotations are taken care of by
OpenEJB. I know you keep wanting to do all the EJB-specific
annotations, but there's no real reuse there. Web modules and
Connectors pretty much both have the same stuff, which is really
only the five or so JSR-250 annotations plus these from javax.ejb:
@EJB(s), @PersistenceUnit, and @PersistenceContext.
You can cross the rest off your list: i.e. javax.ejb @Remote,
@RemoteHome, @Local, @LocalHome, @Stateless, @Stateful,
@MessageDriven, @PrePassivate, @PreActivate, @Init, @Remove,
@Timeout, etc. These are EJB specific and already implemented for
the most part.
-David
Thanks,
Tim McConnell
Tim McConnell wrote:
Hi Dain, What you suggest does make a lot of sense. But for the
stateless-calculator ear file (i.e., calculator-stateless-ear-2
[1].0-M2.ear) I would then expect to find the calculator-
stateless-ear-2[1].0-M2.jar file on one of the parent
classloaders for the WAR classloader in
AbstractWebModuleBuilder. It's not, so I suspect there is a bug
somewhere as you suggest. I shall investigate further tomorrow.
Thanks for the pointer....
Dain Sundstrom wrote:
On Feb 6, 2007, at 12:49 PM, David Blevins wrote:
On Feb 4, 2007, at 7:19 PM, Tim McConnell wrote:
Hi again Dave, after your recommendation below to do all the
annotation discovery during the installModule phase of
deployment ClassFinder is working much better for me. I do
still have another scenario I'd appreciate some advice on. It
seems that when an EJB EAR file (with embedded JAR and WAR
files) gets deployed in Geronimo, there are two builders
invoked: e.g., TomcatModuleBuilder/AbstractWebModuleBuilder
and EJBModuleBuilder such that the embedded JAR file is not
added to the ClassPath/ClassLoader when the WAR is deployed
(I assume this is the way it should work since I haven't
changed it--yet). So, if there are annotations in the WAR
class files pointing to classes in the JAR file, we'll still
encounter NoClassDefException(s). I can just add the JAR
files in the EAR to the classpath of the WAR, which is what
I've done to get around the problem, but I'm not sure this is
the best alternative. Do you have any thoughts?? Thanks much
Those should be added automatically via the deployment
system. Very puzzling. Dain, did you see anything like this
when you did that hack for @EJB annotation support in Servlets?
Nope. The WAR class loader is a child of the EAR class loader
so the WAR should "see" all of the jars in the ear. If that is
not the case, then there is a bug.
-dain