Reproduce and fix ByteString initialization issue (#29244)
* Reproduce ByteString initialization issue * scalafmt * make test reliably fail * core: fix initialization of `ByteString.empty` Refs #29263 Co-authored-by: Johannes Rudolph <johannes.rudolph@gmail.com>
This commit is contained in:
parent
193f4ad704
commit
7f22b9648c
2 changed files with 53 additions and 1 deletions
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Lightbend Inc. <https://www.lightbend.com>
|
||||
*/
|
||||
|
||||
package akka.util
|
||||
|
||||
import java.io.InputStream
|
||||
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.wordspec.AnyWordSpec
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ArrayBuilder
|
||||
|
||||
class ByteStringInitializationSpec extends AnyWordSpec with Matchers {
|
||||
"ByteString intialization" should {
|
||||
"not get confused by initializing CompactByteString before ByteString" in {
|
||||
// a classloader that creates a new universe of classes for everything beneath akka
|
||||
// that prevents that this test interacts with any tests
|
||||
val cleanCl = new ClassLoader(null) {
|
||||
val outerCl = ByteStringInitializationSpec.this.getClass.getClassLoader
|
||||
val buffer = new Array[Byte](1000000)
|
||||
override def loadClass(name: String): Class[_] =
|
||||
if (!name.startsWith("akka")) outerCl.loadClass(name)
|
||||
else {
|
||||
val classFile = name.replace(".", "/") + ".class"
|
||||
val is = outerCl.getResourceAsStream(classFile)
|
||||
val res = slurp(is, new mutable.ArrayBuilder.ofByte)
|
||||
defineClass(name, res, 0, res.length)
|
||||
}
|
||||
|
||||
def slurp(is: InputStream, res: ArrayBuilder[Byte]): Array[Byte] = {
|
||||
val read = is.read(buffer)
|
||||
if (read == 0) throw new IllegalStateException
|
||||
else if (read > 0) slurp(is, res ++= buffer.take(read))
|
||||
else res.result()
|
||||
}
|
||||
}
|
||||
|
||||
import scala.language.reflectiveCalls
|
||||
type WithRun = { def run(): Unit }
|
||||
cleanCl.loadClass("akka.util.ByteStringInitTest").newInstance().asInstanceOf[WithRun].run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ByteStringInitTest {
|
||||
def run(): Unit = {
|
||||
require(CompactByteString.empty ne null)
|
||||
require(ByteString.empty ne null)
|
||||
}
|
||||
}
|
||||
|
|
@ -747,7 +747,7 @@ sealed abstract class ByteString
|
|||
|
||||
override protected def fromSpecific(coll: IterableOnce[Byte]): ByteString = ByteString(coll)
|
||||
override protected def newSpecificBuilder: mutable.Builder[Byte, ByteString] = ByteString.newBuilder
|
||||
override val empty: ByteString = ByteString.empty
|
||||
override def empty: ByteString = ByteString.empty
|
||||
|
||||
def apply(idx: Int): Byte
|
||||
private[akka] def byteStringCompanion: ByteString.Companion
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue