easymock / objenesis

Okay, it's pretty easy to instantiate objects in Java through standard reflection. However there are many cases where you need to go beyond what reflection provides. For example, if there's no public constructor, you want to bypass the constructor code, or set final fields. There are numerous clever (but fiddly) approaches to getting around this and this library provides a simple way to get at them. You will find the official site here.
objenesis.org
Apache License 2.0
603 stars 96 forks source link

JPMS: sun libraries aren't available #332

Open xenoterracide opened 3 months ago

xenoterracide commented 3 months ago

sun classes aren't supposed to be available anymore. If you're using a module-info they definitely aren't available. I tested 3.4 as well.

ava.lang.AssertionError: EqualsVerifier found a problem in class com.xenoterracide.jpa.fixtures.FooAggregate.
-> java.lang.ClassNotFoundException: sun.reflect.ReflectionFactory

For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
(EqualsVerifier null, JDK 21.0.2 on Linux)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:351)
    at spring.app.commons.jpa.test/com.xenoterracide.jpa.test.AbstractSplatTest.abstractAggregateEquality(AbstractSplatTest.java:45)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.objenesis.ObjenesisException: java.lang.ClassNotFoundException: sun.reflect.ReflectionFactory
    at org.objenesis@3.3/org.objenesis.instantiator.sun.SunReflectionFactoryHelper.getReflectionFactoryClass(SunReflectionFactoryHelper.java:57)
    at org.objenesis@3.3/org.objenesis.instantiator.sun.SunReflectionFactoryHelper.newConstructorForSerialization(SunReflectionFactoryHelper.java:37)
    at org.objenesis@3.3/org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.<init>(SunReflectionFactoryInstantiator.java:41)
    at org.objenesis@3.3/org.objenesis.strategy.StdInstantiatorStrategy.newInstantiatorOf(StdInstantiatorStrategy.java:68)
    at org.objenesis@3.3/org.objenesis.ObjenesisBase.getInstantiatorOf(ObjenesisBase.java:94)
    at org.objenesis@3.3/org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.internal.reflection.Instantiator.instantiate(Instantiator.java:69)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.internal.reflection.ClassAccessor.buildObjectAccessor(ClassAccessor.java:335)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.internal.reflection.ClassAccessor.getRedAccessor(ClassAccessor.java:225)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.internal.reflection.ClassAccessor.getRedAccessor(ClassAccessor.java:210)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.internal.reflection.ClassAccessor.getRedObject(ClassAccessor.java:186)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.internal.util.Configuration.ensureUnequalExamples(Configuration.java:219)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.internal.util.Configuration.build(Configuration.java:114)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.buildConfig(SingleTypeEqualsVerifierApi.java:424)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.performVerification(SingleTypeEqualsVerifierApi.java:410)
    at nl.jqno.equalsverifier@3.16.1/nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:347)
    ... 4 more
Caused by: java.lang.ClassNotFoundException: sun.reflect.ReflectionFactory
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:421)
    at java.base/java.lang.Class.forName(Class.java:412)
    at org.objenesis@3.3/org.objenesis.instantiator.sun.SunReflectionFactoryHelper.getReflectionFactoryClass(SunReflectionFactoryHelper.java:54)
    ... 19 more
Reusing configuration cache.

> Task :jpa:dependencyInsight
org.objenesis:objenesis:3.3
  Variant runtime:
    | Attribute Name                 | Provided     | Requested    |
    |--------------------------------|--------------|--------------|
    | org.gradle.status              | release      |              |
    | org.gradle.category            | library      | library      |
    | org.gradle.libraryelements     | jar          | jar          |
    | org.gradle.usage               | java-runtime | java-runtime |
    | org.gradle.dependency.bundling |              | external     |
    | org.gradle.jvm.environment     |              | standard-jvm |
    | org.gradle.jvm.version         |              | 21           |
   Selection reasons:
      - By constraint: dependency was locked to version '3.3'
      - By ancestor

org.objenesis:objenesis:{strictly 3.3} -> 3.3
\--- project :jpa
     \--- project :jpa (*)

org.objenesis:objenesis:3.3
\--- nl.jqno.equalsverifier:equalsverifier:3.16.1
     \--- project :jpa (requested nl.jqno.equalsverifier:equalsverifier:3.+)
          \--- project :jpa (*)

(*) - Indicates repeated occurrences of a transitive dependency subtree. Gradle expands transitive dependency subtrees only once per project; repeat occurrences only display the root of the subtree, followed by this annotation.

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 667ms
1 actionable task: 1 executed
Configuration cache entry reused.
jqno commented 1 month ago

You need to add requires jdk.unsupported; to your module-info.java.

See this question on stackoverflow for details.

xenoterracide commented 1 month ago

interesting, I didn't know jdk.unsupported was a thing. Good to know. I think I may also have seen something about actually being able to require sun.something but I still don't think it's a good idea and that this code should be migrated away from...

In the mean time I've been creating gradle JvmTestSuite's my main test always has a module-info to be on the module-path. If need be I create a whitebox test suite that runs on the classpath.