JDK-8186987 : NullPointerException in RasterPrinterJob without PrinterResolution
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2017-08-24
  • Updated: 2019-03-25
  • Resolved: 2017-09-21
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 10
10 b25Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) Server VM (build 9+181, mixed mode, emulated-client)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.14393]

EXTRA RELEVANT SYSTEM CONFIGURATION :
Printer driver: Brother HL-2240D series

A DESCRIPTION OF THE PROBLEM :
Printing to my network printer "Brother HL-2240D series" failed with a NPE. I use the PrinterJob API. See the stacktrace below. To other printers like CutePDF it is working.

The passed attributeset contains the follow values:

{class javax.print.attribute.standard.MediaPrintableArea=(12.7,12.7)->(184.626,271.621)mm, class javax.print.attribute.standard.Media=iso-a4, class javax.print.attribute.standard.PageRanges=1, class javax.print.attribute.standard.OrientationRequested=portrait, class javax.print.attribute.standard.JobName=Report1, class javax.print.attribute.standard.Chromaticity=monochrome}

REGRESSION.  Last worked in version 8u152


ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
	at java.desktop/sun.print.RasterPrinterJob.setAttributes(RasterPrinterJob.java:1240)
	at java.desktop/sun.awt.windows.WPrinterJob.setAttributes(WPrinterJob.java:696)
	at java.desktop/sun.print.RasterPrinterJob.print(RasterPrinterJob.java:1510)
	at com.inet.viewer.PrinterJobProgress.run(PrinterJobProgress.java:134)
	at java.base/java.lang.Thread.run(Thread.java:844)

REPRODUCIBILITY :
This bug can be reproduced always.


Comments
From the description, it is not an issue in 8, so it will not be backported to JDK 8. It will not be backported to JDK 9 because JDK 9 EOL in March 2018. http://www.oracle.com/technetwork/java/eol-135779.html
15-11-2017

It seems when RasterPrinterJob#setAttributes() is called with no PrinterResolution attribute set, it first checks if PrinterResolution category is supported. If it is supported, then it sees if the supplied resolution value is supported. Now, since no PrinterResolution attribute is set, so isSupportedValue() returns false [as "printer resolution attribute" object is null] It then goes to get the default resolution attribute via getDefaultAttributeValue() which calls getDefaultPrinterSettings() and use yRes,Quality from this printer to construct a "PrinterResolution" object. Now, it seems in Brother HL-2240D series printer, it supports 3 resolution [300, 600, HQ 1200] but for all these 3 resolutions, getDefaultPrinterSettings() returns -50 for yRes and Quality. So, as per this code http://hg.openjdk.java.net/jdk10/client/jdk/file/dbb5b171a16b/src/java.desktop/windows/classes/sun/print/Win32PrintService.java#l1189 res < 0 and no PrinterResolution object is instantiated so when RPJ accesses printerResAttr.getCrossFeedResolution(ResolutionSyntax.DPI); it causes NPE. Proposed fix is to create a default lowly 300 dpi PrinterResolution if, for some reason, yRes and Quality from printer comes out -ve. http://cr.openjdk.java.net/~psadhukhan/8186987/webrev.00/
01-09-2017

The NullPointerException is coming from this piece of code(RasterPrinterJob.java). 1233 printerResAttr = (PrinterResolution)attributes.get(PrinterResolution.class); 1234 if (service.isAttributeCategorySupported(PrinterResolution.class)) { 1235 if (!isSupportedValue(printerResAttr, attributes)) { 1236 printerResAttr = (PrinterResolution) 1237 service.getDefaultAttributeValue(PrinterResolution.class); 1238 } 1239 double xr = 1240 printerResAttr.getCrossFeedResolution(ResolutionSyntax.DPI); 1241 double yr = printerResAttr.getFeedResolution(ResolutionSyntax.DPI); 1242 setXYRes(xr, yr); 1243 } Here it assumes that PrinterResolution attribute is always set, if it is a supported category. So printerResAttr can come as null if PrinterResolution didn't add in to attribute list. This piece of code is added by task JDK-8048328 in JDK9. Compare to JDK8, it is a regression in JDK9.
30-08-2017