2

I've been trying to solve this error for hours and just cannot figure it out. I'm integrating JavaFX, Spring, and several other dependencies in this application, and it's being built using Maven. It seems like the issue is maybe something with my Spring compatibility with my jdk version or my javafx version? Or maybe its my code or my module-info file. I have no clue, but I need some help diagnosing what this issue is. I'm pretty much a beginner at Java, so I may be way off as to what's causing this. Here's my full error:

java.lang.IllegalStateException: Unable to load cache item
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:75) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:130) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:317) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:562) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:407) \~\[spring-core-6.0.11.jar:6.0.11\]
at spring.context@6.0.11/org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:138) \~\[spring-context-6.0.11.jar:na\]
at spring.context@6.0.11/org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:109) \~\[spring-context-6.0.11.jar:na\]
at spring.context@6.0.11/org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:531) \~\[spring-context-6.0.11.jar:na\]
at spring.context@6.0.11/org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:308) \~\[spring-context-6.0.11.jar:na\]
at spring.context@6.0.11/org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:358) \~\[spring-context-6.0.11.jar:na\]
at spring.context@6.0.11/org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:150) \~\[spring-context-6.0.11.jar:na\]
at spring.context@6.0.11/org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:771) \~\[spring-context-6.0.11.jar:na\]
at spring.context@6.0.11/org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:589) \~\[spring-context-6.0.11.jar:na\]
at spring.boot@3.1.2/org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) \~\[spring-boot-3.1.2.jar:na\]
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) \~\[spring-boot-3.1.2.jar:na\]
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) \~\[spring-boot-3.1.2.jar:na\]
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.run(SpringApplication.java:312) \~\[spring-boot-3.1.2.jar:na\]
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) \~\[spring-boot-3.1.2.jar:na\]
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) \~\[spring-boot-3.1.2.jar:na\]
at com.haven.hipmobileapp/com.haven.hipmobileapp.EmailSubmitScreen.start(EmailSubmitScreen.java:21) \~\[classes/:na\]
at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839) \~\[javafx-graphics-20.0.1-mac-aarch64.jar:na\]
at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483) \~\[javafx-graphics-20.0.1-mac-aarch64.jar:na\]
at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456) \~\[javafx-graphics-20.0.1-mac-aarch64.jar:na\]
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) \~\[na:na\]
at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455) \~\[javafx-graphics-20.0.1-mac-aarch64.jar:na\]
at javafx.graphics@20.0.1/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) \~\[javafx-graphics-20.0.1-mac-aarch64.jar:na\]
Caused by: java.lang.IllegalAccessError: class com.haven.hipmobileapp.EmailSubmitScreen$$SpringCGLIB$$0 (in module com.haven.hipmobileapp) cannot access class org.springframework.cglib.core.ReflectUtils (in unnamed module @0x63bae4c7) because module com.haven.hipmobileapp does not read unnamed module @0x63bae4c7
at com.haven.hipmobileapp/com.haven.hipmobileapp.EmailSubmitScreen$$SpringCGLIB$$0.CGLIB$STATICHOOK1(\<generated\>) \~\[classes/:na\]
at com.haven.hipmobileapp/com.haven.hipmobileapp.EmailSubmitScreen$$SpringCGLIB$$0.\<clinit\>(\<generated\>) \~\[classes/:na\]
at java.base/java.lang.Class.forName0(Native Method) \~\[na:na\]
at java.base/java.lang.Class.forName(Class.java:496) \~\[na:na\]
at java.base/java.lang.Class.forName(Class.java:475) \~\[na:na\]
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:551) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:371) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:575) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator.java:107) \~\[spring-core-6.0.11.jar:6.0.11\]
at org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(LoadingCache.java:52) \~\[spring-core-6.0.11.jar:6.0.11\]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) \~\[na:na\]
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:57) \~\[spring-core-6.0.11.jar:6.0.11\]
... 26 common frames omitted

Exception in Application start method
Exception in Application stop method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1081)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:893)
at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:1623)
Caused by: java.lang.IllegalStateException: Unable to load cache item
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:75)
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:130)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:317)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:562)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:407)
at spring.context@6.0.11/org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:138)
at spring.context@6.0.11/org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:109)
at spring.context@6.0.11/org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:531)
at spring.context@6.0.11/org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:308)
at spring.context@6.0.11/org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:358)
at spring.context@6.0.11/org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:150)
at spring.context@6.0.11/org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:771)
at spring.context@6.0.11/org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:589)
at spring.boot@3.1.2/org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734)
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436)
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at spring.boot@3.1.2/org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
at com.haven.hipmobileapp/com.haven.hipmobileapp.EmailSubmitScreen.start(EmailSubmitScreen.java:21)
at javafx.graphics@20.0.1/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at javafx.graphics@20.0.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at javafx.graphics@20.0.1/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.lang.IllegalAccessError: class com.haven.hipmobileapp.EmailSubmitScreen$$SpringCGLIB$$0 (in module com.haven.hipmobileapp) cannot access class org.springframework.cglib.core.ReflectUtils (in unnamed module @0x63bae4c7) because module com.haven.hipmobileapp does not read unnamed module @0x63bae4c7
at com.haven.hipmobileapp/com.haven.hipmobileapp.EmailSubmitScreen$$SpringCGLIB$$0.CGLIB$STATICHOOK1(\<generated\>)
at com.haven.hipmobileapp/com.haven.hipmobileapp.EmailSubmitScreen$$SpringCGLIB$$0.\<clinit\>(\<generated\>)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:496)
at java.base/java.lang.Class.forName(Class.java:475)
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:551)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:371)
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:575)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator.java:107)
at org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(LoadingCache.java:52)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:57)
... 26 more
Exception running application com.haven.hipmobileapp.EmailSubmitScreen

Process finished with exit code 1

Here's my code for my main class:

package com.haven.hipmobileapp;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import net.rgielen.fxweaver.core.FxWeaver;

@SpringBootApplication
public class EmailSubmitScreen extends Application {

    private ConfigurableApplicationContext applicationContext;

    @Override
    public void start(Stage primaryStage) throws Exception {

        applicationContext = SpringApplication.run(EmailSubmitScreen.class);
        // Get the FxWeaver instance from the Spring context
        FxWeaver fxWeaver = applicationContext.getBean(FxWeaver.class);

        // Load FXML file with FxWeaver
        Parent root = fxWeaver.loadView(EmailInputController.class);

        // Create the scene and set it on the stage
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    @Override
    public void stop() throws Exception{
        // Close the Spring context
        applicationContext.close();
    }

    public static void main(String[] args) {
        // Launch the JavaFX application
        launch(args);
    }
}
`

Here's my controller class:

package com.haven.hipmobileapp;

import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import net.rgielen.fxweaver.core.FxmlView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
@FxmlView("/com/haven/hipmobileapp/EmailMenu.fxml")
public class EmailInputController {

    @Autowired
    private UserService userService;

    @FXML
    private TextField emailTextField;

    @FXML
    private Button submitButton;

    public EmailInputController(){

    }


    // Constructor to inject the UserService

    // This method will be called when the submit button is tapped or clicked
    @FXML
    private void handleSubmitButtonAction(Event event) {
        String email = emailTextField.getText();

        // Generate temporary password
        String tempPassword = PasswordGenerator.generateTemporaryPassword(15);
        String encodedPassword = PasswordGenerator.encodePassword(tempPassword);

        // Use the UserService to register the user
        User registeredUser = userService.registerUser(email, encodedPassword);
        // Clear the email text field
        emailTextField.clear();

        // Display a message to the user
        if (registeredUser != null) {
            System.out.println("User registered with email: " + email);
        } else {
            System.out.println("User registration failed.");
        }
    }
}

Here's the service being called:

package com.haven.hipmobileapp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    public User registerUser(String email, String encodedPassword) {
        // Encode the user's password using BCryptPasswordEncoder
        if (userRepository.existsByEmail(email)){
            return null;
    }

        // Create a new user object and save it to the database
        User newUser = new User(email, encodedPassword);
       return userRepository.save(newUser);
    }
}

I've tried to add ALL-UNNAMED for the module in my JVM arguments but that hasn't worked. Happy to provide any other info needed.

James_D
  • 201,275
  • 16
  • 291
  • 322
mjsick1
  • 31
  • 1

1 Answers1

1

Making your application non-modular

Spring <=6 does not work well or easily with java platform modules in my experience.

Instead, make your application non-modular. To do this, remove the module-info.java file from your application.

Then you need JavaFX on your module path. The easiest way to do that IMO is to use a JDK that includes JavaFX, either:

  • Azul Zulu "JDK FX"

OR

  • Bellsoft Liberica "Full JDK"

Otherwise, follow the getting started instructions at openjfx.io for non-modular JavaFX applications.

My thoughts on Spring 6 with Java Platform Modules

Spring 6 (and Spring Boot 3) can be made to work in a modular application with some effort.

Using Spring components as modules means that many of the components and their transitive dependencies are deployed as automatic modules. Automatic modules differ from well-defined modules. Automatic modules do not include a module definition in a module-info file.

The use of automatic modules means that you can't take advantage of benefits that you would otherwise receive from the module system. For instance, at least with Java 20, you can't use jlink to package a runtime that includes automatic modules. By creating a modular project that uses Spring modules in automatic module form, you receive many of the difficulties of creating such a modular application while realizing only a few of the benefits. It is a bitter pill with little upside.

IMO, it is just not worth the effort to use Spring 6 or SpringBoot 3 in a modular JavaFX 20 application. Instead, SpringBoot 3 in a non-modular JavaFX 20 application is recommended.

Perhaps a future upgrade of Spring will make it more module friendly and thus change the recommendation, perhaps not.

jewelsea
  • 150,031
  • 14
  • 366
  • 406