In my Java 8 application (RHEL 6.x, Wildfly 10.1.0.Final) the first time a user prints a document, application gets stuck while getting the list of printers from the system.
Here is the stacktrace of the blocking thread :
"Thread-211" #799 daemon prio=5 os_prio=0 tid=0x00007fca543a6800 nid=0x10755 runnable [0x00007fca02820000]
java.lang.Thread.State: RUNNABLE
at sun.print.CUPSPrinter.canConnect(Native Method)
at sun.print.CUPSPrinter.isCupsRunning(CUPSPrinter.java:444)
at sun.print.UnixPrintServiceLookup.getDefaultPrintService(UnixPrintServiceLookup.java:650)
- locked <0x00000006d2c7fff8> (a sun.print.UnixPrintServiceLookup)
at sun.print.UnixPrintServiceLookup.refreshServices(UnixPrintServiceLookup.java:277)
- locked <0x00000006d2c7fff8> (a sun.print.UnixPrintServiceLookup)
at sun.print.UnixPrintServiceLookup$PrinterChangeListener.run(UnixPrintServiceLookup.java:947)
Other users trying to print documents and relatives threads are blocked by this one.
I looked at the source code of CUPSPrinter.canConnect()
(native code) and at this point we try to connect to the cups server :
/*
* Checks if connection can be made to the server.
*
*/
JNIEXPORT jboolean JNICALL
Java_sun_print_CUPSPrinter_canConnect(JNIEnv *env,
jobject printObj,
jstring server,
jint port)
{
const char *serverName;
serverName = (*env)->GetStringUTFChars(env, server, NULL);
if (serverName != NULL) {
http_t *http = j2d_httpConnect(serverName, (int)port);
(*env)->ReleaseStringUTFChars(env, server, serverName);
if (http != NULL) {
j2d_httpClose(http);
return JNI_TRUE;
}
}
return JNI_FALSE;
}
In my case CUPS is on the same host listening on port 631. I checked the logs & everything seems to be fine.
I also checked active connections for cups with netstat :
tcp 0 0 0.0.0.0:631 0.0.0.0:* LISTEN 76107/cupsd
tcp 0 0 127.0.0.1:45652 127.0.0.1:631 TIME_WAIT -
tcp 0 0 :::631 :::* LISTEN 76107/cupsd
tcp 0 0 ::1:35982 ::1:631 TIME_WAIT -
tcp 0 0 ::1:35981 ::1:631 TIME_WAIT -
tcp 0 0 ::1:35978 ::1:631 TIME_WAIT -
tcp 0 0 ::1:35979 ::1:631 TIME_WAIT -
udp 0 0 0.0.0.0:631 0.0.0.0:* 76107/cupsd
Important notes :
- If I restart Cups service, thread is not deblocked. It seems to live endessly until application restarts.
- I found a bug similar to this on Open JDK : https://bugs.openjdk.java.net/browse/JDK-6290446 But the workaround of setting
-Dsun.java2d.print.polling=false
does not work for me (the property seems to be cleared at some point for an obscure reason, soPrinterChangeListener
gets instantiated and though polling is not desactivated). - I can't reproduce the problem with a test application (clone of production) on the same server
Please HELP !!