quarkus: A @QuarkusTest with a ParameterResolver that return a java record, throws an exception

Describe the bug

During a QuarkuTest, when using a junit “ParameterResolver” that return a java record with at least one field, xstream return this error:

com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : java.lang.UnsupportedOperationException
cause-message       : can't get field offset on a record class: private final java.lang.String com.example.TestRecord.test
class               : com.example.TestRecord
required-type       : com.example.TestRecord
converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path                : /com.example.TestRecord/test
line number         : 2
version             : 1.4.15
-------------------------------

The problem in quarkus is at io.quarkus.test.junit.internal.XStreamDeepClone.doClone(XStreamDeepClone.java:49)

As far as I understand, this class use xstream to just create a copy of the object (the java record) in the Quarkus ClassLoader. If it’s the only usage, i think we can use another library that support records (and maybe use json instead of XML).

what do you think?

The cause is:

java.lang.UnsupportedOperationException: can't get field offset on a record class: private final java.lang.String com.example.TestRecord.test
	at jdk.unsupported/sun.misc.Unsafe.objectFieldOffset(Unsafe.java:648)
	at com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider.getFieldOffset(SunUnsafeReflectionProvider.java:105)

To Reproduce

It’s very simple.

1- Create a Java record, with at least one field record TestRecord(String test)

2- Create a ParameterResolver that return the record new TestRecord("my test")

3- Create a quarkus test that use that ParameterResolver eg:

@QuarkusTest
@ExtendWith(TestRecordResolver.class)
public class QuarkusRecordTest {
  @Test
  public void test(TestRecord record) {
    assert record != null;
  }

}

Environment:

Output of uname -a or ver

Darwin MacBookPro.lan 20.3.0 Darwin Kernel Version 20.3.0: Thu Jan 21 00:06:51 PST 2021; root:xnu-7195.81.3~1/RELEASE_ARM64_T8101 arm64

Output of java -version

openjdk 16 2021-03-16 OpenJDK Runtime Environment AdoptOpenJDK (build 16+36) OpenJDK 64-Bit Server VM AdoptOpenJDK (build 16+36, mixed mode, sharing)

Quarkus version or git rev

Quarkus 1.12.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Maven 3.6.3

Additional context

I reproduced it in a new empty project. I can post it, if need, but it’s super simple.

This occurs from java 15, for this reason https://mail.openjdk.java.net/pipermail/amber-dev/2020-June/006241.html https://medium.com/@atdsqdjyfkyziqkezu/java-15-breaks-deserialization-of-records-902fcc81253d

Complete stacktrace.txt

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 2
  • Comments: 18 (16 by maintainers)

Most upvoted comments

We should look at adding some hooks into JUnit so we no longer require this copying.

Yeah, we can do certainly try that - there might be a problem though… Having Johnzon on the test classpath might cause problems in the JSON-B resolution process when Yasson (which we use as our JSON-B impl of choice) is also present…

Yeah, why not! I don’t see why someone would want xstream serialization when the class in question declares to be java serialization compatible.

Maybe it could be engaged if the class is serializable?