The fix seems wrong to me .. and the problem is not easy.
Windows defines standard paper sizes and we recognise those and will
always serialise
the "Media" as one of the built-in java pre-defined Media.
But windows printer drivers very typically define additional
driver-specific papers,
so at runtime JDK dynamically creates new instances as these are discovered.
They will be instances of Win32MediaSize and their IDs (enum int values)
will
be entirely dependent on the order they "happened" to be added to the list.
When you serialise this out, all you serialise is
(a) the type (Win32MediaSize) and (b) the int value (see the serialized
form docs
for EnumSyntax).
When you come to *deserialize* then what happens depends on whether the
code that adds those to the list has been run (or not). If it has, you
may well
be lucky and get the right intended paper.
If it has not - which is inevitable if you load the preferences in main(..)
before any printing code has run - then the code that initialises the table
has not been run and the int value is meaningless. Pointing it to the ID
in the super-class is wrong. Also you have not run the Win32MediaSize
constructor ! So you will have deserialized a garbage instance .. it
will have an ID that does not correspond to the table, and was meant
to ID some standard paper size. So the fix is probably worse than the bug.
It seems like there should be a readResolve() for Win32MediaSize that
first initialises the table.
And it is only *this simple* (yes, I mean that) because you only have one
printer involved. Get 4 printers with custom IDs and you don't even know
in which order these printers had their IDs initialised.
The documented serialised form leaves you with essentially insufficient
information.
It seems like Win32MediaSize needs a serialised form that includes the
extra info.
But if you "delete" the printer and run the app you now have useless
serialised data
and need to esstablish a policy around that.
Also it seems likely we have the same issue in the CUPS code ..
This is a non-trivial bug and will likely take a lot of careful work to
figure out all the spec/compat/behavioural issues.
-phil.
On 07/15/2016 02:36 AM, Prasanta Sadhukhan wrote:
Hi All,
Bug: https://bugs.openjdk.java.net/browse/JDK-6278300
Please review a fix for an issue where it is seen that
Deserialization of a javax.print.attribute.standard.MediaPrintableArea
printer attribute fails when the serialization happened in a prior
invocation of the program
only for a *non-standard* page size say 4"x6"
It is because EnumSyntax.readResolve() tries to get the EnumSyntax[]
table from Win32MediaSize when the objects are read
and if the EnumSyntax table is not initialized or 0 in length, then
readResolve() will find the object value being read is not in the
EnumSyntax table and will throw this InvalidObjectException
java.io.InvalidObjectException: Integer value = 9 not in valid range
0..-1for class class sun.print.Win32MediaSize
at
javax.print.attribute.EnumSyntax.readResolve(java.desktop@9-internal/EnumSyntax.java:204)
at
jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-internal/Native
Method)
at
jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-internal/NativeMethodAccessorImpl.java:62)
at
jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-internal/DelegatingMethodAccessorImpl.java:43)
at
java.lang.reflect.Method.invoke(java.base@9-internal/Method.java:533)
at
java.io.ObjectStreamClass.invokeReadResolve(java.base@9-internal/ObjectStreamClass.java:1150)
at
java.io.ObjectInputStream.readOrdinaryObject(java.base@9-internal/ObjectInputStream.java:1835)
at
java.io.ObjectInputStream.readObject0(java.base@9-internal/ObjectInputStream.java:1371)
at
java.io.ObjectInputStream.readObject(java.base@9-internal/ObjectInputStream.java:371)
When the printDialog() is invoked, then EnumSyntax table will be
initialised to the current paper ids. But, if printDIalog() is invoked
AFTER objects are deserialised, we run into this problem of enumTable
being 0 in length.
Proposed fix is, to check if the enumtable is not initialised, then
fallback to the supported media size enum table.
webrev: http://cr.openjdk.java.net/~psadhukhan/6278300/webrev.00/
I made it noreg-hard as it needs a custom paper size to be added to
printer media list before invoking the serialization testcase present
in JBS bug entry.
Regards
Prasanta