Bug 252199 - jsr269: annotation processing
Summary: jsr269: annotation processing
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.6.2   Edit
Hardware: PC Windows XP
: P3 enhancement with 17 votes (vote)
Target Milestone: 1.8.2   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-10-27 10:56 EDT by Andrew Clement CLA
Modified: 2014-08-14 15:43 EDT (History)
13 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Clement CLA 2008-10-27 10:56:16 EDT
If using an annotation processor successfully in a Java project and the project is converted to an AspectJ project, the processor stops working.
Comment 1 Andrew Clement CLA 2008-10-27 10:59:39 EDT
There are two initial problems:

- AspectJ does not ship the jdt apt code that makes this work.  Classes in this code are loaded reflectively by the JDT compiler and if not found then no error is produced.
- The reflectively loaded code must be delegated to at the right time during the compilation process.

These are fixable but I worry they will lead down a terrible path, but let's see.

First steps: get hold of the jdt apt code (which has a Java6 dependency), modify it as we do the jdt (with package name prefix, to line it up with the AspectJ JDT), package it where our modified jdt can load it, then delegate to it at the right moment.  At this point I'm expecting it to go BANG.
Comment 2 Andrew Clement CLA 2008-10-27 11:55:21 EDT
a) Extracted org.eclipse.jdt.compiler.apt R3_3_1 from CVS.  dev.eclipse.org/cvsroot/eclipse. (needs dependency on rt.jar from Java 6)

b) Copied in build.xml from shadows - to do same renaming job.  Run it.

c) manual rename on manifest references (*sigh*)

d) Add project org.eclipse.jdt.core (our variant, built from shadows) as project dependency.

Compiling clean.

e) Looked at invocation of the annotation processor (all references to the field Compiler.annotationProcessorManager).  It looks like the compiler has the field initialized by the calls to initializeAnnotationProcessorManager() made in AbstractImageBuilder.newCompiler() but that appears to be the non-batch code.  The batch code seems to be the combination of this:

In Main.performCompilation(), just after the batch compiler is built:

         if (this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_6
			&& this.compilerOptions.processAnnotations) {
		if (checkVMVersion(ClassFileConstants.JDK1_6)) {
			initializeAnnotationProcessorManager();
			if (this.classNames != null) {
				this.batchCompiler.setBinaryTypes(processClassNames(this.batchCompiler.lookupEnvironment));
			}
		} else {
			// report a warning
			this.logger.logIncorrectVMVersionForAnnotationProcessing();
		}
	}

and in Compiler.compile(), just after beginToCompile(sourceUnits):
			
if (this.annotationProcessorManager != null) {
  processAnnotations();
  if (!options.generateClassFiles) {
	// -proc:only was set on the command line
    return;
  }
}


f) The latter code is still in the AspectJ copy of jdt core.  But the code to initialize the field hasn't been run as we have a convulated way to get to the same point. 
Comment 3 Andrew Eisenberg CLA 2008-10-27 12:03:54 EDT
I'm fairly certain that this will have some ramifications in AJDT as well.  I'll need to keep an eye on this.
Comment 4 Andrew Clement CLA 2008-10-27 12:42:58 EDT
urgh, our route to the compiler is so horrible that the apt code cannot be used directly, we dont have the right objects to pass to the configuration mechanism.
Comment 5 Andrew Clement CLA 2008-10-28 12:55:54 EDT
I have a prototype of this working.  The compiler takes the -processor flag and uses a transformed version of the org.eclipse.jdt.compiler.apt module to do the processing.  I have successfully generated aspects based on the annotations on java source.  But until this becomes a more requested feature I won't be doing the work to tidy it up and release.
Comment 6 Steve Ash CLA 2011-11-08 15:44:24 EST
Just for the sake of documentation since it has come up on the mailing list before and in lambok lists: project lambok (http://projectlombok.org/) adds a lot in the way of developer productivity via "magic" woven in to class files via a Java6 APT processor.

This enhancement would (should?) allow Lambok to coexist nicely with AspectJ and AJDT.  My understanding is they do some Eclipse stuff as well so perhaps there are ADJT impacts besides just the compiler.

I first went down the path of trying to create a "commons aspect" library to do some of the things that lambok does (without the cognitive overhead of adopting Roo), but am limited in some cases.  In particular lambok has a "val" type which will do simple type inference on the RHS so that you can simulate C#s val keyword.
Comment 7 Steve Ash CLA 2011-11-23 11:26:18 EST
Just as an additional FYI to my previous comment.  I have looked more into lombok now.  It is not a java6 apt processor.  It uses that to load itself as an agent to patch some javac classes to do its tricks.  I imagine since ajc is based off of the eclipse compiler that there is probably some overlap so reconciling aspectJ and lombok via this mechanism seems highly unlikely.  

I have successfully used the aspectj maven plugin to let javac compile with lombok into a staging directory then using binary weaving to weave aspects in to the target/classes folder and then I get my src + lombok + advice.  Worked wonderfully.

Now if I could just get that to work in AJDT...
Comment 8 David Haraburda CLA 2012-08-07 17:57:13 EDT
Has any progress been made on this bug?  It took me awhile to figure out that AJDT was the reason the the APT I am attempting to use was not being invoked.
Comment 9 Andrew Clement CLA 2012-08-08 11:09:19 EDT
Hi David - no, I'm afraid no progress has been made on this issue.
Comment 10 Christopher Smith CLA 2012-08-21 02:33:11 EDT
Is there a recommended workaround?  I have a project that needs both compile-time weaving and annotation processing, and this is a big (and long-standing) gap in the compiler spec.  I'm using Maven, so if there's a way to work around the issue, then I can use that for now, but I'm needing to generate and then compile source code based on JPA entities, and it appears that the aspectj-maven-plugin and the maven-compiler-plugin are both running in the same phase.
Comment 11 David Haraburda CLA 2012-08-23 16:31:24 EDT
Chris,

There is a workaround for your situation: you can use the maven annotation plugin (also called maven-processor-plugin).  It runs the compiler APT separately and is available at https://code.google.com/p/maven-annotation-plugin/

If you are referring to the JPA static metamodel generation, then that is what we needed it for and it works great.  If you are using Eclipse and m2e there is also the m2e-apt plugin/connector that makes it work with the Eclipse build.
Comment 12 Wojciech Gorski CLA 2012-09-18 04:37:02 EDT
It would be really really great to have this bug fixed, because right now we can't use lombok together with AspectJ.
Comment 13 Andrew Clement CLA 2013-06-24 11:08:14 EDT
unsetting the target field which is currently set for something already released
Comment 14 luvar luvar CLA 2013-10-25 05:21:19 EDT
Hi, I would like to see support for aspectJ and lombok preprocessor in one maven project. Maven has no problem with building this type of project and development would be for me alittle bit more easier if also eclipse will be working.
Comment 15 Neale Upstone CLA 2013-11-28 05:11:28 EST
I'll pitch in on upping the priority of that "tidy up".

My scenario is using Spring Tool Suite with AspectJ for Spring's @Configurable, plus I'm using the Hibernate JPA metadata generator (hibernate-jpamodelgen).

It's become such a pain that I've manually taken AspectJ out of the build by moving to CGlib proxies for transaction management, and for @Configurable, calling AnnotationBeanConfigurerAspect.aspectOf().configureBean(this) from an initialiser block and readResolve() - thankfully usually via a superclass.

For Spring, I think there's a case for addressing this, as Spring Roo and @Configurable depend on AspectJ.
Comment 16 Pavel Yushkovskiy CLA 2014-02-03 16:13:26 EST
This feature is really very important. A lot of projects (including our) use AP from external libraries like Hibernate. Also we used some custom processor.
I had a great need to bring AOP to our project. But it breaks our functionality.

I also tried something what Andrew was written, but had not finished yet. I am trying to make it works inside Itellij Idea and have some problems with plugin which add support for AspectJ.

It will be great if this bug will be fixed in AspectJ library. If you need any help, please contact me. I would me glad to participate
Comment 17 John Cairns CLA 2014-08-13 19:17:10 EDT
Is there a simple work around for being able to generate source code using annotation processing via org.eclipse.jdt.core.javabuilder AND then doing compile time weaving via org.eclipse.ajdt.core.ajbuilder in eclipse.  I have them working independently but just found out that they don't seem to work in conjunction with each other....   I am relatively new to these capabilities and think I have landed on the right defect and have explained my need - but not sure.

Thanks, in advance, for any help.

Regards,
John
Comment 18 Pavel Yushkovskiy CLA 2014-08-14 04:27:17 EDT
It will be possible as soon as new version of aspectj will be availible.
https://github.com/eclipse/org.aspectj/pull/2
Comment 19 Andrew Clement CLA 2014-08-14 15:43:21 EDT
Annotation processor integration is committed with a giant pull request from Sergey Stupin. thanks Sergey!

Tests are in too.

Please note this integration is at the compiler level, so for ajc usage (command line or via Ant). There is more to be done to ensure it all behaves under AJDT and that work is going to be done under bug 344159