Groovy's stub-generator clearly broken

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Groovy's stub-generator clearly broken

Jason Dillon
I've been trying to figure out whats going on with various stub-generator issues on GMaven and it looks its not GMaven's fault... though folks seem to think it is because of how the joint-compilation actually works in Groovy.

Here is an example project I put together that clearly shows how broken it is:

    http://github.com/jdillon/groovy-stub-test

This is using 1.7.4, has a few groovy files and one java file, nothing specific... just pulled from the GMaven testsuite.

TestWithExpected, which is similar to the reported problem on http://jira.codehaus.org/browse/GMAVEN-79, will have an invalid stub generated.  The groovyc task however does not report any errors and compiles just fine.  So I've enabled stubs to be saved, and added an additional javac task to compile all of the stubs, which shows that groovy is not generating proper stubs.

 * * *

So there are multiple problems here...

    First, why is groovy generating invalid stubs?

    Second, why isn't the joint-compiler compiling the stubs?

GMaven tickles more of these problems because it actually has a clean separation of the various stages involved, ie:

 * generate-stubs
 * compile-java
 * compile-groovy

I had recommended that Groovy do this too a long time ago (ie. the uber-tasks)... but alas fell on deaf ears.  Its too bad, since if it was staged, and core used it to build, then the stub-generator would probably be rock-solid today.

 * * *

I'm all for adding more fancy sexy features to Groovy, but it would be nice if this feature that has been around for a long-long-time was actually working correctly.

Almost all of the problems that are reported for GMaven are stub-related.  And since the 1.7 provider, its using the core stub-generator (with only minor modifications to not try and javac itself) most... or probably all of the problems are related to the core stub-generator.  But since normal groovyc doesn't seem to even compile all of the stubs, folks blame GMaven... since it "works with groovyc".

The addition of stub-generator tests is a good sign, and super-way-increadibly-long-overdue.  I'd really like to see the stub-generation system in groovy core to be rock solid before any other fancy magical whatnot be added.

:-\

--jason
---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Groovy's stub-generator clearly broken

Peter Niederwieser
Jason,

Jason Dillon wrote
First, why is groovy generating invalid stubs?
First, we know the stub generator isn't tested well enough. We can certainly fix that.

Second, the joint compilation approach currently used by Groovy is fundamentally limited. It will NEVER be able to generate correct stubs in all cases. The "correct" approach would be to parse Java sources along with Groovy sources and to resolve the two simultaneously, like Groovy Eclipse does. This is also how Scala's joint compilation works. Obviously, it would be a major undertaking to implement this.

Jason Dillon wrote
Second, why isn't the joint-compiler compiling the stubs?
I never noticed this in my experiments, and apparently blamed GMaven instead of groovyc a few times. Sorry for that. I can only guess that groovyc's joint compilation leverages javac's ability to retrieve type information from source files. This would explain why there are no errors for stubs that are never referenced from Java code. And it sounds like a pretty good idea because it makes joint compilation more robust (and probably faster too).

Jason Dillon wrote
The addition of stub-generator tests is a good sign, and super-way-increadibly-long-overdue.  I'd really like to see the stub-generation system in groovy core to be rock solid before any other fancy magical whatnot be added.
Agreed, although I'm not sure how far we can take it with the current approach.

If my speculations turn out to be correct, it seems critical for GMaven to also leverage javac's ability to retrieve type information from source files. Typically, the vast majority of generated stubs isn't referenced from Java code, and it's a pity if they can cause the build to fail; especially as long as we can't always guarantee to generate correct stubs.

Cheers,
Peter
Reply | Threaded
Open this post in threaded view
|

Re: Groovy's stub-generator clearly broken

Jason Dillon
On Aug 6, 2010, at 6:42 PM, Peter Niederwieser wrote:
>> First, why is groovy generating invalid stubs?
>
> First, we know the stub generator isn't tested well enough. We can certainly
> fix that.

Yup and its getting better with the new tests.


> Second, the joint compilation approach currently used by Groovy is
> fundamentally limited. It will NEVER be able to generate correct stubs in
> all cases. The "correct" approach would be to parse Java sources along with
> Groovy sources and to resolve the two simultaneously, like Groovy Eclipse
> does. This is also how Scala's joint compilation works. Obviously, it would
> be a major undertaking to implement this.

This I have to disagree with.  I don't see any reason why stubs can't be generated correctly in all cases.  Or else what is the point of generating stubs at all if they only work in certain cases?


> Jason Dillon wrote:
>>
>> Second, why isn't the joint-compiler compiling the stubs?
>
> I never noticed this in my experiments, and apparently blamed GMaven instead
> of groovyc a few times. Sorry for that. I can only guess that groovyc's
> joint compilation leverages javac's ability to retrieve type information
> from source files. This would explain why there are no errors for stubs that
> are never referenced from Java code. And it sounds like a pretty good idea
> because it makes joint compilation more robust (and probably faster too).

What sounds like a good idea?  Generating stubs that are not valid java files?  I'm confused by what you mean.


> If my speculations turn out to be correct, it seems critical for GMaven to
> also leverage javac's ability to retrieve type information from source
> files. Typically, the vast majority of generated stubs isn't referenced from
> Java code, and it's a pity if they can cause the build to fail; especially
> as long as we can't always guarantee to generate correct stubs.

Um... the generated stub .java files are invalid (in some cases), has nothing to do with type information from source files, and a lot more to do that groovy is generating .java files which are intended to be stubs for real groovy classes to allow javac to compile dependent sources before the groovyc task executes to finish the job.  If groovy is generating invalid .java... there is a problem.

--jason



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Groovy's stub-generator clearly broken

Peter Niederwieser
Jason Dillon wrote
This I have to disagree with.  I don't see any reason why stubs can't be generated correctly in all cases.  
Here is just one example: Say you need to generate Java stub code for "@Foo(expected=Bar)". You can't find a class named Foo, seems like it's a Java class from the same compilation unit. Also you haven't heard of a class named Bar. Now which of the following is true?
1. Bar is a class literal and hence I must translate it to Java by adding ".class"
2. Bar is a static field and hence I must copy it literally
The answer is you can't tell for sure. Instead, you'll have to make an (educated) guess.

Jason Dillon wrote
Or else what is the point of generating stubs at all if they only work in certain cases?
The point is that joint compilation is a non-trivial problem, and hence may need several attempts to be solved correctly.

Jason Dillon wrote
What sounds like a good idea?  Generating stubs that are not valid java files?  I'm confused by what you mean.
It sounds like a good idea to do the minimal work necessary to get the job done. Minimizes the error risk, which is something one should always strive for. Can't hurt for performance either.


Jason Dillon wrote
Um... the generated stub .java files are invalid (in some cases), has nothing to do with type information from source files, and a lot more to do that groovy is generating .java files which are intended to be stubs for real groovy classes to allow javac to compile dependent sources before the groovyc task executes to finish the job.  If groovy is generating invalid .java... there is a problem.
This is not about blaming groovyc or GMaven, it's about achieving good results in an imperfect world (i.e. robustness). Passing the stubs along as source dependencies might help to achieve this goal.

Cheers,
Peter
Reply | Threaded
Open this post in threaded view
|

Re: Groovy's stub-generator clearly broken

Jason Dillon
On Aug 6, 2010, at 8:19 PM, Peter Niederwieser wrote:

> Jason Dillon wrote:
>>
>> This I have to disagree with.  I don't see any reason why stubs can't be
>> generated correctly in all cases.  
>>
>
> Here is just one example: Say you need to generate Java stub code for
> "@Foo(expected=Bar)". You can't find a class named Foo, seems like it's a
> Java class from the same compilation unit. Also you haven't heard of a class
> named Bar. Now which of the following is true?
> 1. Bar is a class literal and hence I must translate it to Java by adding
> ".class"
> 2. Bar is a static field and hence I must copy it literally
> The answer is you can't tell for sure. Instead, you'll have to make an
> (educated) guess.

The imports and/or local definitions of types should be sufficient to resolve the types in this case.  If bar is a static field, the field will be present or will be defined in static imports, and by rendering the appropriate stub, the types should resolve properly.


>> What sounds like a good idea?  Generating stubs that are not valid java
>> files?  I'm confused by what you mean.
>>
>
> It sounds like a good idea to do the minimal work necessary to get the job
> done. Minimizes the error risk, which is something one should always strive
> for. Can't hurt for performance either.

At the cost of generating invalid data?


>> Um... the generated stub .java files are invalid (in some cases), has
>> nothing to do with type information from source files, and a lot more to
>> do that groovy is generating .java files which are intended to be stubs
>> for real groovy classes to allow javac to compile dependent sources before
>> the groovyc task executes to finish the job.  If groovy is generating
>> invalid .java... there is a problem.
>>
>
> This is not about blaming groovyc or GMaven, it's about achieving good
> results in an imperfect world (i.e. robustness). Passing the stubs along as
> source dependencies might help to achieve this goal.

Robustness, IMO, would be to generate stubs and ensure they compile at the cost of any additional microseconds required to do so.

--jason



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Groovy's stub-generator clearly broken

Peter Niederwieser
Jason Dillon wrote
The imports and/or local definitions of types should be sufficient to resolve the types in this case.  If bar is a static field, the field will be present or will be defined in static imports, and by rendering the appropriate stub, the types should resolve properly.
Don't you see that this is, in general, an undecidable problem? Does "import static Baz.*" import Bar or not? Does "expected=Baz.Bar" reference a static field, a top-level class, or a nested class? I could go on and on. And don't get me started on AST transforms.

Jason Dillon wrote
> It sounds like a good idea to do the minimal work necessary to get the job
> done. Minimizes the error risk, which is something one should always strive
> for. Can't hurt for performance either.

At the cost of generating invalid data?
Sorry but I can't follow you here.

Jason Dillon wrote
>> Um... the generated stub .java files are invalid (in some cases), has
>> nothing to do with type information from source files, and a lot more to
>> do that groovy is generating .java files which are intended to be stubs
>> for real groovy classes to allow javac to compile dependent sources before
>> the groovyc task executes to finish the job.  If groovy is generating
>> invalid .java... there is a problem.
>>
>
> This is not about blaming groovyc or GMaven, it's about achieving good
> results in an imperfect world (i.e. robustness). Passing the stubs along as
> source dependencies might help to achieve this goal.

Robustness, IMO, would be to generate stubs and ensure they compile at the cost of any additional microseconds required to do so.
You are mistaking robustness for correctness. My whole point is that you can't ensure correctness with the current approach. Once you've come to realize that, you'll probably appreciate that a little change in how javac is invoked can greatly increase robustness. I'm pretty sure this is why people have more problems with GMaven than with Ant/groovyc joint compilation. It's just a guess, but a well-educated one. Let's leave it at that. Maybe someone else will bring new facts to the table.

Cheers,
Peter
Reply | Threaded
Open this post in threaded view
|

Re: Groovy's stub-generator clearly broken

Jason Dillon
On Aug 6, 2010, at 9:34 PM, Peter Niederwieser wrote:

>> Robustness, IMO, would be to generate stubs and ensure they compile at the
>> cost of any additional microseconds required to do so.
>>
>
> You are mistaking robustness for correctness. My whole point is that you
> can't ensure correctness with the current approach. Once you've come to
> realize that, you'll probably appreciate that a little change in how javac
> is invoked can greatly increase robustness. I'm pretty sure this is why
> people have more problems with GMaven than with Ant/groovyc joint
> compilation. It's just a guess, but a well-educated one. Let's leave it at
> that. Maybe someone else will bring new facts to the table.

People have more problems with GMaven because Groovy generates invalid stubs and doesn't even bother to compile them and GMaven always compiles them.

If the groovy core team doesn't want to solve these problems, then it should state that joint-compilation is a failed POC and abandon the effort.  Instead of providing the ability to generate uncompilable stubs and say it supports joint-compliation.

The problems are hard... sure, but IMO Groovy has the capacity to solve these problems and if its going to support joint-compliation it must do so.  It might mean scanning .java files in addition to .groovy files to discover the proper type/member resolution when analyzing .groovy sources before generating .class files, or some other technique.

Right now my problem is that Groovy advertises joint-complilation, stub-generation, and itself doesn't even bother to compile stubs.  This IMO is not an optimization, but a failure of the joint-compilation mechanics.

IMO... either Groovy supports joint compilation or it does not.  ATM it does not support it due to improper stub generation and avoidance of stub compilation.

Its fine to say its support or not supported... but to do it half-ass... that is what is unacceptable.

GMaven had assumed that Groovy stub-generation was fully functionally and has abandoned its own stub-generation effort... only to find that the core stub generator is really no better than GMaven's in providing full compatibility with Groovy.

You yourself said that Groovy needs better Maven integration.  Well a fully functional stub-generator is the key to that success.  Generally, this conversation and its underlying meaning has fully confused me.  Are you saying its too hard and we should give up?  Or that GMaven will never work because of general problems with stub-generation?  What are you trying to tell me?

--jason  



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Groovy's stub-generator clearly broken

Russel Winder
Jason,

On Fri, 2010-08-06 at 21:52 -0700, Jason Dillon wrote:
[ . . . ]
> If the groovy core team doesn't want to solve these problems, then it
> should state that joint-compilation is a failed POC and abandon the
> effort.  Instead of providing the ability to generate uncompilable
> stubs and say it supports joint-compliation.
[ . . . ]
> IMO... either Groovy supports joint compilation or it does not.  ATM
> it does not support it due to improper stub generation and avoidance
> of stub compilation.
>
> Its fine to say its support or not supported... but to do it
> half-ass... that is what is unacceptable.

Speaking as an bit of an outsider these days:  if the joint compilation
stubs mechanism is broken then Groovy is broken.  If Groovy is broken
then GPars, Grails, Gradle, Gant, Spock, Griffon, etc. as well as GMaven
are broken.

Is there a JIRA entry for this issue.  If there isn't then the problem
doesn't exist, if there is then we can vote for it.
--
Russel.
=============================================================================
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:[hidden email]
41 Buckmaster Road    m: +44 7770 465 077   xmpp: [hidden email]
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc (205 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Groovy's stub-generator clearly broken

Jochen Theodorou
In reply to this post by Jason Dillon
Jason Dillon schrieb:
[...]
> People have more problems with GMaven because Groovy generates
> invalid stubs and doesn't even bother to compile them and GMaven
> always compiles them.
>
> If the groovy core team doesn't want to solve these problems, then it
> should state that joint-compilation is a failed POC and abandon the
> effort.  Instead of providing the ability to generate uncompilable
> stubs and say it supports joint-compliation.

Groovy was and is always more a "good enough" than "correct in all
cases" approach. the current joint-compilation works good enough for a
majority of people in the way groovyc uses it. The groovy classes used
from java tend to be more simple, thus producing less problems. That
GMaven does compile all stubs - needed or not, does not make the matter
more easy for GMaven.

And it was clear from the beginning, that joint compilation cannot
compile everything. I made examples for that even before Alex started
working on that approach. Sometimes a small change in Groovy can make
the joint compilation working, some problems proofed to be solvable
after a while.

But there will be always cases causing problems and transforms are the
obvious biggest problem these days.

> It might mean scanning .java files in addition to
> .groovy files to discover the proper type/member resolution when
> analyzing .groovy sources before generating .class files, or some
> other technique.

if we parse the java files, then we don't need stubs anymore. Groovyc
then can directly generate class files since all the needed information
is then extracted from the java source files. But does it solve all
issues at hand? I don't think so. You will still want the stubs for
javadoc. The problem sphere is then smaller, but not zero.

> Right now my problem is that Groovy advertises joint-complilation,
> stub-generation, and itself doesn't even bother to compile stubs.
> This IMO is not an optimization, but a failure of the
> joint-compilation mechanics.

javac is instructed by groovyc to use the stubs it is needing. That
means joint-compilation is compiling stubs, but only those absolutely
needed. GMaven instructs javac different, thus is having bigger problems.

In the long term groovyc may use the eclipse compiler and do compilation
  without stubs. We made that part not official yet, because of a
dependency on the eclipse compiler then. We can hardly ship it as APL2
project and then put in eclipse licensed stuff.

bye blackdrag

--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email