Rohan Prabhu
Rohan Prabhu

Reputation: 7302

Printing (with lpr) works from command line, but not from Java

So, first things first, we cannot use the javax print services because it is extremely slow as we have more than 20,000 printers installed on a machine (the lookup uses lpstat which is incredibly slow). So, we're using lpr.

When I do this:

cat myfile.pdf | lpr -P "MyPrinter"

it prints the file perfectly to the printer name MyPrinter. To do the same in Java, I'm doing this:

cmd = String.format("lpr -P \"%s\"", "MyPrinter");

Process p = Runtime.getRuntime().exec(cmd);

OutputStream out = p.getOutputStream();

/*
 This essentially runs a thread which reads from a stream and
 outputs it to the STDOUT. This is what I've written to help with
 debugging
*/
StreamRedirect inRed = new StreamRedirect(p.getInputStream(), "IN");
StreamRedirect erRed = new StreamRedirect(p.getErrorStream(), "ER");

inRed.start();
erRed.start();


/*
 This is where I write to lprs STDIN. `document` is an InputStream
*/

final byte buf[] = new byte[1024];
int len;

while((len = document.read(buf)) > 0) {
    out.write(buf, 0, len);
}

out.flush();
out.close();

But, I get the following error:

SR[ER]>>lpr: The printer or class was not found.

Here, SR[ER] is just a custom label that is prefixed by the StreamRedirect. Why is this happening? Why is it able to find a printer when I run it from my command line, but not otherwise?

Also, I tried to run whoami from within the Java program and it says that I am running it as the same user I am logged in as (the same user with which I execute lpr on the command line).

Any help?

Upvotes: 2

Views: 6304

Answers (2)

Zach
Zach

Reputation: 1

cups-bsd includes lpr which is made to be used with Java.

Be sure to execute apt-get remove lpr and apt-get install cups-bsd.

Upvotes: 0

stacker
stacker

Reputation: 68992

You need to put the command and the arguments in a string array

String[] cmd = new String[] { "lpr" , "-P", "MyPrinter" };

Process p = Runtime.getRuntime().exec(cmd);

You might also want to use the newer ProcessBuilder class.

Upvotes: 4

Related Questions