Skip to main content



      Home
Home » Language IDEs » Java Development Tools (JDT) » Follow up on Java 6 blog on in.relation.to about Java 6 processors
Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #257903] Fri, 02 January 2009 10:58 Go to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

Hi,

As discussed on
http://in.relation.to/Bloggers/Java6CompilerPluginsAndTypesa feCriteriaQueries
we are looking into using Java 6 Annotationsprocessor's to create type
safe queries in JPA
and would like to get it to work smoothly within Eclipse.

I finally got a basic example working, or rather I figured out why a my
basic example did not work. Now i'm trying to figure out if that is
expected or a bug ;)

First issue I found was that the following gives an
UnsupportedOperationException:

JavaFileObject f =
processingEnv.getFiler().createSourceFile(clazz.getQualified Name() +
"Extras");

processingEnv.getMessager().printMessage(Diagnostic.Kind.NOT E, "Creating
" + f.toUri());

JavaFileObject.toUri() is the failing one.

IdeOutputJavaFileObject.toUri() states the file does not exist before
the writer is closed - which doesn't make sense to me since uri's
shouldn't require a file to exist...it's just location info.

Is there any other way to log info ?

I can survive with the above limitation, but the following is more
troublesome:

I got

@Handlable
private String stuff;

Where @Handlable is the annotation i'm scanning for in my
annotationprocessor.

Here the following line throws a nullpointer exception:

TypeMirror type = e.asType();

The type field is null in eclipse's compiler for some reason (probably
because the rest of class is waiting for a class to be generated by the
annotationprocessor) resulting in me not being able to generate for
something that is incomplete.

Here is the NPE:
java.lang.NullPointerException
at
org.eclipse.jdt.internal.compiler.apt.model.Factory.newTypeM irror(Factory.java:384)
at
org.eclipse.jdt.internal.compiler.apt.model.Factory.newTypeM irror(Factory.java:389)
at
org.eclipse.jdt.internal.compiler.apt.model.ElementImpl.asTy pe(ElementImpl.java:50)
at proc.HandlableProcessor.process(HandlableProcessor.java:40)
at
org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatch er.handleProcessor(RoundDispatcher.java:139)
at
org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatch er.round(RoundDispatcher.java:121)
at
org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotatio nProcessorManager.processAnnotations(BaseAnnotationProcessor Manager.java:159)
at
org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnno tationProcessorManager.processAnnotations(IdeAnnotationProce ssorManager.java:134)
at
org.eclipse.jdt.internal.compiler.Compiler.processAnnotation s(Compiler.java:794)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler. java:423)

Any ideas on how to otherwise get the type of an field if not through
asType ?

/max
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #257908 is a reply to message #257903] Fri, 02 January 2009 11:00 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

Forgot another issue:

Any way to avoid having to generate a .jar constantly for the annotation
processor to pick it up ? Would be great if it could just use the
classpath of the project (which would have the annotation-procssor as a
dependent project)

Right now I have to export to jar every time I've done a change that the
hotreplace debugger can't replace.

/max

> Hi,
>
> As discussed on
> http://in.relation.to/Bloggers/Java6CompilerPluginsAndTypesa feCriteriaQueries
> we are looking into using Java 6 Annotationsprocessor's to create type
> safe queries in JPA
> and would like to get it to work smoothly within Eclipse.
>
> I finally got a basic example working, or rather I figured out why a my
> basic example did not work. Now i'm trying to figure out if that is
> expected or a bug ;)
>
> First issue I found was that the following gives an
> UnsupportedOperationException:
>
> JavaFileObject f =
> processingEnv.getFiler().createSourceFile(clazz.getQualified Name() +
> "Extras");
>
> processingEnv.getMessager().printMessage(Diagnostic.Kind.NOT E, "Creating
> " + f.toUri());
>
> JavaFileObject.toUri() is the failing one.
>
> IdeOutputJavaFileObject.toUri() states the file does not exist before
> the writer is closed - which doesn't make sense to me since uri's
> shouldn't require a file to exist...it's just location info.
>
> Is there any other way to log info ?
>
> I can survive with the above limitation, but the following is more
> troublesome:
>
> I got
>
> @Handlable
> private String stuff;
>
> Where @Handlable is the annotation i'm scanning for in my
> annotationprocessor.
>
> Here the following line throws a nullpointer exception:
>
> TypeMirror type = e.asType();
>
> The type field is null in eclipse's compiler for some reason (probably
> because the rest of class is waiting for a class to be generated by the
> annotationprocessor) resulting in me not being able to generate for
> something that is incomplete.
>
> Here is the NPE:
> java.lang.NullPointerException
> at
> org.eclipse.jdt.internal.compiler.apt.model.Factory.newTypeM irror(Factory.java:384)
>
> at
> org.eclipse.jdt.internal.compiler.apt.model.Factory.newTypeM irror(Factory.java:389)
>
> at
> org.eclipse.jdt.internal.compiler.apt.model.ElementImpl.asTy pe(ElementImpl.java:50)
>
> at proc.HandlableProcessor.process(HandlableProcessor.java:40)
> at
> org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatch er.handleProcessor(RoundDispatcher.java:139)
>
> at
> org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatch er.round(RoundDispatcher.java:121)
>
> at
> org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotatio nProcessorManager.processAnnotations(BaseAnnotationProcessor Manager.java:159)
>
> at
> org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnno tationProcessorManager.processAnnotations(IdeAnnotationProce ssorManager.java:134)
>
> at
> org.eclipse.jdt.internal.compiler.Compiler.processAnnotation s(Compiler.java:794)
>
> at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler. java:423)
>
> Any ideas on how to otherwise get the type of an field if not through
> asType ?
>
> /max
>
>
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #257912 is a reply to message #257903] Fri, 02 January 2009 11:27 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

btw. the issue seem to be this code:

case Binding.FIELD:
case Binding.LOCAL:
case Binding.VARIABLE:
// For variables, return the type of the variable
return newTypeMirror(((VariableBinding)binding).type);

Why is the binding being casted to a VariableBinding when it is actually
a FieldBinding ?

/max

> Here is the NPE:
> java.lang.NullPointerException
> at
> org.eclipse.jdt.internal.compiler.apt.model.Factory.newTypeM irror(Factory.java:384)
>
> at
> org.eclipse.jdt.internal.compiler.apt.model.Factory.newTypeM irror(Factory.java:389)
>
> at
> org.eclipse.jdt.internal.compiler.apt.model.ElementImpl.asTy pe(ElementImpl.java:50)
>
> at proc.HandlableProcessor.process(HandlableProcessor.java:40)
> at
> org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatch er.handleProcessor(RoundDispatcher.java:139)
>
> at
> org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatch er.round(RoundDispatcher.java:121)
>
> at
> org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotatio nProcessorManager.processAnnotations(BaseAnnotationProcessor Manager.java:159)
>
> at
> org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnno tationProcessorManager.processAnnotations(IdeAnnotationProce ssorManager.java:134)
>
> at
> org.eclipse.jdt.internal.compiler.Compiler.processAnnotation s(Compiler.java:794)
>
> at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler. java:423)
>
> Any ideas on how to otherwise get the type of an field if not through
> asType ?
>
> /max
>
>
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #257915 is a reply to message #257912] Fri, 02 January 2009 11:29 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

forget that - I looked at the wrong class hierachy ;)

The problem is simply that binding.type is null. Even if I remove all
compile errors.

/max

>
> btw. the issue seem to be this code:
>
> case Binding.FIELD:
> case Binding.LOCAL:
> case Binding.VARIABLE:
> // For variables, return the type of the variable
> return newTypeMirror(((VariableBinding)binding).type);
>
> Why is the binding being casted to a VariableBinding when it is actually
> a FieldBinding ?
>
> /max
>
>> Here is the NPE:
>> java.lang.NullPointerException
>> at
>> org.eclipse.jdt.internal.compiler.apt.model.Factory.newTypeM irror(Factory.java:384)
>>
>>
>> at
>> org.eclipse.jdt.internal.compiler.apt.model.Factory.newTypeM irror(Factory.java:389)
>>
>>
>> at
>> org.eclipse.jdt.internal.compiler.apt.model.ElementImpl.asTy pe(ElementImpl.java:50)
>>
>>
>> at proc.HandlableProcessor.process(HandlableProcessor.java:40)
>> at
>> org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatch er.handleProcessor(RoundDispatcher.java:139)
>>
>>
>> at
>> org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatch er.round(RoundDispatcher.java:121)
>>
>>
>> at
>> org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotatio nProcessorManager.processAnnotations(BaseAnnotationProcessor Manager.java:159)
>>
>>
>> at
>> org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnno tationProcessorManager.processAnnotations(IdeAnnotationProce ssorManager.java:134)
>>
>>
>> at
>> org.eclipse.jdt.internal.compiler.Compiler.processAnnotation s(Compiler.java:794)
>>
>>
>> at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler. java:423)
>>
>> Any ideas on how to otherwise get the type of an field if not through
>> asType ?
>>
>> /max
>>
>>
>
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #257918 is a reply to message #257915] Sat, 03 January 2009 13:40 Go to previous messageGo to next message
Eclipse UserFriend
"Max Andersen" <max.andersen@redhat.com> wrote in message
news:gjlfcs$6p9$2@build.eclipse.org...
> forget that - I looked at the wrong class hierachy ;)
>
> The problem is simply that binding.type is null. Even if I remove all
> compile errors.

That sounds a lot like a bug that's recently been fixed. What version of
Eclipse are you using? Give 3.5M4 a try, if you haven't already.
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #257922 is a reply to message #257903] Sat, 03 January 2009 13:56 Go to previous messageGo to next message
Eclipse UserFriend
"Max Andersen" <max.andersen@redhat.com> wrote in message
news:gjldj7$q9p$1@build.eclipse.org...
> Hi,
>
> As discussed on
> http://in.relation.to/Bloggers/Java6CompilerPluginsAndTypesa feCriteriaQueries
> we are looking into using Java 6 Annotationsprocessor's to create type
> safe queries in JPA
> and would like to get it to work smoothly within Eclipse.
>
> I finally got a basic example working, or rather I figured out why a my
> basic example did not work. Now i'm trying to figure out if that is
> expected or a bug ;)
>
> First issue I found was that the following gives an
> UnsupportedOperationException:
>
> JavaFileObject f =
> processingEnv.getFiler().createSourceFile(clazz.getQualified Name() +
> "Extras");
>
> processingEnv.getMessager().printMessage(Diagnostic.Kind.NOT E, "Creating "
> + f.toUri());
>
> JavaFileObject.toUri() is the failing one.
>
> IdeOutputJavaFileObject.toUri() states the file does not exist before the
> writer is closed - which doesn't make sense to me since uri's shouldn't
> require a file to exist...it's just location info.
>
> Is there any other way to log info ?


There are indeed some as-yet unimplemented APIs in the IDE compiler; the
command-line compiler (ecj) is complete but we ran out of time in the IDE
and then funding shifted after Oracle acquired BEA. I've been trying to get
to the unimplemented features in the order they're reported. Feel free to
report any that you hit via Bugzilla (or add a vote, if the missing method
has already been reported), that's how I've been tracking them. APT is
currently a part-time volunteer effort, so patches are very welcome,
especially if they include unit tests.

In this particular case, as a temporary workaround, I would just skip the
toUri() call and put the "clazz.getQualifiedName() + Extras" string into the
log output. I agree that's suboptimal, though.

Newly-supported methods have been going into 3.5 milestone releases, and in
some cases have been backported into the 3.4.2 stream. However, the 3.4.2
stream will soon be frozen.
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #257926 is a reply to message #257908] Sat, 03 January 2009 21:54 Go to previous messageGo to next message
Eclipse UserFriend
"Max Andersen" <max.andersen@redhat.com> wrote in message
news:gjldno$q9p$2@build.eclipse.org...
> Forgot another issue:
>
> Any way to avoid having to generate a .jar constantly for the annotation
> processor to pick it up ? Would be great if it could just use the
> classpath of the project (which would have the annotation-procssor as a
> dependent project)
>
> Right now I have to export to jar every time I've done a change that the
> hotreplace debugger can't replace.


The easiest way to do this is to develop the annotation processor as an
Eclipse plug-in. The code doesn't change, but in addition to declaring your
processor in the META-INF/services/javax.annotation.processors.Processor
file, you also declare it in plugin.xml, with the
org.eclipse.jdt.apt.core.annotationProcessorFactory extension point, and you
add a couple OSGi-related entries in the manifest.mf.

That way, you get the full support of the PDE during debugging. You can
still export the processor as a .jar file for use with javac.

The reason that we don't support putting the processor .jar on the classpath
is that once the processor class has been loaded into a VM, it's hard to
unlock the file that contains it until the VM is shut down. So if you had
both the processor project and the code to be processed in the same Eclipse
workspace, after the first time you tried building (and processing) the code
to be processed, the processor .class file would be locked and you'd no
longer be able to build the processor project. Remember, the processor is
part of the compiler - working on the processor code is no different than
working on the core compiler code, in terms of the classloader issues.

This issue doesn't exist when you're working with javac, because the
compiler VM only lives for a single invocation. It's different in an IDE.

When I'm working on processors I generally have two Eclipse workspaces going
on: one in which I'm developing the processor, and another in which I have
the code that I'll be testing the processor on. I launch the processor by
doing a Run As or Debug As Eclipse Application, making sure that the
processor plugin is selected (which it is by default).

Another way to do it is to create a .jardesc file, by telling the jar export
wizard to save the jar description. Then, you can just right-click on the
..jardesc and say "create JAR file". It's still a manual step, and you still
need to launch the processor in a separate VM and thus a separate Eclipse
workspace, but if you really don't want your processor to be a plug-in it's
a workable approach.
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #258133 is a reply to message #257926] Fri, 16 January 2009 07:49 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

On 04-01-2009 03:54, Walter Harley wrote:
> "Max Andersen"<max.andersen@redhat.com> wrote in message
> news:gjldno$q9p$2@build.eclipse.org...
>> Forgot another issue:
>>
>> Any way to avoid having to generate a .jar constantly for the annotation
>> processor to pick it up ? Would be great if it could just use the
>> classpath of the project (which would have the annotation-procssor as a
>> dependent project)
>>
>> Right now I have to export to jar every time I've done a change that the
>> hotreplace debugger can't replace.
>
>
> The easiest way to do this is to develop the annotation processor as an
> Eclipse plug-in. The code doesn't change, but in addition to declaring your
> processor in the META-INF/services/javax.annotation.processors.Processor
> file, you also declare it in plugin.xml, with the
> org.eclipse.jdt.apt.core.annotationProcessorFactory extension point, and you
> add a couple OSGi-related entries in the manifest.mf.

Yeah, I need to try that. Will have to seperate out the actual processor
jar from the plugin though to avoid eclipse dependencies in it.

> The reason that we don't support putting the processor .jar on the classpath
> is that once the processor class has been loaded into a VM, it's hard to
> unlock the file that contains it until the VM is shut down. So if you had
> both the processor project and the code to be processed in the same Eclipse
> workspace, after the first time you tried building (and processing) the code
> to be processed, the processor .class file would be locked and you'd no
> longer be able to build the processor project. Remember, the processor is
> part of the compiler - working on the processor code is no different than
> working on the core compiler code, in terms of the classloader issues.

Yes, I realize that but the factorypath approach is really really really
bulky and non-intuitive. IMO - you should simply look for any jar in
project classpath that has the proper META-INF/services content
and just run from there. That would go a long way; or maybe even simply
add all .jar's so external entities like javax.persistence would be
available to the processor.

And then factory path would just be an *optional* configuration. WDYT ?

/max
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #258137 is a reply to message #257918] Fri, 16 January 2009 07:49 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

On 03-01-2009 19:40, Walter Harley wrote:
> "Max Andersen"<max.andersen@redhat.com> wrote in message
> news:gjlfcs$6p9$2@build.eclipse.org...
>> forget that - I looked at the wrong class hierachy ;)
>>
>> The problem is simply that binding.type is null. Even if I remove all
>> compile errors.
>
> That sounds a lot like a bug that's recently been fixed. What version of
> Eclipse are you using? Give 3.5M4 a try, if you haven't already.

I tried using
http://download.eclipse.org/eclipse/downloads/drops/M2009010 7-0800/index.php
(3.4.2M build) and that solves this issue.

/max
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #258141 is a reply to message #257922] Fri, 16 January 2009 07:52 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

> Newly-supported methods have been going into 3.5 milestone releases, and in
> some cases have been backported into the 3.4.2 stream. However, the 3.4.2
> stream will soon be frozen.

I've tried out 3.4.2M build and I can now run my processor in there.

Biggest issue I got (besides the bulky factory path) is that if an error
occcurs in the processor (i.e. it cannot load a class because I forgot
to add a dependent jar to factory path) then it looks like the
compilation abruptly stops and I get an "Internal compiler error" and
a single line with the exception stacktrace.

This needs to be less fragile.

Furthermore I can't get the processor to generate output for all files
in a Full clean - it only does it on single files..any idea why that is
happening ?

p.s. sorry for the late follow up but been busy ;)
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #258143 is a reply to message #258141] Fri, 16 January 2009 08:05 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

On 16-01-2009 13:52, Max Andersen wrote:
>> Newly-supported methods have been going into 3.5 milestone releases,
>> and in
>> some cases have been backported into the 3.4.2 stream. However, the 3.4.2
>> stream will soon be frozen.
>
> I've tried out 3.4.2M build and I can now run my processor in there.
>
> Biggest issue I got (besides the bulky factory path) is that if an error
> occcurs in the processor (i.e. it cannot load a class because I forgot
> to add a dependent jar to factory path) then it looks like the
> compilation abruptly stops and I get an "Internal compiler error" and
> a single line with the exception stacktrace.
>
> This needs to be less fragile.
>
> Furthermore I can't get the processor to generate output for all files
> in a Full clean - it only does it on single files..any idea why that is
> happening ?

just to be more clear, if I have A.java, B.java. C.java and do a full
build I only get C_.java (where I would expect A_.java, B_.java and C_.java)

If I update A and B individually I get them all...but after a few
seconds it's all gone again leaving only C_.java behind.

/max

>
> p.s. sorry for the late follow up but been busy ;)
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #258147 is a reply to message #257926] Fri, 16 January 2009 08:40 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: max.andersen.redhat.com

On 04-01-2009 03:54, Walter Harley wrote:
> "Max Andersen"<max.andersen@redhat.com> wrote in message
> news:gjldno$q9p$2@build.eclipse.org...
>> Forgot another issue:
>>
>> Any way to avoid having to generate a .jar constantly for the annotation
>> processor to pick it up ? Would be great if it could just use the
>> classpath of the project (which would have the annotation-procssor as a
>> dependent project)
>>
>> Right now I have to export to jar every time I've done a change that the
>> hotreplace debugger can't replace.
>
>
> The easiest way to do this is to develop the annotation processor as an
> Eclipse plug-in. The code doesn't change, but in addition to declaring your
> processor in the META-INF/services/javax.annotation.processors.Processor
> file, you also declare it in plugin.xml, with the
> org.eclipse.jdt.apt.core.annotationProcessorFactory extension point, and you
> add a couple OSGi-related entries in the manifest.mf.

I tried this (an apt plugin), but I keep getting NoClassDefFundError for
annotations defined in an external jar.

The only setup I can get to work is pure java6 processor and then
duplicate the listing of the .jar (in this case ejb3-persistence.jar)

/max
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #258150 is a reply to message #258141] Fri, 16 January 2009 09:40 Go to previous messageGo to next message
Eclipse UserFriend
Max Andersen a écrit :
> Biggest issue I got (besides the bulky factory path) is that if an error
> occcurs in the processor (i.e. it cannot load a class because I forgot
> to add a dependent jar to factory path) then it looks like the
> compilation abruptly stops and I get an "Internal compiler error" and
> a single line with the exception stacktrace.
> This needs to be less fragile.
Please open a bug report against JDT/Apt with steps to reproduce.
--
Olivier
Re: Follow up on Java 6 blog on in.relation.to about Java 6 processors [message #258190 is a reply to message #258141] Tue, 20 January 2009 01:35 Go to previous message
Eclipse UserFriend
"Max Andersen" <max.andersen@redhat.com> wrote in message
news:4970831A.3010909@redhat.com...

> Biggest issue I got (besides the bulky factory path) is that if an error
> occcurs in the processor (i.e. it cannot load a class because I forgot to
> add a dependent jar to factory path) then it looks like the compilation
> abruptly stops and I get an "Internal compiler error" and
> a single line with the exception stacktrace.

As Olivier said, please enter a bug report, including the code for the
processor.


> Furthermore I can't get the processor to generate output for all files in
> a Full clean - it only does it on single files..any idea why that is
> happening ?

One thing that can make that happen is if your processor contains instance
variables that get set during processing - for instance a "doneProcessing"
flag. In a command-line build, the processor gets called a finite number of
times, and is passed all the files at once. In an IDE build, the processor
gets called over and over, and often only on those files that have been
modified.
Previous Topic:Resolving bindings in createAST
Next Topic:Value of a field for an IAnnotation with K_QUALIFIED_NAME pair value
Goto Forum:
  


Current Time: Mon Apr 28 02:40:49 EDT 2025

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

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

Back to the top