Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Newcomers » Newcomers » NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST
NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST [message #203422] Thu, 05 April 2007 08:40 Go to next message
Eclipse UserFriend
Originally posted by: liddedeyes.gmail.com

Im writing an Annotation Processor for Eclipse 3.2 that modifies the
source code of existing classes instead of simply creating classes in the
apt_generated directory. I do this by modifying the CompilationUnit
returned by eclipseAnnotationProcessorEnvironment.getAST().

However when i use the annotation processor I get a
java.lang.NoClassDefFoundError: org/eclipse/core/filebuffers/FileBuffers.

I’ve added all the required plugin dependencies, and the plugin builds
without errors. I’ve also exported the plugin as a jar and added it to
Java Compiler -> Annotation Processing -> Factory Path. I used
env.getMessager().printWarning(“Im running in ” +
compilationUnit.astRoot.getJavaElement().getElementName()) and verified
that the annotation processor is running properly because of the yellow
squiggly announcing the name of the annotation’s class.

I use the following code to retrieve and modify the CompilationUnit (note:
most of this code has just been copied from online documentation):

if (eclipseAnnotationProcessorEnvironment.getPhase() == Phase.BUILD) {
CompilationUnit astRoot = eclipseAnnotationProcessorEnvironment.getAST();

// start record of the modifications
astRoot.recordModifications();

// modify the AST
org.eclipse.jdt.core.dom.TypeDeclaration typeDeclaration =
(org.eclipse.jdt.core.dom.TypeDeclaration) astRoot.types().get(0);

AST ast = astRoot.getAST();
MethodDeclaration methodDeclaration = ast.newMethodDeclaration();

methodDeclaration.setConstructor(false);
methodDeclaration.setName(ast.newSimpleName("main"));
methodDeclaration.setReturnType2(ast
.newPrimitiveType(PrimitiveType.VOID));

typeDeclaration.bodyDeclarations().add(methodDeclaration);

try {
//The following line is where the error comes from
ITextFileBufferManager bufferManager =
FileBuffers.getTextFileBufferManager();

IPath path = astRoot.getJavaElement().getPath();
try {
// connect the path
bufferManager.connect(path, null);

ITextFileBuffer textFileBuffer = bufferManager
.getTextFileBuffer(path);
// retrieve the buffer
IDocument document = textFileBuffer.getDocument();

// ask the textEditProvider for the change information
TextEdit edit = astRoot.rewrite(document, null);

// apply the changes to the document
edit.apply(document);

// write the changes from the buffer to the file
textFileBuffer.commit(null /* ProgressMonitor */, false /* Overwrite
*/);
} catch (Exception e) {
// TODO
} finally {
// disconnect the path
bufferManager.disconnect(path, null);
}
}
}
Re: NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST [message #203471 is a reply to message #203422] Thu, 05 April 2007 15:56 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: wharley.bea.com

"Brian Arandez" <liddedeyes@gmail.com> wrote in message
news:b4ee2af2e1a76b3e27c3f00fbde033d8$1@www.eclipse.org...
> Im writing an Annotation Processor for Eclipse 3.2 that modifies the
> source code of existing classes instead of simply creating classes in the
> apt_generated directory. I do this by modifying the CompilationUnit
> returned by eclipseAnnotationProcessorEnvironment.getAST().

Modifying the existing class is not supported by APT. This is not a bug in
Eclipse, it's a design principle of the Sun APT interfaces, which is why you
had to jump through all those hoops even to get close. You can only create
new files, you cannot modify existing ones.

You're asking the compiler to be able to modify the class that it's
compiling, midway through compilation. It is not able to do that. (You
might also give some thought to how you expect the debugger and version
control system to handle the resulting situation.)

Can you say more about the use case you're trying to support? Maybe we can
suggest some alternative strategy.

- Walter Harley
JDT APT team
Re: NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST [message #203479 is a reply to message #203422] Thu, 05 April 2007 16:03 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: liddedeyes.gmail.com

I've found my own answer. Apparently I needed to add the required jars in
the Factory Path.
Re: NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST [message #203487 is a reply to message #203479] Thu, 05 April 2007 16:32 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: liddedeyes.gmail.com

Ahh! Thank you Walter. Please ignore my last post, I wasnt able to read
your message before posting. I no longer get the NoClassDefFound errors
but now I realize FileBuffers.getTextFileBufferManager() returns null.
Thanks, now I know why.

I'm trying to create a database persistence layer that will generate
holder objects and database tables using annotations. The user would thus
simply type in the annotations defining the database table, and the plugin
should insert the templated methods into the source-code as well as create
the required tables in the database based on the methods created.

I didn't use the standard methods for creating new classes because APT
doesnt put the classes in the desired packages but instead places them in
the .apt_generated folder. Is it okay for the generated classes to be
moved to the desired locations from inside the annotation processor?

The only reason I'm modifying the current class that contains the
annotations is for adding getter and setter methods. So another
alternative I'm thinking of is using the Eclipse Quick Fix using the
annotations. Is this already possible?
Re: NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST [message #203549 is a reply to message #203487] Thu, 05 April 2007 21:37 Go to previous messageGo to next message
Gary Horen is currently offline Gary HorenFriend
Messages: 18
Registered: July 2009
Junior Member
Hi Brian --

I'm the program manager for the BEA compiler team. We're the people who have
been working since Eclipse 3.1 on the APT feature in Eclipse.You have
stumbled on our favorite example of something that looks at first glance
like just the thing that an annotation processor should be able to do, but
actually can't be done in any reasonable way with the annotation processor
API. As Walter said in a previous post, the API is not designed to make it
possible to insert code in a file that the user created. In fact, the spec
says that a source file must compile to the same bytecode with or without
the presence of annotations.

The processor API provides one solution to the problem of injecting behavior
into an application codebase in response to the presence of an annotation:
you can generate a new Java type. This doesn't always lead to a clean
implementation or a satisfactory user experience, particularly when the user
wants to annotate a Plain Old Java Object to add some new behavior, and
still continue to be able to use it as a POJO. Other approaches to the same
problem that we have seen include simply persisting the annotation values
into the class file and then providing an implementation of the desired
behavior in the runtime container, triggered by introspection, and creating
a post-compilation processor (sometimes called a "bytecode enhancer") that
can actually inject the bytecode equivalent of the "implements" clause and
method definitions, for example, into a classfile, rather than attempting to
either change the user's source code, or change the output of the compiler.
Another possible approach, as you note in your last post, might be to
provide some kind of IDE-based functionality that could respond to the
presence of an annotation, but that could result in an experience that would
be complicated to explain to the user.

We just gave a talk at Eclipsecon 2007 that included a list of problems an
annotation processor solves well, and others that it's not so good for. You
can download the presentation and all the accompanying files at
http://www.eclipsecon.org/2007/index.php?page=sub/&id=36 18 (click on the
Presentation File link).

Having said all that about the alternatives there are for responding to Java
annotations, I have to ask why you seem to be creating a DB persistence
layer yourself. Have you looked at OpenJPA
(http://incubator.apache.org/projects/openjpa.html) or Hibernate
(http://www.hibernate.org)? These teams have put a fair amount of effort
into solving the larger problem you are trying to tackle, and their
offerings are free and open source.

-Gary Horen

"Brian Arandez" <liddedeyes@gmail.com> wrote in message
news:eb04da872a0a590463eb8631366d7f45$1@www.eclipse.org...
> Ahh! Thank you Walter. Please ignore my last post, I wasnt able to read
> your message before posting. I no longer get the NoClassDefFound errors
> but now I realize FileBuffers.getTextFileBufferManager() returns null.
> Thanks, now I know why.
> I'm trying to create a database persistence layer that will generate
> holder objects and database tables using annotations. The user would thus
> simply type in the annotations defining the database table, and the plugin
> should insert the templated methods into the source-code as well as create
> the required tables in the database based on the methods created.
> I didn't use the standard methods for creating new classes because APT
> doesnt put the classes in the desired packages but instead places them in
> the .apt_generated folder. Is it okay for the generated classes to be
> moved to the desired locations from inside the annotation processor?
> The only reason I'm modifying the current class that contains the
> annotations is for adding getter and setter methods. So another
> alternative I'm thinking of is using the Eclipse Quick Fix using the
> annotations. Is this already possible?
>
Re: NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST [message #203665 is a reply to message #203549] Fri, 06 April 2007 09:08 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: liddedeyes.gmail.com

Thanks! This persentation is very helpful! I'm still wondering why the
EclipseAnnotationProcessorEnvironment exposes the AST. What is this
supposed to be used for? I've found no documentation at all concerning its
usage.

My company has been using hibernate for the past 5 years, however we
recently wanted to create our own DB persistence layer because it was
difficult for trainees to learn hibernate and it becomes exteremely
difficult to debug.

Thanks again for the help!
Re: NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST [message #203811 is a reply to message #203665] Fri, 06 April 2007 18:25 Go to previous messageGo to next message
Gary Horen is currently offline Gary HorenFriend
Messages: 18
Registered: July 2009
Junior Member
The EclipseAnnotationProceesorEnvironment is there so that an annotation
processor which doesn't need to run in commandline APT (i.e. one that will
only run inside Eclipse) can be dispatched at compile time, and still take
advantage of Eclipse-specific APIs, like the DOM AST. At this point,
though,I don't know of anyone who has written such a processor.

Again, the groups who have created the DB persistence technologies have put
multiple man-years into them; it sounds like you are planning to take on a
large chunk of work. You might look at one of the other options out there to
see if it will be more straightforward for you, before you dive into
building another one from the ground up...




"Brian Arandez" <liddedeyes@gmail.com> wrote in message
news:9e687ae8860bd9941e16abb2e9f54628$1@www.eclipse.org...
> Thanks! This persentation is very helpful! I'm still wondering why the
> EclipseAnnotationProcessorEnvironment exposes the AST. What is this
> supposed to be used for? I've found no documentation at all concerning its
> usage.
> My company has been using hibernate for the past 5 years, however we
> recently wanted to create our own DB persistence layer because it was
> difficult for trainees to learn hibernate and it becomes exteremely
> difficult to debug.
> Thanks again for the help!
>
Re: NoClassDefFoundError when JPT-APT Annotation Processor rewrites AST [message #203827 is a reply to message #203665] Fri, 06 April 2007 18:34 Go to previous message
Eclipse UserFriend
Originally posted by: wharley.bea.com

"Brian Arandez" <liddedeyes@gmail.com> wrote in message
news:9e687ae8860bd9941e16abb2e9f54628$1@www.eclipse.org...
> Thanks! This persentation is very helpful! I'm still wondering why the
> EclipseAnnotationProcessorEnvironment exposes the AST. What is this
> supposed to be used for? I've found no documentation at all concerning its
> usage.

As Gary said, it's for the use of processors that are targeted to run only
in Eclipse. Unlike the APT interfaces, it is Eclipse-proprietary.

Within the context of APT, the AST interface should be treated as read-only.
Its function is to allow more detailed inspection of the source code than
would be possible through the APT interfaces, which only allow you to view
the type system. For instance, with the AST, you can inspect things like
local variables that are not visible through the APT interfaces.


> My company has been using hibernate for the past 5 years, however we
> recently wanted to create our own DB persistence layer because it was
> difficult for trainees to learn hibernate and it becomes exteremely
> difficult to debug.

Respectfully, I think that you will find that by the time you have written a
full-featured DB persistence layer, it will be just as complex as any other
full-featured DB persistence layer. If there's anything the software world
has painfully rediscovered over and over, it is that rolling your own
solutions does not usually make life easier.

At least if you stick with an open standard, you have some hope of finding
trainees who already have some experience with it; not to mention that you
have other people to draw on, through newsgroups like this one, and you have
lots of other people working to find and fix bugs.
Previous Topic:How do I clone a project?
Next Topic:Eclipse dies
Goto Forum:
  


Current Time: Fri Apr 26 02:17:09 GMT 2024

Powered by FUDForum. Page generated in 0.08353 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top