Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to instantiate when on modulepath #358

Open
jqno opened this issue Sep 28, 2024 · 7 comments
Open

Unable to instantiate when on modulepath #358

jqno opened this issue Sep 28, 2024 · 7 comments

Comments

@jqno
Copy link

jqno commented Sep 28, 2024

(Note that this is a follow-up to issue #160. I suspect it's also the underlying problem for #332.)

Despite the fix made for #160, I'm still unable to use Objenesis when it's running on the modulepath.

I'm not sure what I'm doing wrong, or how I can work around this.

I get this exception:

Exception in thread "main" org.objenesis.ObjenesisException: java.lang.ClassNotFoundException: sun.reflect.ReflectionFactory
	at [email protected]/org.objenesis.instantiator.sun.SunReflectionFactoryHelper.getReflectionFactoryClass(SunReflectionFactoryHelper.java:57)
	at [email protected]/org.objenesis.instantiator.sun.SunReflectionFactoryHelper.newConstructorForSerialization(SunReflectionFactoryHelper.java:37)
	at [email protected]/org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.<init>(SunReflectionFactoryInstantiator.java:41)
	at [email protected]/org.objenesis.strategy.StdInstantiatorStrategy.newInstantiatorOf(StdInstantiatorStrategy.java:61)
	at [email protected]/org.objenesis.ObjenesisBase.getInstantiatorOf(ObjenesisBase.java:94)
	at [email protected]/org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
	at objenesisreproducer/org.example.domain.Reproducer.main(Reproducer.java:8)
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 [email protected]/org.objenesis.instantiator.sun.SunReflectionFactoryHelper.getReflectionFactoryClass(SunReflectionFactoryHelper.java:54)
	... 6 more

I've uploaded a complete reproducer here: https://github.com/jqno/objenesis-module-issue

Note: it needs to be run from within IntelliJ. I was unable to reproduce it with Maven.


The full code is also below:

Reproducer.java:

package org.example.domain;

import org.objenesis.*;

public class Reproducer {
    public static void main(String[] args) {
        Objenesis objenesis = new ObjenesisStd();
        objenesis.newInstance(Reproducer.class);
    }
}

module-info.java:

module objenesisreproducer {
    opens org.example.domain;
    requires org.objenesis;
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>objenesis-issue-160</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.release>17</maven.compiler.release>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.objenesis</groupId>
            <artifactId>objenesis</artifactId>
            <version>3.4</version>
        </dependency>
    </dependencies>
</project>
@jqno
Copy link
Author

jqno commented Sep 30, 2024

It looks like, if I do the same thing from within a JUnit test, it does work. I tried figuring out the commandline parameters that Maven Surefire uses to run the tests, but when I apply them to this program, it doesn't fix the issue. Does Objenesis detect whether it's running inside a unit test and, based on that, decide to do something else?

@henri-tremblay
Copy link
Contributor

No. And normally it guesses the instantiator that should work. I am highly interested in the 2 command lines to compare.

@jqno
Copy link
Author

jqno commented Oct 1, 2024

I did some more digging in the mean time, and I found out that if I add requires jdk.unsupported; to the module-info.java of my own project, it works. I've created another small repo that to reproduce the root cause, which happens when calling Class.forName("sun.reflect.ReflectionFactory, which you can find here: https://github.com/jqno/modules-are-confusing. I've included both a main method and a unit test, so it's easier to compare the two. I also asked StackOverflow, hoping to attract some eyeballs. You can find that here: https://stackoverflow.com/q/79042872/127863

@henri-tremblay
Copy link
Contributor

Hum... I'll look a bit more but I think it will become a usage requirement like many other projects have in order to work in the module path.

@jqno
Copy link
Author

jqno commented Oct 2, 2024

That would be totally fair.

BTW, an answer was posted to the stackoverflow question. It looks like Surefire (and I guess IntelliJ too) run on the classpath, but load the test module on the modulepath. So not the entire application runs on the modulepath. Because of this, the stuff on the classpath is accessible, and this includes a couple of "special" built-in modules, including jdk.unsupported. So that explains the difference.

@lprimak
Copy link

lprimak commented Nov 17, 2024

Getting the same error when using inside OSGi bundle.

@henri-tremblay
Copy link
Contributor

I did a release yesterday. Can you please try 5.6.0? It is possible that is won't work because I haven't fixed this issue specifically. I'm only fixed the imports, exports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants