JDK-8199907 : JShell: NoSuchFieldError occurred due to accessing variables of intersection type inferred by `var`
  • Type: Bug
  • Component: tools
  • Sub-Component: jshell
  • Affected Version: 10
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2018-03-21
  • Updated: 2020-05-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
bitter_fox@bitterfox-MacBookPro% ~/bin/jdk-10/bin/jshell  -J-Duser.language=en
|  Welcome to JShell -- Version 10
|  For an introduction type: /help intro

jshell> <Z extends Runnable & CharSequence> Z get1() { return null; }
|  created method get1()

jshell> var z = get1()
z ==> null

jshell> z.run()
|  java.lang.NoSuchFieldError thrown: z
|        at (#3:1)

jshell> void m() {z.run();}
|  created method m()

jshell> m()
|  java.lang.NoSuchFieldError thrown: z
|        at m (#4:1)
|        at (#5:1)

jshell> 

Examples above are based on VariablesTest#lvti, but the testing is not completeness.
Comments
Please evaluate the difficulty and importance of fixing this
18-05-2019

The cause of this issue is restoring enhanced type(intersection type) doesn't work well. Currently, it replaces the type of the field symbol with the enhanced type(intersection type) after enter. Then, it restores it before generate. The restore logic is to find all fields from top-level class decl of compilation unit and replace the type of each fields' symbol. However, when we compile `z.run()` above, there are no fields in top-level class of compilation unit. Note that type of field z is actually Object in jshell and enhanced type is Runnable & CharSequence. Compiled field access's type is CharSequence and there is no field named z and typed CharSequence. A possible fix is that it restores all of symbol which is replaced.
25-03-2018

Following rewrites class's fields type: http://hg.openjdk.java.net/jdk/jdk/rev/48ec75306997#l24.61 This makes them(Snippet 13, 14) compilable
21-03-2018

I'm not sure why their(Snippet 13 and 14 in above) statuses are VALID though z is compiled as a filed of Object type.
21-03-2018

Following is with debug info [/tmp] bitter_fox@bitterfox-MacBookPro% ~/bin/jdk-10/bin/jshell -J-Duser.language=en /de| Welcome to JShell -- Version 10 | For an introduction type: /help intro jshell> /de | Debugging on jshell> <Z extends Runnable & CharSequence> Z get1() { return null; } Compiling: <Z extends Runnable & CharSequence> Z get1() { return null; } Kind: METHOD -- <Z extends Runnable & CharSequence>Z get1() { return null; } compileAndLoad [Unit(get1)] ++setCompilationInfo() MethodSnippet:get1/()Z-<Z extends Runnable & CharSequence> Z get1() { return null; } package REPL; import java.io.*;import java.math.*;import java.net.*;import java.nio.file.*;import java.util.*;import java.util.concurrent.*;import java.util.function.*;import java.util.prefs.*;import java.util.regex.*;import java.util.stream.*;class $JShell$11 { public static <Z extends Runnable & CharSequence> Z get1() { return null; }} -- diags: [] setStatus() MethodSnippet:get1/()Z-<Z extends Runnable & CharSequence> Z get1() { return null; } - status: VALID compileAndLoad ins = [Unit(get1)] -- legit = [Unit(get1)] Compiler generating class REPL.$JShell$11 compileAndLoad [Unit(get1)] -- deps: [] success: true recordCompilation: MethodSnippet:get1/()Z-<Z extends Runnable & CharSequence> Z get1() { return null; } -- status VALID, unresolved [] | created method get1() jshell> var z = get1() Compiling: var z = get1(); Kind: VARIABLE -- /*missing*/ z = get1() compileAndLoad [Unit(z)] ++setCompilationInfo() Snippet:VariableKey(z)#12-var z = get1(); package REPL; import java.io.*;import java.math.*;import java.net.*;import java.nio.file.*;import java.util.*;import java.util.concurrent.*;import java.util.function.*;import java.util.prefs.*;import java.util.regex.*;import java.util.stream.*;import static REPL.$JShell$11.get1; class $JShell$12 { public static Object z; public static Object do_it$() throws Throwable { Object z_ = get1(); return z = z_; } } -- diags: [] setStatus() Snippet:VariableKey(z)#12-var z = get1(); - status: VALID compileAndLoad ins = [Unit(z)] -- legit = [Unit(z)] Compiler generating class REPL.$JShell$12 compileAndLoad [Unit(z)] -- deps: [] success: true recordCompilation: Snippet:VariableKey(z)#12-var z = get1(); -- status VALID, unresolved [] z ==> null jshell> z.run() Compiling: z.run() Kind: EXPRESSION_STATEMENT -- z.run(); compileAndLoad [Unit(null)] ++setCompilationInfo() Snippet:StatementKey#13-z.run() package REPL; import java.io.*;import java.math.*;import java.net.*;import java.nio.file.*;import java.util.*;import java.util.concurrent.*;import java.util.function.*;import java.util.prefs.*;import java.util.regex.*;import java.util.stream.*;import static REPL.$JShell$11.get1; import static REPL.$JShell$12.z; class $JShell$13 { public static Object do_it$() throws Throwable { z.run(); return null; } } -- diags: [] setStatus() Snippet:StatementKey#13-z.run() - status: VALID compileAndLoad ins = [Unit(null)] -- legit = [Unit(null)] Compiler generating class REPL.$JShell$13 compileAndLoad [Unit(null)] -- deps: [] success: true recordCompilation: Snippet:StatementKey#13-z.run() -- status VALID, unresolved [] | java.lang.NoSuchFieldError thrown: z | at (#3:1) jshell> void m() {z.run();} Compiling: void m() {z.run();} Kind: METHOD -- void m() { z.run(); } compileAndLoad [Unit(m)] ++setCompilationInfo() MethodSnippet:m/()void-void m() {z.run();} package REPL; import java.io.*;import java.math.*;import java.net.*;import java.nio.file.*;import java.util.*;import java.util.concurrent.*;import java.util.function.*;import java.util.prefs.*;import java.util.regex.*;import java.util.stream.*;import static REPL.$JShell$11.get1; import static REPL.$JShell$12.z; class $JShell$14 { public static void m() {z.run();}} -- diags: [] setStatus() MethodSnippet:m/()void-void m() {z.run();} - status: VALID compileAndLoad ins = [Unit(m)] -- legit = [Unit(m)] Compiler generating class REPL.$JShell$14 compileAndLoad [Unit(m)] -- deps: [] success: true recordCompilation: MethodSnippet:m/()void-void m() {z.run();} -- status VALID, unresolved [] | created method m() jshell> m() Compiling: m() Kind: EXPRESSION_STATEMENT -- m(); compileAndLoad [Unit(null)] ++setCompilationInfo() Snippet:StatementKey#15-m() package REPL; import java.io.*;import java.math.*;import java.net.*;import java.nio.file.*;import java.util.*;import java.util.concurrent.*;import java.util.function.*;import java.util.prefs.*;import java.util.regex.*;import java.util.stream.*;import static REPL.$JShell$11.get1; import static REPL.$JShell$12.z; import static REPL.$JShell$14.m; class $JShell$15 { public static Object do_it$() throws Throwable { m(); return null; } } -- diags: [] setStatus() Snippet:StatementKey#15-m() - status: VALID compileAndLoad ins = [Unit(null)] -- legit = [Unit(null)] Compiler generating class REPL.$JShell$15 compileAndLoad [Unit(null)] -- deps: [] success: true recordCompilation: Snippet:StatementKey#15-m() -- status VALID, unresolved [] | java.lang.NoSuchFieldError thrown: z | at m (#4:1) | at (#5:1) jshell>
21-03-2018