Tuesday, December 27, 2011

Java Print Service Frustrations

This is probably not the most exciting "toy" to play with for the holidays, but I wanted to explore some use-cases that involve printing through Java back-end services. Basically, in an enterprise environment you may run into requirements, where the documents you receive or generate also are required to be printed out for whatever reasons. In all honesty, I never had to deal with Java's print Apis and thus started from scratch.

It turns out, that there are 2 approaches (reminds me of the multitude of Date implementations...). One approach dates back to the 1990s and is called the Java 2 Print API and is tied more to User Interfaces (UI) triggering the printing process. With Java 1.4, the Java Print Service API (JPS) was introduced (JSR 6) which serves as a super-set of the the Java 2 Print Api.

The JPS Api is certainly workable but I ran into some serious trouble. For my initial use-case, I may receive simple text documents, e.g. XML that I want to send to a definable printer as plain text.

I was unable to get that to work on my Mac using Mac OS X 10.6.8. However, on my Windows JVM it worked flawlessly and my text files were printed out without any complaints. On my Mac, though, my little Java test application finishes without any errors but my printer queue states:

Error: pstopdffilter/pstocupsraster failed with err number -31000

Googling did not help much either. There seemed to be some anecdotal evidence that other people might have had trouble with text printing as well but I was unable to uncover definite answers (Many of the information is years old). The question I have is whether this is an issue with:
  • My Printer, which is a Brother HL-4070CDW
  • The Mac JVM (Mine is: build 1.6.0_29-b11-402-10M3527)
  • CUPS
  • something else
If any of the readers has encountered similar issues or is able to shed some more light into this issue, please let me know (THANKS!).

While searching for explanations, I stumbled across the following thread on stackoverflow.comhttp://stackoverflow.com/questions/1655297/print-to-specific-printer-ipp-uri-in-java. There they mentioned the following CUPS specific libraries:
Jipsi aparently changed names and moved to Google code:
As I need a generic solution that works not only on Mac using CUPS but also on Windows I have not experimented with any of the libraries above. Nevertheless I wanted to mention them.

I have also tried various other DocFlavors and settings but to no avail. What is interesting, though, is that the printing of PDF files works fine. Printing image files such as PNG or JPG fails as well.

Here is the trivial application that I am using:

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Sides;

public class PrintPS {

  public static void main(String args[]) throws FileNotFoundException, PrintException {
    FileInputStream textStream = new FileInputStream(args[0]); 
    DocFlavor myFormat = DocFlavor.INPUT_STREAM.AUTOSENSE;
    Doc myDoc = new SimpleDoc(textStream, myFormat, null); 
  
    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); 
  
    aset.add(new Copies(1)); 
    aset.add(Sides.ONE_SIDED); 
  
    PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
  
    System.out.println("Printing to default printer: " + printService.getName());
  
    DocPrintJob job = printService.createPrintJob(); 
    job.print(myDoc, aset); 

  }
}

Furthermore, I looked at the follwing Java-based Text editors to see how they accomplish printing (Which works fine on my Mac as well):
RTEXT uses the DocFlavor: DocFlavor.SERVICE_FORMATTED.PRINTABLE which in turn uses a component that implements the java.awt.print.Printable Interface. 

I guess, as a next step I have two options...go down into the trenches of Java2D or have some fun generating PDF files...And all I wanted was to print some simple text that works across Operating Systems. 

4 comments:

Javin @ noClassdeffoundError in Java said...

Thanks for touching JAva print service. there is not much article on this and its really frustrating when you first use it form scratch as I seen you as well.

stephenCollines said...

There are seemed to some unofficial data that other people may have trouble with text printing as well, but I could not discover some answers.

custom business cards

Anonymous said...

oI need help on this topic. Have you guy found a solution to running java printing service in mac os?

TH said...

I am having same problem. Not able to run java printing service in mac os 10.8.2.

The printJob never completed. It always happened in printJobNoMoreEvents and the job just goes end.

My jvm version is build 1.6.0_37-b06-434-11M3909