Skip to content

Commit 2a83ac9

Browse files
committed
Fix Deserialization Issues for ChildProcessors
- make childParsers an array instead of a vector. We do this because Vectors (and other scala collections) have an issue where failure to deserialize leads to very unhelpful error messages, possible a bug in Java deserialization logic. And when using things like charsets/udfs/layers, it's very easy to mess up classpaths and hit this bug, so it's important to have good diagnostics. The solution is to avoid scala collections for things that might fail deserialization. We could switch to a Java Vector, but we don't really need the functionality the Vector provides. The uses of these Vectors just need fast length and indexing, which Array provides. - make childProcessors a def instead of a lazy val. Changing childProcessors causes it to not be serialized at all so the fact that it's a Vector doesn't matter. Using a def could cause it to be calculated multiple times, but childProcessors is only accessed once per Processor during compilation, so this isn't an issue. In fact, it probably wants to be a def since childProcessors is something we'll never use again so it just wastes memory as a val - change runtimeDependencies to def for the same reason as childProcessors DAFFODIL-2152
1 parent 5150220 commit 2a83ac9

File tree

79 files changed

+258
-247
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+258
-247
lines changed

daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/Grammar.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class SeqComp private (context: SchemaComponent, children: Seq[Gram])
9292
final override lazy val parser = {
9393
if (parserChildren.isEmpty) new NadaParser(context.runtimeData)
9494
else if (parserChildren.length == 1) parserChildren.head
95-
else new SeqCompParser(context.runtimeData, parserChildren.toVector)
95+
else new SeqCompParser(context.runtimeData, parserChildren.toArray)
9696
}
9797

9898
lazy val unparserChildren = {
@@ -110,7 +110,7 @@ class SeqComp private (context: SchemaComponent, children: Seq[Gram])
110110
final override lazy val unparser = {
111111
if (unparserChildren.isEmpty) new NadaUnparser(context.runtimeData)
112112
else if (unparserChildren.length == 1) unparserChildren.head
113-
else new SeqCompUnparser(context.runtimeData, unparserChildren.toVector)
113+
else new SeqCompUnparser(context.runtimeData, unparserChildren.toArray)
114114
}
115115
}
116116

daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/ChoiceCombinator.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ case class ChoiceCombinator(ch: ChoiceTermBase, alternatives: Seq[Gram])
7979

8080
lazy val parser: Parser = {
8181
if (!ch.isDirectDispatch) {
82-
val cp = new ChoiceParser(ch.termRuntimeData, parsers.toVector)
82+
val cp = new ChoiceParser(ch.termRuntimeData, parsers.toArray)
8383
ch.choiceLengthKind match {
8484
case ChoiceLengthKind.Implicit => cp
8585
case ChoiceLengthKind.Explicit =>

daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/SequenceCombinator.scala

+9-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import org.apache.daffodil.lib.util.Misc
2727
import org.apache.daffodil.runtime1.processors.parsers._
2828
import org.apache.daffodil.runtime1.processors.unparsers._
2929
import org.apache.daffodil.unparsers.runtime1._
30+
import org.apache.daffodil.unparsers.runtime1.{ Separated => SeparatedUnparser }
3031

3132
/**
3233
* Base class for all kinds of sequences.
@@ -71,7 +72,7 @@ class OrderedSequence(sq: SequenceTermBase, sequenceChildrenArg: Seq[SequenceChi
7172
// the mta parser differently to avoid this
7273
private lazy val sepUnparser = sepGram.unparser
7374

74-
lazy val sequenceChildren = sequenceChildrenArg.toVector
75+
lazy val sequenceChildren = sequenceChildrenArg.toArray
7576

7677
override lazy val parser: Parser = sq.hasSeparator match {
7778
case true =>
@@ -117,7 +118,7 @@ class OrderedSequence(sq: SequenceTermBase, sequenceChildrenArg: Seq[SequenceChi
117118
sepMtaAlignmentMaybe,
118119
sepMtaUnparserMaybe,
119120
sepUnparser,
120-
childUnparsers
121+
childUnparsers.map(_.asInstanceOf[SequenceChildUnparser with SeparatedUnparser])
121122
)
122123
case false =>
123124
new OrderedUnseparatedSequenceUnparser(srd, childUnparsers)
@@ -155,7 +156,7 @@ class UnorderedSequence(
155156
// the mta parser differently to avoid this
156157
private lazy val sepUnparser = sepGram.unparser
157158

158-
private lazy val sequenceChildren = sequenceChildrenArg.toVector
159+
private lazy val sequenceChildren = sequenceChildrenArg.toArray
159160

160161
private lazy val parsers = alternatives.map(_.parser)
161162

@@ -209,7 +210,11 @@ class UnorderedSequence(
209210
sepMtaAlignmentMaybe,
210211
sepMtaUnparserMaybe,
211212
sepUnparser,
212-
childUnparsers
213+
childUnparsers.map(
214+
_.asInstanceOf[
215+
SequenceChildUnparser with SeparatedUnparser
216+
]
217+
)
213218
)
214219
case false =>
215220
new OrderedUnseparatedSequenceUnparser(srd, childUnparsers)

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BCDUnparsers.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class BCDIntegerRuntimeLengthUnparser(
4747
) extends BCDIntegerBaseUnparser(e)
4848
with HasRuntimeExplicitLength {
4949

50-
override lazy val runtimeDependencies = Vector(lengthEv)
50+
override def runtimeDependencies = Vector(lengthEv)
5151
}
5252

5353
final class BCDIntegerDelimitedUnparser(e: ElementRuntimeData)
@@ -59,7 +59,7 @@ final class BCDIntegerDelimitedUnparser(e: ElementRuntimeData)
5959
final class BCDIntegerMinimumLengthUnparser(e: ElementRuntimeData)
6060
extends BCDIntegerBaseUnparser(e) {
6161

62-
override lazy val runtimeDependencies = Vector()
62+
override def runtimeDependencies = Vector()
6363

6464
override def getBitLength(s: ParseOrUnparseState): Int = {
6565
val number = getNumberToPut(s.asInstanceOf[UState])
@@ -91,7 +91,7 @@ class BCDDecimalRuntimeLengthUnparser(
9191
) extends BCDDecimalBaseUnparser(e, binaryDecimalVirtualPoint)
9292
with HasRuntimeExplicitLength {
9393

94-
override lazy val runtimeDependencies = Vector(lengthEv)
94+
override def runtimeDependencies = Vector(lengthEv)
9595
}
9696

9797
final class BCDDecimalDelimitedUnparser(e: ElementRuntimeData, binaryDecimalVirtualPoint: Int)
@@ -105,7 +105,7 @@ final class BCDDecimalMinimumLengthUnparser(
105105
binaryDecimalVirtualPoint: Int
106106
) extends BCDDecimalBaseUnparser(e, binaryDecimalVirtualPoint) {
107107

108-
override lazy val runtimeDependencies = Vector()
108+
override def runtimeDependencies = Vector()
109109

110110
override def getBitLength(s: ParseOrUnparseState): Int = {
111111
val number = getNumberToPut(s.asInstanceOf[UState])

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryBooleanUnparsers.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class BinaryBooleanUnparser(
116116
lengthUnits
117117
) {
118118

119-
override lazy val runtimeDependencies = Vector(lengthEv)
119+
override def runtimeDependencies = Vector(lengthEv)
120120

121121
override def getBitLength(s: ParseOrUnparseState): Int = {
122122
val nBytesAsJLong = lengthEv.evaluate(s)
@@ -140,7 +140,7 @@ class BinaryBooleanMinimumLengthUnparser(
140140
lengthUnits
141141
) {
142142

143-
override lazy val runtimeDependencies = Vector()
143+
override def runtimeDependencies = Vector()
144144

145145
override def getBitLength(s: ParseOrUnparseState): Int = 32
146146

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BinaryNumberUnparsers.scala

+8-8
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class BinaryIntegerKnownLengthUnparser(
111111
) extends BinaryIntegerBaseUnparser(e)
112112
with HasKnownLengthInBits {
113113

114-
override lazy val runtimeDependencies = Vector()
114+
override def runtimeDependencies = Vector()
115115

116116
}
117117

@@ -122,7 +122,7 @@ class BinaryIntegerRuntimeLengthUnparser(
122122
) extends BinaryIntegerBaseUnparser(e)
123123
with HasRuntimeExplicitLength {
124124

125-
override val runtimeDependencies = Vector(lengthEv)
125+
override def runtimeDependencies = Vector(lengthEv)
126126
}
127127

128128
class BinaryIntegerMinimumLengthUnparser(
@@ -132,7 +132,7 @@ class BinaryIntegerMinimumLengthUnparser(
132132

133133
private val primNumeric = e.optPrimType.get.asInstanceOf[NodeInfo.PrimType.PrimNumeric]
134134

135-
override lazy val runtimeDependencies = Vector()
135+
override def runtimeDependencies = Vector()
136136

137137
override def getBitLength(s: ParseOrUnparseState): Int = {
138138
if (maybeNBits.isDefined) {
@@ -151,7 +151,7 @@ class BinaryIntegerMinimumLengthUnparser(
151151

152152
class BinaryFloatUnparser(e: ElementRuntimeData) extends BinaryNumberBaseUnparser(e) {
153153

154-
override lazy val runtimeDependencies = Vector()
154+
override def runtimeDependencies = Vector()
155155

156156
override def getBitLength(s: ParseOrUnparseState) = 32
157157

@@ -168,7 +168,7 @@ class BinaryFloatUnparser(e: ElementRuntimeData) extends BinaryNumberBaseUnparse
168168

169169
class BinaryDoubleUnparser(e: ElementRuntimeData) extends BinaryNumberBaseUnparser(e) {
170170

171-
override lazy val runtimeDependencies = Vector()
171+
override def runtimeDependencies = Vector()
172172

173173
override def getBitLength(s: ParseOrUnparseState) = 64
174174

@@ -190,7 +190,7 @@ class BinaryDecimalKnownLengthUnparser(
190190
) extends BinaryDecimalUnparserBase(e, signed, binaryDecimalVirtualPoint)
191191
with HasKnownLengthInBits {
192192

193-
override lazy val runtimeDependencies = Vector()
193+
override def runtimeDependencies = Vector()
194194

195195
}
196196

@@ -203,7 +203,7 @@ class BinaryDecimalRuntimeLengthUnparser(
203203
) extends BinaryDecimalUnparserBase(e, signed, binaryDecimalVirtualPoint)
204204
with HasRuntimeExplicitLength {
205205

206-
override val runtimeDependencies = Vector(lengthEv)
206+
override def runtimeDependencies = Vector(lengthEv)
207207
}
208208

209209
class BinaryDecimalMinimumLengthUnparser(
@@ -212,7 +212,7 @@ class BinaryDecimalMinimumLengthUnparser(
212212
binaryDecimalVirtualPoint: Int
213213
) extends BinaryDecimalUnparserBase(e, signed, binaryDecimalVirtualPoint) {
214214

215-
override lazy val runtimeDependencies = Vector()
215+
override def runtimeDependencies = Vector()
216216

217217
override def getBitLength(s: ParseOrUnparseState): Int = {
218218
// type is xs:decimal, the length is determined by the minimum number of

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/BlobLengthUnparser.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import org.apache.daffodil.runtime1.processors.unparsers._
2828

2929
abstract class BlobUnparserBase(override val context: ElementRuntimeData) extends PrimUnparser {
3030

31-
override lazy val runtimeDependencies = Vector()
31+
override def runtimeDependencies = Vector()
3232

3333
protected def getLengthInBits(state: UState): Long
3434

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/ChoiceAndOtherVariousUnparsers.scala

+7-7
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ case class ChoiceBranchMap(
6767
*/
6868
class ChoiceBranchEmptyUnparser(val context: RuntimeData) extends PrimUnparserNoData {
6969

70-
override lazy val runtimeDependencies = Vector()
70+
override def runtimeDependencies = Vector()
7171

7272
def unparse(state: UState): Unit = {
7373
// do nothing
@@ -82,9 +82,9 @@ class ChoiceCombinatorUnparser(
8282
with ToBriefXMLImpl {
8383
override def nom = "Choice"
8484

85-
override val runtimeDependencies = Vector()
85+
override def runtimeDependencies = Vector()
8686

87-
override val childProcessors = choiceBranchMap.childProcessors.toVector
87+
override def childProcessors = choiceBranchMap.childProcessors
8888

8989
def unparse(state: UState): Unit = {
9090
if (state.withinHiddenNest) {
@@ -159,9 +159,9 @@ class DelimiterStackUnparser(
159159
"</DelimiterStack>"
160160
}
161161

162-
override lazy val childProcessors = Vector(bodyUnparser)
162+
override def childProcessors = Vector(bodyUnparser)
163163

164-
override lazy val runtimeDependencies =
164+
override def runtimeDependencies =
165165
(initiatorOpt.toList ++ separatorOpt.toList ++ terminatorOpt.toList).toVector
166166

167167
def unparse(state: UState): Unit = {
@@ -193,9 +193,9 @@ class DynamicEscapeSchemeUnparser(
193193
) extends CombinatorUnparser(ctxt) {
194194
override def nom = "EscapeSchemeStack"
195195

196-
override lazy val childProcessors = Vector(bodyUnparser)
196+
override def childProcessors = Vector(bodyUnparser)
197197

198-
override lazy val runtimeDependencies = Vector(escapeScheme)
198+
override def runtimeDependencies = Vector(escapeScheme)
199199

200200
def unparse(state: UState): Unit = {
201201
// evaluate the dynamic escape scheme in the correct scope. the resulting

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/ConvertBinaryCalendarUnparser.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ case class ConvertBinaryCalendarSecMilliUnparser(
4040
/**
4141
* Primitive unparsers must override runtimeDependencies
4242
*/
43-
override lazy val runtimeDependencies = Vector()
43+
override def runtimeDependencies = Vector()
4444

4545
protected def putNumber(
4646
dos: DataOutputStream,

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/ConvertNonBaseTenTextNumberUnparser.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ case class ConvertNonBaseTenTextNumberUnparser(
2929
base: Int
3030
) extends TextPrimUnparser {
3131

32-
override lazy val runtimeDependencies = Vector()
32+
override def runtimeDependencies = Vector()
3333

3434
override def unparse(state: UState): Unit = {
3535

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/ConvertTextBooleanUnparser.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ case class ConvertTextBooleanUnparser(
3434
/**
3535
* Primitive unparsers must override runtimeDependencies
3636
*/
37-
override lazy val runtimeDependencies = Vector(textBooleanTrueRepEv, textBooleanFalseRepEv)
37+
override def runtimeDependencies = Vector(textBooleanTrueRepEv, textBooleanFalseRepEv)
3838

3939
def unparse(state: UState): Unit = {
4040

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/ConvertTextCalendarUnparser.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ case class ConvertTextCalendarUnparser(
3737
/**
3838
* Primitive unparsers must override runtimeDependencies
3939
*/
40-
override lazy val runtimeDependencies = Vector(calendarEv, dateTimeFormatterEv)
40+
override def runtimeDependencies = Vector(calendarEv, dateTimeFormatterEv)
4141

4242
def unparse(state: UState): Unit = {
4343

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/ConvertTextStandardNumberUnparser.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ case class ConvertTextCombinatorUnparser(
3535
converterUnparser: Unparser
3636
) extends CombinatorUnparser(rd) {
3737

38-
override lazy val runtimeDependencies = Vector()
38+
override def runtimeDependencies = Vector()
3939

40-
override lazy val childProcessors = Vector(converterUnparser, valueUnparser)
40+
override def childProcessors = Vector(converterUnparser, valueUnparser)
4141

4242
override def unparse(state: UState): Unit = {
4343
converterUnparser.unparse1(state)
@@ -57,7 +57,7 @@ case class ConvertTextNumberUnparser(
5757
with TextDecimalVirtualPointMixin
5858
with ToBriefXMLImpl {
5959

60-
override lazy val runtimeDependencies = Vector(textNumberFormatEv)
60+
override def runtimeDependencies = Vector(textNumberFormatEv)
6161

6262
override def unparse(state: UState): Unit = {
6363

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/ConvertZonedNumberUnparser.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ case class ConvertZonedCombinatorUnparser(
3030
converterUnparser: Unparser
3131
) extends CombinatorUnparser(rd) {
3232

33-
override lazy val runtimeDependencies = Vector()
33+
override def runtimeDependencies = Vector()
3434

35-
override lazy val childProcessors = Vector(converterUnparser, valueUnparser)
35+
override def childProcessors = Vector(converterUnparser, valueUnparser)
3636

3737
override def unparse(state: UState): Unit = {
3838
converterUnparser.unparse1(state)
@@ -52,7 +52,7 @@ case class ConvertZonedNumberUnparser(
5252
with TextDecimalVirtualPointMixin
5353
with ToBriefXMLImpl {
5454

55-
override lazy val runtimeDependencies = Vector()
55+
override def runtimeDependencies = Vector()
5656

5757
override def unparse(state: UState): Unit = {
5858

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/DelimitedUnparsers.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ sealed class StringDelimitedUnparser(
4040
isDelimRequired: Boolean
4141
) extends TextPrimUnparser {
4242

43-
override lazy val runtimeDependencies = Vector()
43+
override def runtimeDependencies = Vector()
4444

4545
val fieldDFA = CreateFieldDFA()
4646
val textUnparser = new TextDelimitedUnparser(context)

daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/unparsers/runtime1/DelimiterUnparsers.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class DelimiterTextUnparser(
3535

3636
private def erd = context
3737

38-
override lazy val runtimeDependencies = Vector()
38+
override def runtimeDependencies = Vector()
3939

4040
override lazy val nom = {
4141
if (delimiterType == DelimiterTextType.Initiator) "InitiatorUnparser"

0 commit comments

Comments
 (0)