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?
-David
David Blevins wrote:
On Jan 27, 2007, at 10:20 PM, Tim McConnell wrote:
Hi David, I'm having a couple problems with ClassFinder that I
hope you can help me with.
1 -- I've annotated a number of methods in a serlvlet with the
@Resource annotation, but I'm having some trouble discovering
them in the WAR file just prior to deployment. Doing some
traces I can see that the "isAnnotationPresent()" check in
ClassFinder.findAnnotatedMethods() is failing. This is a bit
perplexing to me since the @Resource has the RUNTIME retention
policy, and ClassFinder.FindAnnotatedMethods() finds both the
classinfo and the methodinfo. Also, it's not getting a
ClassNotFoundException. Have you seen this before and/or do you
know what might be causing this ??
I'm not sure how you're constructing the ClassFinder, but as I
mentioned to Dain when he hacked the @EJB stuff in for servlets
you definitely want to use the constructor where you pass in the
webapp classloader plus the exact list of URLs to search making
sure you don't search the URLs in any of the parents. The code
that Dain came up with which would also apply would be like this:
ClassLoader webappClassLoader =
module.getEarContext().getClassLoader();
UrlSet urlSet = new UrlSet(webappClassLoader);
if (classLoader instanceof MultiParentClassLoader) {
MultiParentClassLoader multiParentClassLoader
= (MultiParentClassLoader) webappClassLoader;
for (ClassLoader parent :
multiParentClassLoader.getParents()) {
if (parent != null) {
urlSet = urlSet.exclude(parent);
}
}
} else {
ClassLoader parent =
webappClassLoader.getParent();
if (parent != null) {
urlSet = urlSet.exclude(parent);
}
}
ClassFinder finder = new ClassFinder
(webappClassLoader, urlSet.getUrls());
Then when you call ...
finder.findAnnotatedMethod(javax.annotation.Resource.class)
it should return the methods for all classes in the webapp that
use javax.annotation.Resource. If it doesn't, definitely make
sure the webapp doesn't have the annotation spec jar in the WEB-
INF/lib/ directory. The easiest way to check for that is to
simply...
ClassLoader webappClassLoader = module.getEarContext
().getClassLoader();
Class resourceAnnotation = webappClassLoader.loadClass
("javax.annotation.Resource");
assert javax.annotation.Resource.class.equals(resourceAnnotation);
If that assertion fails, than something is going very wrong with
the webapp classloader and definitely nothing annotation related
will work.
2 -- I've also noticed that when I annotate a class that extends
another class, then the ClassFinder will fail with a
NoClassFoundException on the class that is extended. I assume
this is because the extended classes are not in the WAR file that
is getting deployed. I create my own classloader and create a
ClassFinder instance by passing it the URL of the WAR file itself
(plus the URL of any embedded JAR files in the WAR) and don't use
a parent classloader. My quandary is that I'm trying to discover
these annotation prior to deployment so I'm not sure I have a
parent or system classloader I can use to find these extended
classes. Do you have any recommendations ??
Yea, you really won't be able to do any annotation processing
during or before the createModule phase of deployment as there are
no classloaders. It's pretty much a hard wall with no way past.
Kind of frustrating. I noticed in your proposals for annotation
processing for JSR 88 you have most of the work being done before
and during the createModule phase. Unfortunately, none of that
will be possible without some major changes to the deployment
system. You'll probably have to do most the work in installModule
and initContext like we did for EJBs.
Thanks for any assistance.
Hope this helps.
-David
--
Thanks,
Tim McConnell