murat8505 / projectlombok

Automatically exported from code.google.com/p/projectlombok
0 stars 1 forks source link

Java 7 multicatch exception syntax causes infinite loop #573

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create an android project
2. Add the attached file "LintBreaker.java" to it under com.example.lomboktest
3. Run android lint across the project

What is the expected output? What do you see instead?
Expect it to terminate with a report. What I get is an apparently infinite loop 
from within the Lombok AST parser, where it attempts to do error correction by 
either inserting characters forever or running past the EOF. When I have 
attached a debugger to the process, it indicates that the errors are coming at 
character positions past the number of characters in the actual file.

What version of the product are you using? On what operating system?
The android lint from the 22.0.5 tools. It uses lombok.ast 0.2. OS is Debian 
sid.

Please provide any additional information below.
LintBreaker.java is obviously distilled down from a larger file that I 
originally noticed the problem on, so the code itself probably doesn't make 
much sense, but should be syntactically correct at language level 7. In the 
larger project, reverting to language level 6 and stopping use of the level 7 
syntactic sugar (diamond operator and multicatch) fixed everything, so I 
definitely believe it has to do with language features introduced in Java 7. I 
noticed that lombok.ast uses a "modified" version of parboiled that is quite 
old. I attempted to build a custom version of lombok.ast using parboiled 1.1.6, 
but couldn't get it to build. The "generateSource" ant target failed with (to 
me) mysterious errors.

My apologies if this is the wrong place to report this, but it seems to me to 
be an underlying issue with lombok.ast, and not with the Android lint tool's 
use of it. That may be an incorrect assumption. Also, I have been deleting 
things out of the original file bit by bit, and can't really afford to leave 
lint running for hours each time. It did run overnight on the actual codebase 
without terminating. The last test run on the attached version of the file did 
not terminate normally after 10 minutes of operation.

Original issue reported on code.google.com by rapro...@gmail.com on 4 Sep 2013 at 12:05

Attachments:

GoogleCodeExporter commented 9 years ago
I've been able to get it down to a smaller testcase, and with it, I can confirm 
your assumption that it is an issue in lombok.ast.

See the attached two files - I cut down your LintBreaker into Issue573, and 
added a runner class Issue573Main. I added both to an Eclipse project in my 
lombok and lombok.ast workspace.

In the current state, Issue573Main manages to run for 40 minutes straight. 
Removing one of the three try-catch blocks in Issue573 and trying again still 
takes a couple of seconds, but finds 8 ParseProblems, the first one at the | in 
the multicatch and the subsequent as resulting errors.

Original comment by askon...@gmail.com on 4 Sep 2013 at 9:58

Attachments:

GoogleCodeExporter commented 9 years ago
Thank you very much for your prompt attention and effort. My initial uninformed 
novice suspicion is that CatchTemplate in 
lombok.ast/src/main/lombok/ast/Templates.java has a reference to a 
VariableDefinition, and VariableDefinitionTemplate might not be able to 
properly process multicatch syntax. Perhaps a similar 
CatchVariableDefinitionTemplate that allows for the possibility of one or more 
TypeReference separated by '|' instead of a single TypeReference could be one 
possible approach?

I don't know nearly enough about the internals of the Lombok parser to 
understand why it takes three such clauses to really freak out the parser, but 
it looks to me like the file isn't really processed properly (i.e. spurious 
parse errors occur) even with just one multicatch expression.

Original comment by rapro...@gmail.com on 4 Sep 2013 at 10:15

GoogleCodeExporter commented 9 years ago
It looks like Parboiled cannot really handle this kind of situation well; I've 
seen it choke on almost-but-not-quite-legal syntax in other projects before. 

That said, we should be able to parse Java 7 sugar...

Original comment by askon...@gmail.com on 5 Sep 2013 at 8:48

GoogleCodeExporter commented 9 years ago
I've taken a look at the parsing. Adapting the grammar wouldn't be the problem, 
but storing a multicatch node properly is the difficult part here: Everything 
downstream expects a variable declaration (i.e. type + name), whereas we would 
suddenly, somehow, pass more than one type.

Original comment by askon...@gmail.com on 20 Sep 2013 at 11:28

GoogleCodeExporter commented 9 years ago
Now that Android build tools version 19 supports language features like 
multicatch this is probably going to happen a lot more from android lint...

Original comment by tnor...@google.com on 21 Dec 2013 at 1:59

GoogleCodeExporter commented 9 years ago
I was going to see if I could work around this. Since the code hangs in the 
parboiled code, I need the source code for parboiled 0.9.7.2, the version 
bundled with project lombok itself (presumably because it's been tweaked?).

In lombok.ast's 
buildScripts/ivy-repo/com.github.parboiled.custom-parboiled-0.9.7.2.xml it 
points to the source code as this download:
http://projectlombok.org/ivyrepo/parboiled/parboiled-0.9.7.2-src.jar

However, that .jar doesn't seem to include the source code; it looks like it's 
also just containing the binaries:

$ jar tvf parboiled-0.9.7.2-src.jar  | grep .java | wc
       0       0       0
$ jar tvf parboiled-0.9.7.2-src.jar  | grep .class | wc
     229    1832   18253

Does anyone know where I can find the exact parboiled sources?

(I optimistically tried using the latest parboiled release, 1.1.6, but the APIs 
appear to have changed quite a lot. I don't see anything near 0.9.7 in 
http://repo1.maven.org/maven2/org/parboiled/parboiled-java.)

Original comment by tnor...@google.com on 27 Dec 2013 at 12:45

GoogleCodeExporter commented 9 years ago
If anyone else wants to look at this, the sources are found here:
https://github.com/sirthias/parboiled/archive/v0.9.7.2.zip

I started trying to fix this, but then I realized I have a better option: 
Rather than relying on the parboiled parser, I'll just make Android lint's 
command line client use ECJ directly instead (we already use ECJ when lint is 
running inside Eclipse). In addition to fixing this bug (and other bugs like 
issue 415) it makes everything a *lot* faster - like 10x faster. In short, 
while I said in an earlier comment that this bug is a big problem for us, it no 
longer is.

Original comment by tnor...@google.com on 30 Dec 2013 at 5:50