geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim McConnell <tim.mcco...@gmail.com>
Subject Re: ClassFinder questions/problems -- annotation processing
Date Mon, 05 Feb 2007 03:19:56 GMT
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

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

Mime
View raw message