JDK-6448717 : Unable to retrieve printer list on system with unconnected printers
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.2_09,5.0,6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-07-13
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
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 JDK 6 JDK 7
5.0u11Fixed 6u1Fixed 7 b03Fixed
Related Reports
Relates :  
Description
J2SE Version (please include all output from java -version flag):
  java version "1.6.0-rc"
  Java(TM) SE Runtime Environment (build 1.6.0-rc-b90)
  Java HotSpot(TM) Client VM (build 1.6.0-rc-b90, mixed mode, sharing)

Does this problem occur on J2SE 1.4.x or 5.0.x ?  Yes / No (pick one)
  Yes 5.0 U6
  Possible regression from 6.0 beta, in which bug 4916938 is reportedly fixed

Operating System Configuration Information (be specific):
  Windows XP Pro SP2

Hardware Configuration Information (be specific):
  Sony Vaio

Bug Description:
  Same or related to 4916938

Getting printer list hangs when a printer is listed as "Unable to connect"

On my laptop, I have a printer from home installed.  The printer is actually physically connected to my home computer and shared so this laptop can print to it over the wireless network when I am at home.  When I am at work, it shows up on the "Printers and Faxes" screen with a status of "Unable to connect".  

The problem is that trying to just bring up my printer list in Java takes 6 - 8 minutes.  (8 minutes using 5.0_6, 6 minutes using 6.0 b90)  If I go into Word, my printer list is instant.  However, if I select this printer, Word hangs for about a minute and then asks me if I want to wait longer.

My theory is that since Java gets the capabilities of each printer first, before returning the list, one bad print driver or bad connection can wreak havoc.  A hang, like this, can occur.  Or a bad driver could crash the VM leaving a user unable to print or know which printer is the offending one.

In Word, as long as this printer is not selected, it makes no difference that I have a single bad printer.  If I would accidentally select the bad printer, I would soon learn not to do that.  

In Java, its very existence means that I have to wait.  If the wait was a few seconds, it would be livable, but there is no way the average user will wait 6 - 8 minutes before giving up.

These calls all take a long time:
services = PrintServiceLookup.lookupPrintServices(SERVICE_FORMATTED.PAGEABLE,null);
services = PrintServiceLookup.lookupPrintServices(SERVICE_FORMATTED.PRINTABLE,null);
services = PrintServiceLookup.lookupPrintServices(null,null);
services = java.awt.print.PrinterJob.lookupPrintServices();
(Looks like sun.print.Win32PrintServiceLookup.getPrintServices calls PrintServiceLookup)

I am not sure what the best solution is for this, but it seems like the getting the capabilities lazily would solve lots of problems.  A bad print driver that causes the VM to crash (This has happened!) could be identified and avoided.  Getting the services would probably also be faster.  Lastly, and more applicable to this bug, a hanging printer could be avoided and the user not forced to endure this interminably long wait when the list is requested.

A problem with looking up the capabilities later might be that, if the printer is selected and the capabilities are loaded on demand, developers may not be expecting it and the EDT might be the thread that gets hung.  Still, this would essentially be the same way Windows deals with it, as the Word dialog is locked while it tries to access the unconnected printer.

Deleting the "Unable to connect" printer solved the problem and brought down the wait to a couple of seconds.  However, this is not an acceptable work-around as we cannot tell our clients that they need to delete printers from their system to use our product.

Thread dumps created during the hangs
-------------------------------------

"RequestExecutor foreground: 1" daemon prio=2 tid=0x03551400 nid=0xe58 runnable [0x0822f000..0x0822fd94]
   java.lang.Thread.State: RUNNABLE
	at sun.print.Win32PrintService.getCapabilities(Native Method)
	at sun.print.Win32PrintService.getPrinterCapabilities(Unknown Source)
	at sun.print.Win32PrintService.getSupportedDocFlavors(Unknown Source)
	at sun.print.Win32PrintService.isDocFlavorSupported(Unknown Source)
	at sun.print.Win32PrintService.getUnsupportedAttributes(Unknown Source)
	at sun.print.Win32PrintServiceLookup.getPrintServices(Unknown Source)
	at javax.print.PrintServiceLookup.getServices(Unknown Source)
	at javax.print.PrintServiceLookup.lookupPrintServices(Unknown Source)
	at dsi.system.print.client.ActGetPrintServices.execute(ActGetPrintServices.java:32)
	at dsi.client.request.AbstractRequest.processBackground(AbstractRequest.java:141)
	at dsi.client.request.RequestExecutor$ExecQueue.processRequest(RequestExecutor.java:183)
	at dsi.client.request.RequestExecutor$ExecQueue.run(RequestExecutor.java:222)
	at java.lang.Thread.run(Unknown Source)

"RequestExecutor foreground: 1" daemon prio=2 tid=0x036e7000 nid=0xd98 runnable [0x0c12f000..0x0c12fb14]
   java.lang.Thread.State: RUNNABLE
	at sun.print.Win32PrintService.getCapabilities(Native Method)
	at sun.print.Win32PrintService.getPrinterCapabilities(Unknown Source)
	at sun.print.Win32PrintService.getSupportedDocFlavors(Unknown Source)
	at sun.print.Win32PrintService.isDocFlavorSupported(Unknown Source)
	at sun.print.Win32PrintService.getUnsupportedAttributes(Unknown Source)
	at sun.print.Win32PrintServiceLookup.getPrintServices(Unknown Source)
	at javax.print.PrintServiceLookup.getServices(Unknown Source)
	at javax.print.PrintServiceLookup.lookupPrintServices(Unknown Source)
	at java.awt.print.PrinterJob.lookupPrintServices(Unknown Source)
	at dsi.system.print.client.ActGetPrintServices.execute(ActGetPrintServices.java:34)
	at dsi.client.request.AbstractRequest.processBackground(AbstractRequest.java:141)
	at dsi.client.request.RequestExecutor$ExecQueue.processRequest(RequestExecutor.java:183)
	at dsi.client.request.RequestExecutor$ExecQueue.run(RequestExecutor.java:222)
	at java.lang.Thread.run(Unknown Source)



Steps to Reproduce (be specific):
See above

Comments
EVALUATION getPrinterCapabilities is still called for each printer that's why it's taking so long. The fix is to limit the call to this function to the default printer only.
26-07-2006