JDK-8155765 : javax.tools.ToolProvider::getSystemToolClassLoader returns app class loader even if no tool is available
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-04-29
  • Updated: 2017-05-17
  • Resolved: 2016-11-23
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.
JDK 9
9 b147Fixed
Related Reports
Relates :  
Description
The spec for javax.tools.ToolProvider::getSystemToolClassLoader specifies to return null if no tool is provided.  ToolProvider now finds javac and javadoc.   

Currently, in jdk9, it always returns the application class loader unconditionally which is a bug.

On the other hand, what should it return if jdk.compiler or jdk.javadoc is present in the image but not both?   spec clarification might be needed.
Comments
The module containing javax.tools.ToolProvider (i.e. java.compiler) has been deprivileged, meaning that no additional special action needs to be taken in regard to JDK-8151210, except possibly for a test. That would allow the method to safely always return the system class loader, but that still wouldn't address the spec as currently written. Even though the body of the spec does not mention null, the possibility of a null result is mentioned in the @return tag. The spirit of the original implementation of this method was to return the URLClassLoader created to load tools from tools.jar, in the belief that other vendors might provide other tools via such a channel. With that in mind, how about the following text: Returns a class loader that may be used to load system tools, or null if no such special loader is provided. @implSpec This implementation always returns null. @deprecated This method is subject to removal in a future version of Java SE. Use the {@link java.util.ServiceLoader service loader mechanism} to locate system tools as well as user-installed tools.
14-09-2016

This requires specification change - which Jon will come up with. In private discussion, we agreed to have this assigned to Jon as that makes for more efficient arrangement since otherwise I am looking for input from him anyway on the spec, javadoc, rationale, CCC etc.
13-09-2016

Thanks Mandy. I'll wait for spec clarification from Jon.
05-09-2016

The proposed spec change looks good. FYI. Vincente is also making spec change of ToolProvider::getSystemToolClassLoader to throw SecurityException (JDK-8151210).
17-08-2016

I think I am hearing that - We leave the code as is - Remove from javadoc the phrase "* or {@code null} if no tools are provided" from "@return the class loader for tools provided with this platform * or {@code null} if no tools are provided" (if more changes are required, input would be appreciated) - Mark the method for deprecation with forRemoval=true - Get any necessarily approvals for the API change.
17-08-2016

Notwithstanding the excellent text provided by Alex, I suggest that since the use case for the method has expired (i.e. to access the internal classloader created for tools.jar), we should deprecate the method with forRemoval=true.
16-08-2016

Jon is the authority for javax.tools but a few questions immediately spring to mind about this method: - Should the method be aware of tools that merely exist in _observable_ modules somewhere on disk, or should it return only tools exported by _resolved_ modules elsewhere in the application's module graph? - Should the method return the same loader on successive invocations? (Assuming no perturbation of the environment by, say, an agent that redefines modules and adds reads edges.) - What are "user-installed tools"? The term does not appear elsewhere in javax.tools. Rather, the package spec speaks of "alternative compilers or tools" that appear through the service provider mechanism. I think it would be best to bind the "tools provided with this platform" to the Tool objects returned by the ToolProvider::getSystem* methods: - If ToolProvider::getSystemJavaCompiler returns a non-null reference to a JavaCompiler object, then the class of that object is visible through the loader returned by ToolProvider::getSystemToolClassLoader. - If ToolProvider::getSystemDocumentationTool returns a non-null reference to a DocumentationTool object, then the class of that object is visible through the loader returned by ToolProvider::getSystemToolClassLoader. Then, all questions about "What if the jdk.compiler module is not observable?" or "What if the jdk.javadoc module is not resolved?" are deferred to the getSystem* methods, which should themselves be more specific about what it means for a module to be "available". To allow for the Tool classes to come from different loaders, and to avoid committing to a class loader hierarchy, the method's spec should commit to nothing more than returning a loader that provides visibility to all such classes. Whether it's the same loader every time is a detail best avoided. I suggest: "Returns a class loader through which the classes of tools provided with this platform are visible. The classes of any tools provided by the user are not necessarily visible through this class loader, and should instead be located with the service provider mechanism." (Second sentence slightly edited to avoid overuse of the term "provided".)
16-08-2016

The original spec was written with the existence (or otherwise) of tools.jar in mind. That time has passed, and a clarification is in order. I approve of Alex's suggested change to the specification, although we would still need CCC approval for the change.
16-08-2016

Spec seems clear enough to me: "Returns: the class loader for tools provided with this platform or null if no tools are provided". In the case that the platform only provides a compiler, then "the class loader for tools provided with this platform" is a class loader that knows about the compiler. The 'null' result should occur iff "no tools are provided."
16-08-2016

Alex & Dan, Can you comment on the spec clarification Mandy requests ? TIA.
16-08-2016