JDK-6181488 : Java Printing: Default print service lookup problems when running CUPS
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2004-10-19
  • Updated: 2016-04-13
  • Resolved: 2016-04-12
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
9Resolved
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)

FULL OS VERSION :
Linux frogstar 2.4.19-64GB-SMP #1 SMP Thu Mar 20 15:42:37 UTC 2003 i686 unknown

EXTRA RELEVANT SYSTEM CONFIGURATION :
SuSE 8.1
glibc 2.2.5
CUPS 1.1.15

A DESCRIPTION OF THE PROBLEM :
PrintServiceLookup.lookupPrintServices() does not return a useful
value under Linux.  There are several possibilities for identifying
the default printer on a Unix/Linux system:

    $PRINTER
    $LPDEST
    lpstat -d

lookupPrintServices() doesn't seem to use any of these.  Instead
it returns the first configured printer on the system, taken in
alphabetical order.  If this happens to be the current user's
default printer, it's only by coincidence.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run test program included below.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The value of $PRINTER, $LPDEST or `lpstat -d`.
ACTUAL -
The first configured printer on the system,
taken in alphabetical order, equivalent to:

    grep -v ^# /etc/printcap | sort | head -1

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.print.*;

public class Printer {
    public static void main( String args[] ) {
        PrintService printer = PrintServiceLookup.lookupDefaultPrintService();
        System.out.println( printer.getName() );
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
PrintService[] services  = null;
PrintService   myPrinter = null;
DocFlavor myFlavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
PrintRequestAttributeSet jobAttrs = new HashPrintRequestAttributeSet();
services = PrintServiceLookup.lookupPrintServices( myFlavor, jobAttrs );
if ( System.getProperty( "os.name" ).startsWith( "Windows" ) )
    // No problem under Windows ...
    myPrinter = PrintServiceLookup.lookupDefaultPrintService();
else {
    try {  // XXX Yuck! XXX
        Process child = Runtime.getRuntime().exec(
            new String[] { "/bin/sh", "-c", "echo ${PRINTER:-$LPDEST}" }
        );
        BufferedReader rdr = new BufferedReader(
            new InputStreamReader( child.getInputStream() )
        );
        String envPrinter = rdr.readLine().trim();
        child.destroy();
        for ( int i=0; myPrinter == null && i<services.length; i++ )
            if ( services[i].getName().equals( envPrinter ) )
                myPrinter = services[i];
    }
    catch ( Exception ignore ) {}
}
if ( myPrinter == null )
    myPrinter = services[0];
###@###.### 10/19/04 21:30 GMT

Comments
JDK-8058316 Implemented querying CUPS to get the default printer .
12-04-2016

EVALUATION I see 3 issues reported in this report: 1. Wrong default printer, compared to output of lpstat -d It is the problem reported in this CR. 2. "Not accepting jobs" status in 1.4 and later releases This is a known bug in 1.4 (see 4918778) If you see a problem in 1.5 or later releases please run "/usr/sbin/lpc status" (see output below) check if queing and printing are both enabled. If you still see a problem, please file a NEW bug. [jgodinez@sfbay test]$ /usr/sbin/lpc status C524: printer is on device 'http' speed -1 queuing is enabled printing is enabled no entries daemon present sCa22P10: printer is on device 'lpd' speed -1 queuing is enabled printing is enabled no entries daemon present 3. PrintServiceLookup.lookupDefaultPrintService or PrintServiceLookup.lookupPrintServices returning null in 1.5 and later releases: Still cannot reproduce this. I tested using these configurations using the program below. Suse 10 and CUPS 1.2.2, Fedora 5 and CUPS 1.1.23 Fedora 5 and CUPS 1.2.4 Check your configuration by running the following commands (see similar output below): "/etc/init.d/cups status" - determine if your cupsd is running? "lpstat -d" or "/usr/sbin/lpc status" - get list of printers and their status If your configuration is OK, file a NEW bug including the output of these commands. ---------------- Services_getStatus.java ------------------------ import javax.print.*; import javax.print.attribute.*; import javax.print.attribute.standard.*; public class Services_getStatus { public static void main(String[] args){ PrintService defServ = PrintServiceLookup.lookupDefaultPrintService(); System.out.println("Default PrintService: "+defServ); PrintService[] serv = PrintServiceLookup.lookupPrintServices(null, null); if (serv.length==0) { System.out.println("no PrintService found"); } else { System.out.println("number of Services "+serv.length); } for (int i = 0; i<serv.length ;i++) { PrintServiceAttributeSet psa = serv[i].getAttributes(); System.out.println("printer name "+(i+1)+" "+psa.get(PrinterName.class)); System.out.println("accepting "+psa.get(PrinterIsAcceptingJobs.class)); } } } ----------------------- OUTPUT: [jgodinez@sfbay etc]$ /etc/init.d/cups status cups: scheduler is running. [jgodinez@sfbay etc]$ cat /etc/fedora-release Fedora Core release 5 (Bordeaux) [jgodinez@sfbay etc]$ lpstat -d system default destination: C524 [jgodinez@sfbay test]$ /usr/sbin/lpc status C524: printer is on device 'http' speed -1 queuing is enabled printing is enabled no entries daemon present sCa22P10: printer is on device 'lpd' speed -1 queuing is enabled printing is enabled no entries daemon present [jgodinez@sfbay test]$ ldd /usr/sbin/lpc linux-gate.so.1 => (0x007a4000) libcups.so.2 => /usr/lib/libcups.so.2 (0x00d6e000) libpthread.so.0 => /lib/libpthread.so.0 (0x07475000) libm.so.6 => /lib/libm.so.6 (0x00db3000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x0774a000) libc.so.6 => /lib/libc.so.6 (0x00111000) libz.so.1 => /usr/lib/libz.so.1 (0x00de0000) /lib/ld-linux.so.2 (0x003f1000) [jgodinez@sfbay test]$ cups-config --api-version 1.2 [jgodinez@sfbay test]$ ../jdk/jdk1.5.0_08/bin/java Services_getStatus Default PrintService: IPP Printer : C524 number of Services 2 printer name 1 C524 accepting accepting-jobs printer name 2 sCa22P10 accepting accepting-jobs ==========================================================================
21-08-2006

EVALUATION The problem is that JDK uses "lpc status" to get the default printer. CUPS has speced this command differently than lpr or lprng (each printing system replaces commmands such as "lpr", "lpc", "lpq" with its own). So we expect only one printer but get back the list of all printers. The first one in that list is currently assumed to be the only one and therefore the system default. We need to find another way to find the default printer for CUPS. It seems CUPS (unlike lpr and lprng) implements a useful version of lpdest (a system V printing command) and that is what returns the default printer, honouring the PRINTER and LPDEST variables with the caveat (from the cups sources that: /* * First see if the LPDEST or PRINTER environment variables are * set... However, if PRINTER is set to "lp", ignore it to work * around a "feature" in most Linux distributions - the default * user login scripts set PRINTER to "lp"... */ Here's some tests which show how cups behaves /usr/sbin/lpc status LEXC710: printer is on device 'lpd' speed -1 queuing is enabled printing is enabled no entries daemon present lexmark: printer is on device 'http' speed -1 queuing is enabled printing is enabled no entries daemon present $ echo $PRINTER PRINTER: Undefined variable. $ echo $LPDEST LPDEST: Undefined variable. $ lpstat -d system default destination: LEXC710 $ setenv PRINTER lexmark $ lpstat -d system default destination: lexmark We have code to detect CUPS. So my suggestion is that we detect CUPS and then use lpstat instead of lpc. We can't just "always" use lpdest because it does not work for the lpd based printing systems. Another alternative would be to query CUPS APIs directly so long as those APIs also can inherit the user's environment - ie an HTTP call will not suffice - it needs to be into library code executing in the user's environment. As it happens this (an HTTP call) is what we do in JDK 1.5. ie we detect CUPS and talk to the CUPS server directly to find the default printer. But that will ignore PRINTER and LPDEST. Its moderately annoying but it seems like we will need to use lpdest to get that default printer, although we would continue to use HTTP to get "all" printers, and also for job submission as we will always specify the printer there, so aren't susceptible to defaults. Some additional testing is needed to be sure. But it appears this is still a bug in 1.5 but with a different root cause. ###@###.### 10/19/04 22:04 GMT
19-10-2004