The lpr command works fine when tested manually. However, when the application attempts to print using Java's java.io.PrintService API, I encounter the following error:
java.io.IOException: error=254 running: '/usr/bin/lpr' '-PTESTPRN2' '-J Java Printing' '-o job-sheets=standard' '/tmp/javaprint13160595099572358650'
usage: lpr [-fghjlmnprs] [-PPrinter] [-#NumberCopies] [-CClass]
[-JJob] [-TTitle] [-iNumberColumns] [-wWidth] [Filename ...]
The spooler itself is set up correctly and prints without issues when commands are executed manually:
lpr -PTESTPRN2 /etc/hosts
What I've tried:
- Considered downgrading to Java 8, as it might generate compatible lpr commands and lpr with -j and -o works fine, but Java 11 is currently installed. Note:application can't run on java8
- The lpr command works fine when executed manually without unsupported flags (e.g.,
lpr -PTESTPRN2 /path/to/file). - Thought about creating a wrapper script to skip unsupported flags, but that seems not efficent way in production env.
- Write sample Java code that uses JPS to print and got same error with java11 but works on java8.
- Run the sample Java code with wrapper script. It works, but still Temenos gave the same error.
Sample Java Code for Testing
mport javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.io.*;
public class PrintHostsFileWithQueue {
public static void main(String[] args) {
String printerName = "TESTPRN2"; // Replace with your print queue name
try {
// Specify the file to print
File file = new File("/etc/hosts");
if (!file.exists()) {
System.out.println("The file /etc/hosts does not exist.");
return;
}
// Create a FileInputStream for the file
FileInputStream fis = new FileInputStream(file);
// Define the document flavor (plain text)
DocFlavor flavor = DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_8;
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
attributes.add(new Copies(1)); // Number of copies
attributes.add(new JobSheets(JobSheets.NONE, JobSheets.NONE));
// Get all available print services
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(flavor, null);
// Find the specified print queue
PrintService selectedService = null;
for (PrintService service : printServices) {
if (service.getName().equalsIgnoreCase(printerName)) {
selectedService = service;
break;
}
}
if (selectedService == null) {
System.out.println("Printer with name '" + printerName + "' not found.");
fis.close();
return;
}
// Create a print job
DocPrintJob printJob = selectedService.createPrintJob();
// Create a Doc object wrapping the input stream
Doc doc = new SimpleDoc(fis, flavor, null);
// Print the document
printJob.print(doc, null);
System.out.println("Printing /etc/hosts to printer: " + printerName);
fis.close();
} catch (FileNotFoundException e) {
System.out.println("File not found: " + e.getMessage());
} catch (PrintException e) {
System.out.println("Error during printing: " + e.getMessage());
} catch (IOException e) {
System.out.println("Error closing the file: " + e.getMessage());
}
}
}
Wrapper Script
#!/bin/bash
# Step 1: Backup the existing lpr binary
if [ -f /usr/bin/lpr ]; then
echo "Backing up the existing /usr/bin/lpr..."
mv /usr/bin/lpr /usr/bin/lpr.original
else
echo "/usr/bin/lpr does not exist. Exiting."
exit 1
fi
# Step 2: Create the new lpr wrapper script
echo "Creating the new /usr/bin/lpr wrapper script..."
cat <<'EOF' | tee /usr/bin/lpr > /dev/null
#!/bin/bash
# Remove unsupported options and pass others to the original lpr
ARGS=()
for arg in "$@"; do
case "$arg" in
-o*|*-J*) ;; # Ignore unsupported options
*) ARGS+=("$arg") ;;
esac
done
/usr/bin/lpr.original "${ARGS[@]}"
EOF
# Step 3: Make the new script executable
echo "Making /usr/bin/lpr executable..."
chmod +x /usr/bin/lpr
# Step 4: Confirm the change
echo "lpr wrapper script has been created and is now executable."
echo "Test the print command to confirm it's working."