1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
import java.io._
import java.net.URLClassLoader
class C {
def serializeDeserialize[T <: AnyRef](obj: T) = {
val buffer = new ByteArrayOutputStream
val out = new ObjectOutputStream(buffer)
out.writeObject(obj)
val in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray))
in.readObject.asInstanceOf[T]
}
serializeDeserialize((c: String) => c.length)
}
object Test {
def main(args: Array[String]): Unit = {
test()
}
def test(): Unit = {
val loader = getClass.getClassLoader.asInstanceOf[URLClassLoader]
val loaderCClass = classOf[C]
def deserializedInThrowawayClassloader = {
val throwawayLoader: java.net.URLClassLoader = new java.net.URLClassLoader(loader.getURLs, ClassLoader.getSystemClassLoader) {
val maxMemory = Runtime.getRuntime.maxMemory()
val junk = new Array[Byte]((maxMemory / 2).toInt)
}
val clazz = throwawayLoader.loadClass("C")
assert(clazz != loaderCClass)
clazz.newInstance()
}
(1 to 4) foreach { i =>
// This would OOM by the third iteration if we leaked `throwawayLoader` during
// deserialization.
deserializedInThrowawayClassloader
}
}
}
|