geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <>
Subject Re: ClassFinder questions/problems -- annotation processing
Date Tue, 06 Feb 2007 20:49:33 GMT

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 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

View raw message