Repositories don't get initialised when application is started [EDITED]

As the title says, the repositories of our application don't get initialised, but we're not instantiating either, as other fixes online have suggested.

This is the game launcher of the app.

    public class JavaFxApplication extends Application {

    private static ConfigurableApplicationContext context;

    public static void main(String[] args) {
        Application.launch(JavaFxApplication.class, args);
    }

    @Override
    public void init() throws Exception {
        ApplicationContextInitializer<GenericApplicationContext> initializer =
            ac -> {
                ac.registerBean(Application.class, () -> JavaFxApplication.this);
                ac.registerBean(Parameters.class, this::getParameters);
                ac.registerBean(HostServices.class, this::getHostServices);
            };
        context = new SpringApplicationBuilder()
                .sources(PacManLauncher.class)
                .initializers(initializer)
                .run(getParameters().getRaw().toArray(new String[0]));
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Pac-Man");
        primaryStage.getIcons().add(new Image("images/pacman/pacman.png"));
        Parent root = new LoginPage(primaryStage);
        Scene scene = new Scene(root, 600, 400);
        scene.getStylesheets().add("stylesheet/stylesheet.css");
        primaryStage.setScene(scene);

        primaryStage.show();
    }

    @Override
    public void stop() throws Exception {
        context.close();
        Platform.exit();
    }
}

This is the login authentication page.

//more code
  @Autowired
    private UserRepository userRepository;

    private static BCryptPasswordEncoder passwordEncoder;

    /**
     * Instantiates a new Authentication service with the User repository.
     *
     * @param userRepository the user repository
     */

    public AuthenticationService(UserRepository userRepository) {

        this.userRepository = userRepository;
    }

   /**
     * Login form.
     *
     * @param username the username
     * @param password the password
     * @return a boolean (true if user is correctly logged in, false if the opposite)
     */
    public boolean login(String username, String password) {

        passwordEncoder = new BCryptPasswordEncoder();
        Optional<User> user = userRepository.findByName(username);
        if (user.isPresent()) {
            if (passwordEncoder.matches(password, 
user.get().getPassword())) {
                UserSession.getInstance(username, user.get().getId());
            }
        }
        return (UserSession.getUserId() != null && UserSession.getUserName() != null);
    }
//more code

The login code works in a seperate project, but in this as a whole, gives us a nullpointer on the autowiring. Does anyone know how we can get a repository to be made without a nullpointer coming up or can you at least guide us to the right direction with some sources.

Thanks in advance.

EDIT: I put up the wrong game launcher on the app, so if anyone can help with this one, it would be appreciated. :)

2 answers

  • answered 2019-12-05 17:21 duffymo

    Try moving the @Autowired annotation from the private data member to the constructor:

    private UserRepository userRepository;
    
    @Autowired
    public AuthenticationService(@Qualifier(value = "userRepository") UserRepository userRepository) {
    
        this.userRepository = userRepository;
    }
    

    Constructor injection is preferred to setter injection.

    You don't include all the code. If the object that expects UserRepository is not under Spring's control it won't be injected.

  • answered 2019-12-05 19:23 Shekhar Rai

    Edit

    As you have updated your question I have updated my answer as well. And I'm still pointing out the similar thing that I have described before!

    • You are missing @SpringBootApplication annotation on your JavaFxApplication class and seems like you have it in your PacManLauncher
    • Your JavaFxApplication main-class (annotated with @SpringBootApplication) must be in the parent package and repositories , components, configuration classes in the children directory so that spring-boot will inject/configure all required components, configurations and repositories.

      Spring-Boot application directory tree structure

    I have updated your code as well,

    @SpringBootApplication
    public class JavaFxApplication extends Application {
    
        private static ConfigurableApplicationContext context;
    
        public static void main(String[] args) {
            Application.launch(args);
        }
    
        @Override
        public void init() throws Exception {
            context = springBootApplicationContext();
        }
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            primaryStage.setTitle("Pac-Man");
            primaryStage.getIcons().add(new Image("images/pacman/pacman.png"));
            Parent root = new LoginPage(primaryStage);
            Scene scene = new Scene(root, 600, 400);
            scene.getStylesheets().add("stylesheet/stylesheet.css");
            primaryStage.setScene(scene);
    
            primaryStage.show();
        }
    
        @Override
        public void stop() throws Exception {
            context.close();
        }
    
         private ConfigurableApplicationContext springBootApplicationContext() {
            SpringApplicationBuilder builder = new SpringApplicationBuilder(JavaFxApplication.class);
            String[] args = getParameters().getRaw().stream().toArray(String[]::new);
            return builder.run(args);
        }
    }
    

    PS: I have removed your code from init() method which may not required as the above code can inject every spring components. I also removed source -> PacManLauncher class as well. Please run JavaFxApplication .. I hoe it should fix your issue:)