From bcfed89c89325c9aa62b4399f158825d831634eb Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Thu, 12 Jan 2023 18:55:16 +0300 Subject: [PATCH 1/2] ClassNotFoundException from KryoHelper.readObject when running ContestEstimator for seata-core-0.5.0 #1649 Avoid Java 9 code style --- .../src/main/java/SettingsTemplateHelper.java | 8 ++-- .../util/JavaSerializerWrapper.kt | 42 +++++++++++++++++++ .../utbot/instrumentation/util/KryoHelper.kt | 38 +---------------- 3 files changed, 47 insertions(+), 41 deletions(-) create mode 100644 utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/JavaSerializerWrapper.kt diff --git a/buildSrc/src/main/java/SettingsTemplateHelper.java b/buildSrc/src/main/java/SettingsTemplateHelper.java index 099d019456..45502e2f33 100644 --- a/buildSrc/src/main/java/SettingsTemplateHelper.java +++ b/buildSrc/src/main/java/SettingsTemplateHelper.java @@ -47,7 +47,7 @@ public static void proceed(Project project) { if (s.startsWith("enum class ")) {//Enum class declaration enums.add(new EnumInfo(s.substring(11, s.length() - 2))); } else if (s.matches("[A-Z_]+,?") && !enums.isEmpty()) {//Enum value - var enumValue = s.substring(0, s.length()); + String enumValue = s.substring(0, s.length()); if (enumValue.endsWith(",")) enumValue = enumValue.substring(0, enumValue.length() - 1); enums.get(enums.size() - 1).docMap.put(enumValue, new ArrayList<>(docAcc)); } else if (s.startsWith("const val ")) {//Constand value to be substitute later if need @@ -66,9 +66,9 @@ public static void proceed(Project project) { s = acc.toString(); acc.delete(0, acc.length()); if (s.startsWith("var") || s.startsWith("val")) { - var i = s.indexOf(" by ", 3); + int i = s.indexOf(" by ", 3); if (i > 0) { - var key = s.substring(3, i).trim(); + String key = s.substring(3, i).trim(); if (key.contains(":")) { key = key.substring(0, key.lastIndexOf(':')); } @@ -91,7 +91,7 @@ public static void proceed(Project project) { i = s.indexOf('(', i); if (i > 0) { s = s.substring(i + 1); - var defaultValue = s.substring(0, s.indexOf(')')).trim(); + String defaultValue = s.substring(0, s.indexOf(')')).trim(); if (defaultValue.contains(",")) defaultValue = defaultValue.substring(0, defaultValue.indexOf(',')); defaultValue = dictionary.getOrDefault(defaultValue, defaultValue); if (defaultValue.matches("[\\d_]+L")) { diff --git a/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/JavaSerializerWrapper.kt b/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/JavaSerializerWrapper.kt new file mode 100644 index 0000000000..1cb6685d28 --- /dev/null +++ b/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/JavaSerializerWrapper.kt @@ -0,0 +1,42 @@ +package org.utbot.instrumentation.util + +import com.esotericsoftware.kryo.kryo5.Kryo +import com.esotericsoftware.kryo.kryo5.KryoException +import com.esotericsoftware.kryo.kryo5.io.Input +import com.esotericsoftware.kryo.kryo5.serializers.JavaSerializer +import java.io.InputStream +import java.io.ObjectInputStream +import java.io.ObjectStreamClass + +/** + * This ad-hoc solution for ClassNotFoundException + */ +class JavaSerializerWrapper : JavaSerializer() { + override fun read(kryo: Kryo, input: Input?, type: Class<*>?): Any? { + return try { + val graphContext = kryo.graphContext + var objectStream = graphContext.get(this) as ObjectInputStream? + if (objectStream == null) { + objectStream = WrappingObjectInputStream(input, kryo) + graphContext.put(this, objectStream) + } + objectStream.readObject() + } catch (ex: java.lang.Exception) { + throw KryoException("Error during Java deserialization.", ex) + } + } +} + +class WrappingObjectInputStream(iss : InputStream?, private val kryo: Kryo) : ObjectInputStream(iss) { + override fun resolveClass(type: ObjectStreamClass): Class<*>? { + return try { + Class.forName(type.name, false, kryo.classLoader) + } catch (ex: ClassNotFoundException) { + try { + return Kryo::class.java.classLoader.loadClass(type.name) + } catch (e: ClassNotFoundException) { + throw KryoException("Class not found: " + type.name, ex) + } + } + } +} \ No newline at end of file diff --git a/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/KryoHelper.kt b/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/KryoHelper.kt index fa98eacfd6..b632f15a21 100644 --- a/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/KryoHelper.kt +++ b/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/KryoHelper.kt @@ -8,12 +8,9 @@ import com.esotericsoftware.kryo.kryo5.io.Output import com.esotericsoftware.kryo.kryo5.objenesis.instantiator.ObjectInstantiator import com.esotericsoftware.kryo.kryo5.objenesis.strategy.InstantiatorStrategy import com.esotericsoftware.kryo.kryo5.objenesis.strategy.StdInstantiatorStrategy -import com.esotericsoftware.kryo.kryo5.serializers.JavaSerializer import com.esotericsoftware.kryo.kryo5.util.DefaultInstantiatorStrategy import com.jetbrains.rd.util.lifetime.Lifetime import com.jetbrains.rd.util.lifetime.throwIfNotAlive -import org.utbot.api.exception.UtMockAssumptionViolatedException -import org.utbot.framework.plugin.api.TimeoutException import java.io.ByteArrayOutputStream /** @@ -123,11 +120,9 @@ internal class TunedKryo : Kryo() { } this.setOptimizedGenerics(false) - register(TimeoutException::class.java, TimeoutExceptionSerializer()) - register(UtMockAssumptionViolatedException::class.java, UtMockAssumptionViolatedExceptionSerializer()) // TODO: JIRA:1492 - addDefaultSerializer(java.lang.Throwable::class.java, JavaSerializer()) + addDefaultSerializer(java.lang.Throwable::class.java, JavaSerializerWrapper()) val factory = object : SerializerFactory.FieldSerializerFactory() {} factory.config.ignoreSyntheticFields = true @@ -135,35 +130,4 @@ internal class TunedKryo : Kryo() { factory.config.fieldsCanBeNull = true this.setDefaultSerializer(factory) } - - /** - * Specific serializer for [TimeoutException] - [JavaSerializer] is not applicable - * because [TimeoutException] is not in class loader. - * - * This serializer is very simple - it just writes [TimeoutException.message] - * because we do not need other components. - */ - private class TimeoutExceptionSerializer : Serializer() { - override fun write(kryo: Kryo, output: Output, value: TimeoutException) { - output.writeString(value.message) - } - - override fun read(kryo: Kryo?, input: Input, type: Class?): TimeoutException = - TimeoutException(input.readString()) - } - - /** - * Specific serializer for [UtMockAssumptionViolatedException] - [JavaSerializer] is not applicable - * because [UtMockAssumptionViolatedException] is not in class loader. - */ - private class UtMockAssumptionViolatedExceptionSerializer : Serializer() { - override fun write(kryo: Kryo, output: Output, value: UtMockAssumptionViolatedException) { - output.writeString(value.message) - } - - override fun read(kryo: Kryo?, input: Input, type: Class?): UtMockAssumptionViolatedException { - input.readString() // shift the reading position - return UtMockAssumptionViolatedException() - } - } } \ No newline at end of file From e093a2045a7edf64967543936d7236792b417ff9 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Mon, 16 Jan 2023 17:50:22 +0300 Subject: [PATCH 2/2] ClassNotFoundException from KryoHelper.readObject when running ContestEstimator for seata-core-0.5.0 #1649 Add fallback to super (namely to ObjectInputStream) --- .../org/utbot/instrumentation/util/JavaSerializerWrapper.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/JavaSerializerWrapper.kt b/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/JavaSerializerWrapper.kt index 1cb6685d28..bf7e1fd310 100644 --- a/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/JavaSerializerWrapper.kt +++ b/utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/util/JavaSerializerWrapper.kt @@ -35,7 +35,11 @@ class WrappingObjectInputStream(iss : InputStream?, private val kryo: Kryo) : Ob try { return Kryo::class.java.classLoader.loadClass(type.name) } catch (e: ClassNotFoundException) { - throw KryoException("Class not found: " + type.name, ex) + try { + return super.resolveClass(type); + } catch (e: ClassNotFoundException) { + throw KryoException("Class not found: " + type.name, e) + } } } }