New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Antlr4 code generator throws exception under java 8 #337

Closed
glebreutov opened this Issue Oct 2, 2013 · 17 comments

Comments

Projects
None yet
7 participants
@glebreutov
Copy link

glebreutov commented Oct 2, 2013

I'm getting IndexOutOfBoundsException while trying to generate classes with Antlr Tool under Java 8.Under Java 7 same command with same grammar run's without issues.

This command:

java -cp antlr-4.1-complete.jar org.antlr.v4.Tool %* antlr4.bat MidasMain.g4 -package some.pkg.name  -visitor  -o ..\src\antlr4folder

Causes following exception:

 Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.rangeCheck(Unknown Source)
        at java.util.ArrayList.get(Unknown Source)
        at org.antlr.v4.misc.OrderedHashMap.getElement(OrderedHashMap.java:46)
        at org.antlr.v4.analysis.LeftRecursiveRuleTransformer.setAltASTPointers(LeftRecursiveRuleTransformer.java:241)
        at org.antlr.v4.analysis.LeftRecursiveRuleTransformer.translateLeftRecursiveRule(LeftRecursiveRuleTransformer.java:162)
        at org.antlr.v4.analysis.LeftRecursiveRuleTransformer.translateLeftRecursiveRules(LeftRecursiveRuleTransformer.java:89)
        at org.antlr.v4.semantics.SemanticPipeline.process(SemanticPipeline.java:94)
        at org.antlr.v4.Tool.processNonCombinedGrammar(Tool.java:399)
        at org.antlr.v4.Tool.process(Tool.java:384)
        at org.antlr.v4.Tool.processGrammarsOnCommandLine(Tool.java:343)
        at org.antlr.v4.Tool.main(Tool.java:190)

Issue can be reproduced with antlr 4.0 and antlr 4.1 under java 8

java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b108)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b50, mixed mode)
@sharwell

This comment has been minimized.

Copy link
Member

sharwell commented Oct 2, 2013

Java 8 isn't a supported platform right now.

@sharwell sharwell closed this Oct 2, 2013

@spullara

This comment has been minimized.

Copy link

spullara commented Jan 9, 2014

JDK 8 goes final this month and GA in March. Is this hard to fix?

@parrt

This comment has been minimized.

Copy link
Member

parrt commented Jan 9, 2014

Hi Sam, I'm downloading jdk 8 for os x as we speak. I'll reopen to examine for imminent 4.2 release. BTW, have you seen the antlr4 plugin for intellij?

@parrt parrt reopened this Jan 9, 2014

@parrt

This comment has been minimized.

Copy link
Member

parrt commented Jan 9, 2014

Any chance you have a sample grammar that fails?

@sharwell

This comment has been minimized.

Copy link
Member

sharwell commented Jan 9, 2014

Oracle changed the implementation of HashMap in a way that breaks the OrderedHashMap class that's used in ANTLR 3 and ANTLR 4.

  1. The putAll method was changed to no longer call put for the individual add operations.
  2. The putIfAbsent method was added, and needs to be handled separately to fully support Java 8 (though we don't actually call this method).

That puts us in a tricky situation.

  • Leaving OrderedHashMap as-is means ANTLR will work with Java 6 and 7, but it will not work with Java 8.
  • Updating the OrderedHashMap class to work with Java 8 will make it not work with Java 6 or 7.

We can avoid the worst situations by overriding the putAll method in OrderedHashMap to throw UnsupportedOperationException. This is frustrating because we will have to manually iterate in all the places where this method was used previously, but would fix this problem.

@sharwell

This comment has been minimized.

Copy link
Member

sharwell commented Jan 9, 2014

Actually, I can just update the method to use a slower implementation:

@Override
public void putAll(Map<? extends K, ? extends V> m) {
    // Java 6/7 and Java 8 use different implementations for this method, so
    // we force them all to use a trivial strategy that at least works
    for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
        put(e.getKey(), e.getValue());
    }
}

@ghost ghost assigned sharwell Jan 9, 2014

@cowang

This comment has been minimized.

Copy link

cowang commented Jan 10, 2014

You could use System.getProperty("java.version"), e.g.
(completely off the cuff uncompiled code)

@Override
public void putAll(Map<? extends K, ? extends V> m) {
    // Java 6/7 and Java 8 use different implementations for this method, so
    // we force Java 8 to use a trivial strategy that at least works
    if (System.getProperty("java.version").compareTo("1.8") < 0) { // before Java 1.8
       super.putAll(m);
    } else { // Java 1.8 or greater
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
            put(e.getKey(), e.getValue());
    }
}
@spullara

This comment has been minimized.

Copy link

spullara commented Jan 10, 2014

This isn't future proof to 1.10 :)

On Thu, Jan 9, 2014 at 4:24 PM, George S. Cowan notifications@github.comwrote:

You could use System.getProperty("java.version"), e.g.
(completely off the cuff uncompiled code)

@override
public void putAll(Map<? extends K, ? extends V> m) {
// Java 6/7 and Java 8 use different implementations for this method, so
// we force Java 8 to use a trivial strategy that at least works
if (System.getProperty("java.version").compareTo("1.8") < 0) { // before Java 1.8
super.putAll(m);
} else { // Java 1.8 or greater
for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
put(e.getKey(), e.getValue());
}
}


Reply to this email directly or view it on GitHubhttps://github.com//issues/337#issuecomment-31992046
.

@parrt

This comment has been minimized.

Copy link
Member

parrt commented Jan 10, 2014

I've tried 3x and can't get jdk 8 to download. hmm... Anyway, I don't think that putAll would be a bottleneck for any of our stuff. I don't seem to see a lot of references. let's just go with your simple reimplementation.

@spullara

This comment has been minimized.

Copy link

spullara commented Jan 11, 2014

Awesome. Thanks all.

@spullara

This comment has been minimized.

Copy link

spullara commented Jan 11, 2014

I verified that if this change is made it looks like it will work in JDK 8 for my grammar.

@cowang

This comment has been minimized.

Copy link

cowang commented Jan 13, 2014

This isn't future proof to 1.10 :)

Oh, duh. I wondered why all the examples of using java.version whacked it off at the second dot and transformed it to a float. My way would be so much more elegant (except of course for the minor fact that it doesn't work).

@spullara

This comment has been minimized.

Copy link

spullara commented Jan 13, 2014

Generally the best bet is to look for a class introduced in 1.8.

On Mon, Jan 13, 2014 at 7:30 AM, George S. Cowan
notifications@github.comwrote:

This isn't future proof to 1.10 :)

Oh, duh. I wondered why all the examples of using java.version whacked it
off at the second dot and transformed it to a float. My way would be so
much more elegant (except of course for the minor fact that it doesn't
work).


Reply to this email directly or view it on GitHubhttps://github.com//issues/337#issuecomment-32179117
.

@spullara

This comment has been minimized.

Copy link

spullara commented Jan 13, 2014

Alternatively, you might want something more like my redis-protocol parser
if you are going that direction, since converting to a float doesn't work
either:

https://github.com/spullara/redis-protocol/blob/master/client/src/main/java/redis/client/RedisClientBase.java#L124

On Mon, Jan 13, 2014 at 1:51 PM, Sam Pullara spullara@twitter.com wrote:

Generally the best bet is to look for a class introduced in 1.8.

On Mon, Jan 13, 2014 at 7:30 AM, George S. Cowan <notifications@github.com

wrote:

This isn't future proof to 1.10 :)

Oh, duh. I wondered why all the examples of using java.version whacked it
off at the second dot and transformed it to a float. My way would be so
much more elegant (except of course for the minor fact that it doesn't
work).


Reply to this email directly or view it on GitHubhttps://github.com//issues/337#issuecomment-32179117
.

@cowang

This comment has been minimized.

Copy link

cowang commented Jan 15, 2014

... converting to a float doesn't work either

I can't believe I'm so slow to catch this. Bad week in general.

Like your code.

@sharwell sharwell closed this in 85a923f Jan 17, 2014

parrt added a commit that referenced this issue Jan 17, 2014

Merge pull request #424 from sharwell/fix-337
Fix IndexOutOfBoundsException when using ANTLR with Java 8 (fixes #337)
@javamonkey

This comment has been minimized.

Copy link

javamonkey commented Jun 27, 2016

i get same error using antlrworks2

@AsnelChristian

This comment has been minimized.

Copy link

AsnelChristian commented Oct 7, 2017

Hello, I am also getting the same error message; i am using java9 though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment