[ 
https://issues.apache.org/jira/browse/DAFFODIL-3073?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Steve Lawrence updated DAFFODIL-3073:
-------------------------------------
    Description: 
Daffodil implements saved parsers by just serializing the DataProcessor. 
Although Scala guarantees binary compatibility, it does not guarantee 
serialization compatibility. This means that if you serialize a saved processor 
using one version of Scala and try to reload it on another version of scala, 
it's possible things could break. In practice, this doesn't seem to break 
things with Daffodil usage of the scala library and things we happen to 
serialize--most classes we use are written to be compatible.

One type where this isn't the case is with scala's ArraySeq. This type does not 
implement serialVersionUID so any changes to the class could lead to a new UID 
and incompatibilities. And Scala 2.13.17 made changes that caused this to 
happen. Daffodil 3.11.0 uses Scala 2.13.16, so using Scala 2.13.17 or newer to 
build saved parers will fail when trying to use them for 3.11.0.

We don't intentionally use ArraySeq directly in any of our serialized classes, 
but Scala implements vararg using ArraySeq. For example, if you have this class:

{code:scala}
class Foo(args: Type*) \{ ... }
{code}

And try to serialize it, you end up with serialized ArraySeq, and potential 
serialization incompatibilities.

And we do use this in one specific serialized class, in CompiledDPath:
{code:scala}
class CompiledDPath(val ops: RecipeOp*) extends Serializable {
{code}

We don't really need this to be an ArraySeq or var args. We should change this 
so ops is just a normal Array, which will help to avoid potential serialization 
incompatibilities in the future if ArraySeq ever changes again.


  was:
Daffodil implements saved parsers by just serializing the DataProcessor. 
Although Scala guarantees binary compatibility, it does not guarantee 
serialization compatibility. This means that if you serialize a saved processor 
using one version of Scala and try to reload it on another version of scala, 
it's possible things could break. In practice, this doesn't seem to break 
things with Daffodil usage of the scala library and things we happen to 
serialize--most classes we use are written to be compatible.

One type where this isn't the case is with scala's ArraySeq. This type does not 
implement serialVersionUID so any changes to the class could lead to a new UID 
and incompatibilities.

We don't intentionally use ArraySeq directly in any of our serialized classes, 
but scala implements vararg using ArraySeq. For example, if you have this class:

{code:scala}
class Foo(args: Type*) \{ ... }
{code}

And try to serialize it, you will end up with serialized ArraySeq. 

We do use this in one specific place, in CompiledDPath:
{code}




> Use of varargs in serialized classes can lead to reload incompatablities
> ------------------------------------------------------------------------
>
>                 Key: DAFFODIL-3073
>                 URL: https://issues.apache.org/jira/browse/DAFFODIL-3073
>             Project: Daffodil
>          Issue Type: Bug
>          Components: Front End
>            Reporter: Steve Lawrence
>            Priority: Major
>             Fix For: 4.2.0
>
>
> Daffodil implements saved parsers by just serializing the DataProcessor. 
> Although Scala guarantees binary compatibility, it does not guarantee 
> serialization compatibility. This means that if you serialize a saved 
> processor using one version of Scala and try to reload it on another version 
> of scala, it's possible things could break. In practice, this doesn't seem to 
> break things with Daffodil usage of the scala library and things we happen to 
> serialize--most classes we use are written to be compatible.
> One type where this isn't the case is with scala's ArraySeq. This type does 
> not implement serialVersionUID so any changes to the class could lead to a 
> new UID and incompatibilities. And Scala 2.13.17 made changes that caused 
> this to happen. Daffodil 3.11.0 uses Scala 2.13.16, so using Scala 2.13.17 or 
> newer to build saved parers will fail when trying to use them for 3.11.0.
> We don't intentionally use ArraySeq directly in any of our serialized 
> classes, but Scala implements vararg using ArraySeq. For example, if you have 
> this class:
> {code:scala}
> class Foo(args: Type*) \{ ... }
> {code}
> And try to serialize it, you end up with serialized ArraySeq, and potential 
> serialization incompatibilities.
> And we do use this in one specific serialized class, in CompiledDPath:
> {code:scala}
> class CompiledDPath(val ops: RecipeOp*) extends Serializable {
> {code}
> We don't really need this to be an ArraySeq or var args. We should change 
> this so ops is just a normal Array, which will help to avoid potential 
> serialization incompatibilities in the future if ArraySeq ever changes again.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to