Bug 116229 - [waiting-on-build] PointcutParser interface cannot be used in LTW environment
Summary: [waiting-on-build] PointcutParser interface cannot be used in LTW environment
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.5.0RC1   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-11-14 09:49 EST by Matthew Webster CLA
Modified: 2005-11-29 14:14 EST (History)
0 users

See Also:


Attachments
Testcase (1010 bytes, application/octet-stream)
2005-11-14 09:53 EST, Matthew Webster CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Webster CLA 2005-11-14 09:49:40 EST
The PointcutParser interface and the RecflectionWorld on which it depends 
cannot be used in a run-time environment where the user application and 
AspectJ are loaded by separate class loaders. This is because the 
ReflectionWorld uses an unqualified Class.forName() call. The existing 
RuntimePointcuts testcase passes because the current harness (incorrectly) 
loads the testcase and AspectJ with the same class loader (see AjcTestCase.run
()). The attached modification to the XML script simulates a more realistic 
environment.

The ReflectionWorld needs to be explicitly created with a class loader. Using 
Thread.getContextClassLoader() is a traditional solution but problematic for 
both the test harness and environments like OSGi that do not associate a new 
thread with each application.
Comment 1 Matthew Webster CLA 2005-11-14 09:53:25 EST
Created attachment 29868 [details]
Testcase

Using the <run ltw=""> option in the harness ensures the testcase is loaded by
a separate class loader.
Comment 2 Matthew Webster CLA 2005-11-17 06:13:26 EST
See also Bug 116755. Starting with a World would at least allow lint warnings 
to be configured.
Comment 3 Adrian Colyer CLA 2005-11-19 12:01:44 EST
I've been all through the reflective world and pointcut parser and made sure that a user supplied 
classloader can be used in all locations. Construct a ReflectionWorld using a classloader, or call 
setClassLoader on a PointcutParser and all should be well. I've applied the test case patch and the updated 
test passes with this change in place.

I also had to change the test in BcelWorld to determine if an aspect is an @AspectJ aspect - it is not 
sufficient simply to look for the @Aspect annotation since code style aspects have that too. I now do the 
additional work to make sure that code style aspects compiled with 1.5  don't return true.

Will close report once fix is available in a published build.
Comment 4 Adrian Colyer CLA 2005-11-21 07:09:41 EST
Fix now available in published build.
Comment 5 Matthew Webster CLA 2005-11-24 12:43:39 EST
This interface fails to resolve annotions. Working on a patch for bug 117885, which ensures AspectJ and a testcase are not loaded by the same class loader, the ReflectOnAjcCompiledPointcuts test failes because "MyAnn" cannot be loaded. The problem is Java15ReflectionBasedReferenceTypeDelegate which uses the default constructor PointcutParser() which does not pass on its ReflectionWorld. Fortunately this is the only place.

As I said in our discussion the PointcutParser() constructor makes no sense. Its existence will be a source of hard to solve bugs. It should be withdrawn in favour of a factory method on RelflectionWorld or some facade class.
Comment 6 Matthew Webster CLA 2005-11-25 05:34:42 EST
You can tell I don't like the PoincutParser() default constructor can't you. My primary concern is that an API shouldn't allow a user to get into trouble. A program using this API will run just fine in a simple test environment then fail later in a more complex one (read difficult to diagnose problems) with an IllegalArgumentException which does not say "you need to supply a class loader matey" to me. Worse still you throw away the stack trace from the original ReflectionWorldException (because you can't nest exceptions in JDK 1.3) which gave some hint as to the actual problem.

The PointcutParser() does type resolution which is not clear from the javadoc. Worse still it does resolution relative to itself not, as the user may assume, relative to the invoking program. By not asking the user for the class loader the API assumes we don't need it, but we do.
Comment 7 Adrian Colyer CLA 2005-11-27 13:44:41 EST
I've taken away all of the constructors, and replaced them with static factory methods that allow me to specify a descriptive name. 

I also had to revert one place where I was using the supplied classloader to load a class when I actually should have been using the weaver-loading classloader - in the ReflectionBasedReferenceTypeDelegateFactory.

Fix in tree, waiting on build.
Comment 8 Adrian Colyer CLA 2005-11-29 14:14:53 EST
fix now available