Description
Description
It is not currently possible to re-use an IonWriter
to serialize several values across multiple calls to IonObjectMapper#writeValue(IonWriter, Object)
. I believe this is unintentional, as the documentation for that method states that the method will not close the underlying writer.
Impact
The current behavior has a few downsides:
- Attempting to re-use an
IonWriter
results in a somewhat crypticIndexOutOfBoundsException
. This occurs because the writer maintains a list of buffers that is emptied whenclose()
is called. Subsequent writes attempt to access the first buffer in the now empty list. - A new
IonWriter
must be created for each individual value, which requires several buffers/collections/objects to be allocated and initialized. This expense likely dwarfs the cost of serialization. - Each call to
writeValue
causes an Ion Version Marker to be emitted, resetting the symbol table and requiring a new one to be defined for each value. This eliminates a large portion of the size savings one typically gets from encoding their data in Ion.
Cause
The ObjectMapper
class's implementation of _configAndWriteValue
calls close()
on the JsonGenerator
that's used to serialize the provided value.
Ion's implementation of JsonGenerator
is IonGenerator
, and its implementation of close()
attempts to flush the IonWriter
by calling close()
on it.
Suggested Fix
I believe that IonGenerator#close
should only call _writer.close()
if _ioContext.isResourceManaged()
is true. Otherwise, the user provided a reference to the IonWriter
being used and should have the authority to flush()
/finish()
/close()
it at their own discretion.
Please let me know if you agree with this assessment. I'd be happy to put together a PR with this change. Thanks!