Skip to content

Commit

Permalink
Fix stackoverflow for scala traits (#9)
Browse files Browse the repository at this point in the history
* Integration test for transitively Serializable objects

* Fix StackoverflowError for scala traits

* Up version to 1.4.1
  • Loading branch information
tianyu authored Jan 3, 2023
1 parent aacf474 commit 22f9ea1
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 16 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The plugin adds `readResolve` method for every object which either:
// plugins dsl
plugins {
id "me.shika.kotlin-object-java-serialization" version "1.4.0"
id "me.shika.kotlin-object-java-serialization" version "1.4.1"
}
// or else
Expand All @@ -25,7 +25,7 @@ buildscript {
}
}
dependencies {
classpath "me.shika:kotlin-object-java-serialization:1.4.0"
classpath "me.shika:kotlin-object-java-serialization:1.4.1"
}
}
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ allprojects {
}

group 'me.shika'
version '1.4.0'
version '1.4.1'
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ObjectSerializationPlugin : KotlinCompilerPluginSupportPlugin {
SubpluginArtifact(
groupId = "me.shika",
artifactId = "kotlin-object-java-serialization",
version = "1.4.0"
version = "1.4.1"
)

override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean =
Expand Down
7 changes: 5 additions & 2 deletions integration-test/build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
apply plugin: "org.jetbrains.kotlin.jvm"
plugins {
id 'org.jetbrains.kotlin.jvm'
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation project('scala-module')
testImplementation 'junit:junit:4.12'

kotlinCompilerPluginClasspath project(':kotlin-plugin')
}
}
8 changes: 8 additions & 0 deletions integration-test/scala-module/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
plugins {
id 'scala'
id 'java-library'
}

dependencies {
api 'org.scala-lang:scala-library:2.12.17'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
trait NotSerializableTrait
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
trait SerializableTrait extends Serializable
3 changes: 3 additions & 0 deletions integration-test/src/main/kotlin/ImplementScala.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object SerializableFromScala: SerializableTrait

object NotSerializableFromScala: NotSerializableTrait
11 changes: 11 additions & 0 deletions integration-test/src/main/kotlin/TestInterface.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import java.io.Serializable

interface TestInterface: Serializable

object DirectlyImplementsTestInterface: TestInterface

abstract class ExtendsTestInterface: TestInterface

object IndirectlyImplementsTestInterface: ExtendsTestInterface()

object NotSerializable
27 changes: 18 additions & 9 deletions integration-test/src/test/kotlin/DeserializationTest.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
import org.junit.Assert.assertEquals
import org.junit.Assert.assertSame
import org.junit.Test
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
import java.io.*

class ObjectSerializationIntegrationTest {
@Test
fun `object instance is the same after deserialization`() {
assertEquals(TestObject, serializeDeserialize(TestObject))
assertSame(TestObject, serializeDeserialize(TestObject))
assertSame(DirectlyImplementsTestInterface, serializeDeserialize(DirectlyImplementsTestInterface))
assertSame(IndirectlyImplementsTestInterface, serializeDeserialize(IndirectlyImplementsTestInterface))
assertSame(SerializableFromScala, serializeDeserialize(SerializableFromScala))
}

private fun serializeDeserialize(instance: Serializable): Serializable {
@Test(expected = NotSerializableException::class)
fun `cannot serialize non-serializable object`() {
serializeDeserialize(NotSerializable)
}

@Test(expected = NotSerializableException::class)
fun `cannot serialize non-serializable object from scala`() {
serializeDeserialize(NotSerializableFromScala)
}

private fun serializeDeserialize(instance: Any): Any? {
val outputStream = ByteArrayOutputStream()
ObjectOutputStream(outputStream).use {
it.writeObject(instance)
}
return ObjectInputStream(ByteArrayInputStream(outputStream.toByteArray())).use {
it.readObject() as TestObject
it.readObject()
}
}
}
2 changes: 1 addition & 1 deletion kotlin-plugin/src/main/kotlin/me/shika/generation/utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fun IrClass.needSerializableFix(): Boolean {

fun IrClass.isSerializable(): Boolean {
return allSuperInterfaces()
.any { it.fqNameWhenAvailable == SERIALIZABLE_FQ_NAME || it.isSerializable() }
.any { it.fqNameWhenAvailable == SERIALIZABLE_FQ_NAME || it !== this && it.isSerializable() }
|| getAllSuperclasses().any { it.isSerializable() }
}

Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ rootProject.name = 'kotlin-object-java-serialization'
include ':gradle-plugin'
include ':kotlin-plugin'
include ':integration-test'
include ':integration-test:scala-module'

0 comments on commit 22f9ea1

Please sign in to comment.