JDK-8130264 : Change the mechanism by which JDK loads the platform-specific PrinterJob implementation
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6,7,8,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-07-01
  • Updated: 2019-04-22
  • Resolved: 2018-11-30
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 12
12 b23Fixed
Related Reports
CSR :  
Relates :  
Description
Whilst examining the cases in which core reflection internally in the JDK it
was noted that the implementation class of java.awt.print.PrinterJob  is
located via a System property java.awt.printerjob.

This lead to a question as to whether this is a "pluggable" SPI that
can be over-ridden by external code. There was in fact no such intention
and it was just a convenience. See the docs in System.c which say :

  /* Note: java.awt.printerjob is an implementation private property which
     * just happens to have a java.* name because it is referenced in
     * a java.awt class. It is the mechanism by which the implementation
     * finds the appropriate class in the JRE for the platform.
     * It is explicitly not designed to be overridden by clients as
     * a way of replacing the implementation class, and in any case
     * the mechanism by which the class is loaded is constrained to only
     * find and load classes that are part of the JRE.
     * This property may be removed if that mechanism is redesigned
     */
    PUTPROP(props, "java.awt.printerjob", sprops->printerJob); 

It may be best to do that and stop this internal property from polluting the public properties.
Comments
javax.print.PrintServiceLookup uses ServiceLoader to find the platform class, bundled as a Service. But there the javax.print API has declared that these are services. I don't know if I want to do the same here since they really aren't. One by product of that is that to make things easier for the module-info we renamed the platform implementation classes to be the same so the module-info could be the same. But I don't think that is appropriate here. In this and similar cases its not just the name but the package and renaming everything to sun.print.PrinterJob (for example) would be quite disruptive. But perhaps we can use a class of that name as a platform-specific proxy which returns the actual instance. I'm sure this would be more lightweight than a service and less disruptive than renaming the existing classes. I have confirmed with the build team that if a class with the same name is in "share" and also in a platform location such as "windows" that the platform-specific one will always prevail. So we can default in "share" to the PSPrinterJob class which will then get picked up on all unix platforms and just have mac + windows specific classes there.
15-11-2018