Java SE API仕様のMediaSizeに関する間違い15年

間違いはどこから

タイトルを変更しました。旧題名は「PrintRequestAttributeSetにMediaSize指定を追加する?」です。Javaの本家の仕様解説文が長いこと間違ったままであったとという話です。一部はまだ間違ったままです。

最初に信じてうまく行かなくて困ったのは「Java印刷サービスAPIユーザー・ガイド」でしたが、API仕様ドキュメントの記述も違っていました。パッケージの説明ページの最下部なのであまり見ない部分でしたから当時は気がついていませんでした。

Java印刷サービスで印刷する用紙をA4に指定する方法の話です。

Java印刷サービスAPIユーザー・ガイドの中の属性の指定方法には次のような説明があります。

次の例では、PrintRequestAttributeSetを作成して、A4媒体を使用してジョブを5部両面印刷しています。 
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new Copies(5)); 
aset.add(MediaSize.ISO_A4); 
aset.add(Sides.DUPLEX); 

MediaSize.ISO_A4 は正しくありません。正しくはMediaSizeName.ISO_A4です。

上のリンクはJava8のものです。URLにも8が見えています。この記述の過去とこの後が気になります。

Javaに印刷サービスが追加導入されたのは、Java1.4の時ですから2002年ごろのことです。この時の「Java 印刷サービス API ユーザーガイド」は今となっては見つけにくいですが、探し出せました。この記述になっています。

もしかして、印刷サービスの開発の過程で変更になったのに例文が元のままという事態なのかもしれませんが、それでは調査が困難です。間違いのはじまりは諦めることにします。

現在Javaのバージョンは12になっています。誰かが気がつけば修正されるはずです。直っていれば私の理解が正しかったということになりますし、そうでなければ私の理解不足の疑念は晴れません。この間違いと思われる記述は、どこまでこのままなのか調べてみました。

調査する文書

「Java印刷サービスAPI」などでウェブ検索をして出てくるのが上記のリンクのページで、Java8です。9以上がなかなか見つかりません。「Java印刷サービスAPI」は拡張された時の特別な解説文なので、時が経ってもう無くてもいいだろうと、無くなった、あるいは目立つ所に置かないようになったのかもしれません。

探しているうちに、別のところにも同様なプログラム例があることがわかりました。Java印刷サービスを構成するのは、4つのパッケージ、javax.print, javax.print.attribute, javax.print.attribute.standard, javax.print.event ですが、このパッケージの説明文にもありました。

ただし、MediaSize.ISO_A4ではなく、MediaSize.A4になっています。どちらにしても間違っていますが。

このパッケージの説明文のプログラム例はjava1.4からありました。Java5では改行がなくなって2行のリストになっていますが中身は同じ。そして6,7,8で同じです。Java8を出しておきます。

パッケージ javax.print

FileInputStream psStream;
try {
   psStream = new FileInputStream("file.ps");
} catch (FileNotFoundException ffne) {
}
if (psStream == null) {
    return;
}

DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT;
Doc myDoc = new SimpleDoc(psStream, psInFormat, null);  
PrintRequestAttributeSet aset = 
        new HashPrintRequestAttributeSet();
aset.add(new Copies(5));
aset.add(MediaSize.A4);
aset.add(Sides.DUPLEX);
PrintService[] services = 
  PrintServiceLookup.lookupPrintServices(psInFormat, aset);
if (services.length > 0) {
   DocPrintJob job = services[0].createPrintJob();
   try {
        job.print(myDoc, aset);
   } catch (PrintException pe) {}
}

そっくりなプログラム例がパッケージ javax.print.attributeの説明文にもありますが、インスタンス名のpsStreamが大文字小文字のミス、綴のミスでこのままではコンパイルできません。かなり信頼度は落ちます。

FileInputStream psStream;
try {
   psstream = new FileInputStream("file.ps");
} catch (FileNotFoundException ffne) {
}
if (psstream == null) {
    return;
}
//Set the document type.  See the DocFlavor documentation for
//more information.
DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT;
Doc myDoc = new SimpleDoc(pstream, psInFormat, null);  
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new Copies(5));
aset.add(MediaSize.A4);
aset.add(Sides.DUPLEX);

PrintService[] services = 
                PrintServiceLookup.lookupPrintServices(psInFormat, aset);
if (services.length > 0) {
   DocPrintJob job = services[0].createPrintJob();
   try {
        job.print(myDoc, aset);
   } catch (PrintException pe) {}
}

Java9以降

Package javax.printにあるプログラムは正しく修正されています

 FileInputStream psStream;
 try {
     psStream = new FileInputStream("file.ps");
 } catch (FileNotFoundException ffne) {
 }
 if (psStream == null) {
     return;
 }
 DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT;
 Doc myDoc = new SimpleDoc(psStream, psInFormat, null);
 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
 aset.add(new Copies(5));
 aset.add(MediaSizeName.ISO_A4);
 aset.add(Sides.DUPLEX);
 PrintService[] services =
 PrintServiceLookup.lookupPrintServices(psInFormat, aset);
 if (services.length > 0) {
     DocPrintJob job = services[0].createPrintJob();
     try {
         job.print(myDoc, aset);
     } catch (PrintException pe) {}
 }

ただしPackage javax.print.attributeこちらは、大文字小文字、綴の間違いも含めてそのままです。

FileInputStream psStream;
 try {
     psstream = new FileInputStream("file.ps");
 } catch (FileNotFoundException ffne) {
 }
 if (psstream == null) {
     return;
 }
 //Set the document type. See the DocFlavor documentation for
 //more information.
 DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT;
 Doc myDoc = new SimpleDoc(pstream, psInFormat, null);
 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
 aset.add(new Copies(5));
 aset.add(MediaSize.A4);
 aset.add(Sides.DUPLEX);
 PrintService[] services =
     PrintServiceLookup.lookupPrintServices(psInFormat, aset);
 if (services.length > 0) {
     DocPrintJob job = services[0].createPrintJob();
     try {
         job.print(myDoc, aset);
     } catch (PrintException pe) {}
 }

最新Java12では

Package javax.printです。java9のものがそのまま出ています。

FileInputStream psStream;
 try {
     psStream = new FileInputStream("file.ps");
 } catch (FileNotFoundException ffne) {
 }
 if (psStream == null) {
     return;
 }
 DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT;
 Doc myDoc = new SimpleDoc(psStream, psInFormat, null);
 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
 aset.add(new Copies(5));
 aset.add(MediaSizeName.ISO_A4);
 aset.add(Sides.DUPLEX);
 PrintService[] services =
 PrintServiceLookup.lookupPrintServices(psInFormat, aset);
 if (services.length > 0) {
     DocPrintJob job = services[0].createPrintJob();
     try {
         job.print(myDoc, aset);
     } catch (PrintException pe) {}
 }
 

Package javax.print.attributeです。java9のものがそのまま出ています。

FileInputStream psStream;
 try {
     psstream = new FileInputStream("file.ps");
 } catch (FileNotFoundException ffne) {
 }
 if (psstream == null) {
     return;
 }
 //Set the document type. See the DocFlavor documentation for
 //more information.
 DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT;
 Doc myDoc = new SimpleDoc(pstream, psInFormat, null);
 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
 aset.add(new Copies(5));
 aset.add(MediaSize.A4);
 aset.add(Sides.DUPLEX);
 PrintService[] services =
     PrintServiceLookup.lookupPrintServices(psInFormat, aset);
 if (services.length > 0) {
     DocPrintJob job = services[0].createPrintJob();
     try {
         job.print(myDoc, aset);
     } catch (PrintException pe) {}
 }

まとめ

正しいのは、MediaSizeName.ISO_A4です。

バージョン リリース年 印刷サービスガイド API仕様ドキュメントのパッケージ説明
javax.print javax.print.attribute
1.4 2002 MediaSize.ISO_A4 MediaSize.A4 MediaSize.A4
5 2004 MediaSize.ISO_A4 MediaSize.A4 MediaSize.A4
6 2006 MediaSize.ISO_A4 MediaSize.A4 MediaSize.A4
7 2011 MediaSize.ISO_A4 MediaSize.A4 MediaSize.A4
8 2014 MediaSize.ISO_A4 MediaSize.A4 MediaSize.A4
9 2017 MediaSizeName.ISO_A4 MediaSize.A4
10 2018.3 MediaSizeName.ISO_A4 MediaSize.A4
11 2018.9 MediaSizeName.ISO_A4 MediaSize.A4
12 2019.3 MediaSizeName.ISO_A4 MediaSize.A4

Java12

Java11からモジュールの分類が入って、API Specificationへ到達するまでの様子が変わりました。htmlのフレーム仕立てでなくなりました。Java12について構造の概略を示します。

Oracle help CenterJavaのなかのJava SE documentationを選択して JDK 12 Documentation に到達。

JDK 12 Documentationから さらにSpecifications枠のAPI Documentationを選択して、
Java® Platform, Standard Edition & Java Development Kit Version 12 API SpecificationのOverviewに達する。

そこから、Moduleの選択になります。見慣れたものが入っているモジュールは

Module java.base

Module java.desktop

です。

この先は見慣れたクラスなどのマニュアルです。

リンク

調査したリンクのJava8とJava12の一覧です。

version8

Java印刷サービスAPIガイド

Java™ Platform, Standard Edition 8 API Specification

javax.print

javax.print.attribute

version12

Java® Platform, Standard Edition & Java Development Kit Version 12 API Specification

Module java.desktopの中に

javax.print

javax.print.attribute