Bug 526911 - Generated class file causes exception, works with javac 9.0.1 and 1.8.*
Summary: Generated class file causes exception, works with javac 9.0.1 and 1.8.*
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.8   Edit
Hardware: Other Mac OS X
: P3 blocker (vote)
Target Milestone: 4.7.3   Edit
Assignee: Sasikanth Bharadwaj CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 529471 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-11-06 16:11 EST by Thomas Vogler CLA
Modified: 2018-07-17 04:13 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Vogler CLA 2017-11-06 16:11:36 EST
Create project from the sources in http://www.thomas-vogler.de/javabug.tgz using eclips oxygen. Running it causes wild exception in some internal initializer. 

The code works fine compiling it with javac 9.0.1 and all 1.8 versions I was working with. 

The included class files also cause java 9.0.1 to crash. 

See included read me files. 

You may contact me vial email mail@thomas-vogler.de or thmsvglr@gmail.com

I cannot include attachments as Iā€™m writing this on a mobile phone.
Comment 1 Stephan Herrmann CLA 2017-11-06 18:28:34 EST
To make this bug report self-contained, here's the exception:

Exception in thread "main" java.lang.IllegalAccessError: Update to static final field de.thomasvogler.xxx.I.$SWITCH_TABLE$de$thomasvogler$xxx$V$T attempted from a different method ($SWITCH_TABLE$de$thomasvogler$xxx$V$T) than the initializer method <clinit> 
	at de.thomasvogler.xxx.I.$SWITCH_TABLE$de$thomasvogler$xxx$V$T(I.java:7)
	at de.thomasvogler.xxx.I.getH(I.java:29)
	at de.thomasvogler.xxx.I.create(I.java:15)
	at de.thomasvogler.xxx.Main.run(Main.java:11)
	at de.thomasvogler.xxx.Main.main(Main.java:6)
Comment 2 Stephan Herrmann CLA 2017-11-06 18:32:50 EST
Quoting from Arias bug links via bug 509753:

"The issue is that the JVMS was changed in Java 9 to disallow "final" fields from being modified outside of the <clinit> method. Even other methods called by <clinit>."

This implies that some byte code patterns generated by ecj, which were accepted by JVM's <= 1.8, are now considered as illegal.
Comment 3 Sasikanth Bharadwaj CLA 2017-11-07 00:22:35 EST
I will take a look
Comment 4 Eclipse Genie CLA 2017-11-09 06:39:36 EST
New Gerrit change created: https://git.eclipse.org/r/111290
Comment 5 Sasikanth Bharadwaj CLA 2017-11-24 04:22:12 EST
(In reply to comment #4)
> New Gerrit change created: https://git.eclipse.org/r/111290
Brief description of the change - At 9 and above, a Clinit is always added to the class. It will be removed anyway if no bytecode was generated. Code to initialize synthetic finals is now generated into the Clinit. Below 9, everything stays the same. Currently, only fields for enum switch seems to be candidates for this initialization. Couldn't find any other field that requires this treatment.
Comment 6 Stephan Herrmann CLA 2017-11-24 16:45:10 EST
(In reply to Sasikanth Bharadwaj from comment #5)
> (In reply to comment #4)
> > New Gerrit change created: https://git.eclipse.org/r/111290
> Brief description of the change - At 9 and above, a Clinit is always added
> to the class. It will be removed anyway if no bytecode was generated. Code
> to initialize synthetic finals is now generated into the Clinit. Below 9,
> everything stays the same. Currently, only fields for enum switch seems to
> be candidates for this initialization. Couldn't find any other field that
> requires this treatment.

Sound good. Just one question: what happens if you compile -1.8 and run on JDK 9?
Comment 7 Sasikanth Bharadwaj CLA 2017-11-27 00:49:40 EST
(In reply to comment #6)
> (In reply to Sasikanth Bharadwaj from comment #5)
> > (In reply to comment #4)
> > > New Gerrit change created: https://git.eclipse.org/r/111290
> > Brief description of the change - At 9 and above, a Clinit is always added
> > to the class. It will be removed anyway if no bytecode was generated. Code
> > to initialize synthetic finals is now generated into the Clinit. Below 9,
> > everything stays the same. Currently, only fields for enum switch seems to
> > be candidates for this initialization. Couldn't find any other field that
> > requires this treatment.
> 
> Sound good. Just one question: what happens if you compile -1.8 and run on JDK
> 9?
Runs fine. It's only at 9 (and above, I would assume) that this restriction is enforced.
Comment 8 Sasikanth Bharadwaj CLA 2017-11-27 04:41:18 EST
Merged to master via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=cae762398f6069da2c270456205f250a95d26868. Wonder what happened to genie. Resolving... Marking for backport to 4.7.3
Comment 9 Stephan Herrmann CLA 2017-11-27 15:37:08 EST
(In reply to Sasikanth Bharadwaj from comment #7)
> (In reply to comment #6)
> > (In reply to Sasikanth Bharadwaj from comment #5)
> > > (In reply to comment #4)
> > > > New Gerrit change created: https://git.eclipse.org/r/111290
> > > Brief description of the change - At 9 and above, a Clinit is always added
> > > to the class. It will be removed anyway if no bytecode was generated. Code
> > > to initialize synthetic finals is now generated into the Clinit. Below 9,
> > > everything stays the same. Currently, only fields for enum switch seems to
> > > be candidates for this initialization. Couldn't find any other field that
> > > requires this treatment.
> > 
> > Sound good. Just one question: what happens if you compile -1.8 and run on JDK
> > 9?
> Runs fine. It's only at 9 (and above, I would assume) that this restriction
> is enforced.

What exactly do you mean by "at 9"?
If the compiler at -1.8 didn't bother, wouldn't the resulting class file blow up the JVM 9? 
Or does JVM 9 still apply old logic to classfiles of version 52?
Comment 10 Sasikanth Bharadwaj CLA 2017-11-28 00:18:10 EST
(In reply to comment #9)
> (In reply to Sasikanth Bharadwaj from comment #7)
> > (In reply to comment #6)
> > > (In reply to Sasikanth Bharadwaj from comment #5)
> > > > (In reply to comment #4)
> > > > > New Gerrit change created: https://git.eclipse.org/r/111290
> > > > Brief description of the change - At 9 and above, a Clinit is always added
> > > > to the class. It will be removed anyway if no bytecode was generated. Code
> > > > to initialize synthetic finals is now generated into the Clinit. Below 9,
> > > > everything stays the same. Currently, only fields for enum switch seems to
> > > > be candidates for this initialization. Couldn't find any other field that
> > > > requires this treatment.
> > >
> > > Sound good. Just one question: what happens if you compile -1.8 and run on
> JDK
> > > 9?
> > Runs fine. It's only at 9 (and above, I would assume) that this restriction
> > is enforced.
> 
> What exactly do you mean by "at 9"?
> If the compiler at -1.8 didn't bother, wouldn't the resulting class file blow up
> the JVM 9?
> Or does JVM 9 still apply old logic to classfiles of version 52?
That's what I meant. classfile version 53 blows up, lower versions do not.
Comment 11 Jay Arthanareeswaran CLA 2017-12-06 05:30:54 EST
Verified for 4.8 M4 using build I20171205-2000.

Reopening for 4.7.3
Comment 12 Eclipse Genie CLA 2018-01-03 01:08:23 EST
New Gerrit change created: https://git.eclipse.org/r/114878
Comment 13 Eclipse Genie CLA 2018-01-03 03:46:05 EST
Gerrit change https://git.eclipse.org/r/114878 was merged to [R4_7_maintenance].
Commit: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=5471079f969802ad967935d787efda37b4d2aa05
Comment 14 Sasikanth Bharadwaj CLA 2018-01-03 03:46:26 EST
(In reply to comment #13)
> Gerrit change https://git.eclipse.org/r/114878 was merged to [R4_7_maintenance].
> Commit:
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=5471079f969802ad967935d787efda37b4d2aa05
Released to 4.7.3
Comment 15 Stephan Herrmann CLA 2018-01-06 06:54:30 EST
*** Bug 529471 has been marked as a duplicate of this bug. ***
Comment 16 Jay Arthanareeswaran CLA 2018-02-09 01:04:44 EST
Verified for 4.7.3 with build M20180207-1700