In the compiler the Options context singleton is used in a lot of places. However, there are some uses that occur before the compiler's command-line arguments have been parsed.
In this scenario, it just appears as if whatever option the code is checking for is not set, even if it actually is, making it too easy to create subtle bugs.
Recommendations:
- Fix the existing bugs (see below)
- Add assertions to detect premature access to the Options instance
- Add a convenience method Options.whenReady(Runnable) that performs some action when the Options instance is ready (immediately if already ready). This relieves client code from having to worry about when that happens.
The following abbreviated call traces represent existing premature access bugs:
Main.compile()
-> Log.instance()
-> JCDiagnostic.Factory.instance()
-> JavacMessages.instance()
-> options.isSet("rawDiagnostics")
Main.compile()
-> Log.instance()
-> JCDiagnostic.Factory.instance()
-> JCDiagnostic.Factory.initOptions()
-> options.isSet("onlySyntaxErrorsUnrecoverable")
Main.compile()
-> BasicJavacTask.initPlugins()
-> Depend.init()
-> Depend.addExports()
-> JavacTool.getStandardFileManager()
-> new JavacFileManager()
-> JavacFileManager.setContext()
-> BaseFileManager.setContext()
-> options.get("procloader");
In this scenario, it just appears as if whatever option the code is checking for is not set, even if it actually is, making it too easy to create subtle bugs.
Recommendations:
- Fix the existing bugs (see below)
- Add assertions to detect premature access to the Options instance
- Add a convenience method Options.whenReady(Runnable) that performs some action when the Options instance is ready (immediately if already ready). This relieves client code from having to worry about when that happens.
The following abbreviated call traces represent existing premature access bugs:
Main.compile()
-> Log.instance()
-> JCDiagnostic.Factory.instance()
-> JavacMessages.instance()
-> options.isSet("rawDiagnostics")
Main.compile()
-> Log.instance()
-> JCDiagnostic.Factory.instance()
-> JCDiagnostic.Factory.initOptions()
-> options.isSet("onlySyntaxErrorsUnrecoverable")
Main.compile()
-> BasicJavacTask.initPlugins()
-> Depend.init()
-> Depend.addExports()
-> JavacTool.getStandardFileManager()
-> new JavacFileManager()
-> JavacFileManager.setContext()
-> BaseFileManager.setContext()
-> options.get("procloader");
- links to
-
Commit(master) openjdk/jdk/644d154c
-
Review(master) openjdk/jdk/23056