Bug 398590 - Using 'requires' clause on one aspect causes all other aspects with this clause to fail - regardless
Summary: Using 'requires' clause on one aspect causes all other aspects with this clau...
Status: RESOLVED DUPLICATE of bug 398588
Alias: None
Product: AspectJ
Classification: Tools
Component: LTWeaving (show other bugs)
Version: 1.7.1   Edit
Hardware: PC Windows 7
: P3 blocker (vote)
Target Milestone: 1.7.2   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-01-20 02:31 EST by Lyor Goldstein CLA
Modified: 2013-01-22 11:29 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lyor Goldstein CLA 2013-01-20 02:31:04 EST
The usage of the 'requires' clause causes all aspects that have have 'requires' clauses not to be loaded regardless of whether the specified required class exists or not. Here is the scenario and why it happens:

   Let's assume we have a bunch of aspects (A1, A2, A3, etc.) - all with 'requires' clauses and all referencing classes that can be satisfied. ClassLoaderWeavingAdaptor#registerAspects goes over the aspects in a Definition one by one. It reaches aspect A1 and detects that it has a 'requires' clause, and so it invokes BcelWorld#addAspectRequires. This causes the aspect A1 and its required class to be registered in an internal 'aspectRequiredTypes' map.

   Then the code calls BcelWeaver#addLibraryAspect with A1 as the argument, which in turn calls addOrReplaceAspect which invokes 'hasUnsatisfiedDependency'. The 'hasUnsatisfiedDependency' has been written to run only ONCE - i.e., it checks if it has already run, and if so then it does nothing. Otherwise, it removes from the 'aspectRequiredTypes' map all the types that can be resolved, thus leaving only those that cannot be resolved. In other words, it assumes that after having run (once !!!) any remaining type must be unsatified. Thus, when it is invoked with A1, being the 1st time, it resolves the required type by A1 and leaves the 'aspectRequiredTypes' map empty - but also marks that no further running is required.

   When the ClassLoaderWeavingAdaptor#registerAspects loop reaches A2, it call BcelWorld#addAspectRequires since A2 also declares a 'requires' clause. This causes A2 and its referenced class to be mapped in the 'aspectRequiredTypes' map. However, when BcelWeaver#addLibraryAspect is called with A2 and the code reaches 'hasUnsatisfiedDependency' - the code assumes that it has already run (which it has - with A1), so it does not check if indeed A2's referenced class can be satisfied (which we assume it can). In other words, all subsequent aspects (A2, A3, etc.) are declared as having unsatisified dependencies - which they don't.

   The (quick) bugfix seems rather simple: every time BcelWorld#addAspectRequires method is called, it should mark 'aspectRequiredTypesProcessed' as FALSE, in order to force a re-evaluation in case 'hasUnsatisfiedDependency' is called.
Comment 1 Andrew Clement CLA 2013-01-22 11:29:01 EST
duplicate

*** This bug has been marked as a duplicate of bug 398588 ***