0

I'm writing an application using Vaadin 8 and Spring Boot / Spring Data that needs to implement a simple login system. I have a table in PostgreSQL hosting user details, and to log-in I wanted to move the password check to the DB side by using a stored procedure.

Thing is, I have the following class that handles the authentication:

public class Authentication {

@Autowired
private JdbcTemplate jdbcTemplate;

public Boolean authenticate(String username, String password) {
    String passwordCheck =  "SELECT crypt(?, password) = password " +
            "FROM usuaris " +
            "WHERE usuari = ?;";

    PreparedStatementCallback<Boolean> psCallback = (ps) -> {
        ps.setString(1, password);
        ps.setString(2, username);

        return ps.execute();
    };

    return jdbcTemplate.execute(passwordCheck, psCallback);
   }
}

That gets used in a Login Dialog like so:

public class LoginDialog extends Window {
    @Autowired
    Authentication auth;

   private void tryToLogIn() {
        if (auth.authenticate(username.getValue(), password.getValue())) {
            Notification.show("Login successful!", Notification.Type.HUMANIZED_MESSAGE);
        } else {
            Notification.show("Invalid credentials", Notification.Type.ERROR_MESSAGE);
        }
    }
}

When I try to debug the application, it keeps throwing a NPE in the authenticate() method with the Autowired Authentication class.

I have tried annotating the Authentication class as a @Component, @Autowiring a setter instead of the JdbcTemplate, and everything keeps failing.

Does anybody know what could I be missing here?

Thank you!

EDIT1: I have checked the question this one could be a duplicate of, and I made sure I'm not creating the Authentication class as New. I've also tried using the @Configurable annotation and it still does throw the NPE.

I should be able to Autowire the class, so why is it still not working? I forgot to mention I tried to just autowire a standalone JdbcTemplate in the LoginDialog class, and it still threw a NPE.

  • Where are you calling `tryToLogIn()`? Is it in the constructor of `LoginDialog ` perhaps? – Morfic Apr 13 '17 at 08:32
  • `tryToLogIn()` is being called as the OnClick method of a button in `LogInDialog`. I think I have found the problem tho: it doesn't seem to be in any of those classes, but on the main VaadinUI class where I am in fact instantiating a new LoginDialog, so that has to be why every attempt at autowiring something fails. – Enrique Villarreal Apr 13 '17 at 09:03
  • If you instantiate the object yourself, no attempt at autowiring is done. Spring has no knowledge of the object. Because you probably want a new window instance each time the button is clicked, you can autowire the `ApplicationContext` in your UI and [request a window instance from it](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/BeanFactory.html#getBean-java.lang.Class-). – Morfic Apr 13 '17 at 09:21
  • That did the trick! I added the @Component annotation to both `LoginDialog` and `Authentication` and used `GetBean` instead of instantiating the object manually. Thank you! – Enrique Villarreal Apr 13 '17 at 09:52
  • Cheers, glad I could help – Morfic Apr 13 '17 at 10:26
  • Another problem has arisen tho. Vaadin windows have a close button that should destroy them, but since it's now a Spring-managed component, I can't destroy it as such. Any ideas? – Enrique Villarreal Apr 13 '17 at 18:54
  • By default spring beans are singletons, make your window prototype. Sorry, can't provide any links as i'm on mobile, but this info should suffice. – Morfic Apr 13 '17 at 19:24
  • That did help at opening more than one LoginWIndow (although it doesn't make much sense to me given that I would either log in and remember the session, or close it if I didn't want to log-in). The thing is, I have no way of destroying them, as the close button on the SubWindow doesn't kill the prototype bean. I'm searching for ways to do it, but I haven't found anything yet. – Enrique Villarreal Apr 14 '17 at 09:08
  • You don't have to do anything, it will be collected when the garbage collector runs if no one else is referencing it, just like any other java object. – Morfic Apr 14 '17 at 09:20
  • Gotcha. Unfortunately that doesn't quite work for me since I need to be able to close the window. I'll have to find a way to use the Window as a traditional object while still being able to Autoinject the other classes – Enrique Villarreal Apr 14 '17 at 09:46
  • What do you mean? Just close it, don't hold a reference in the UI or any other place (always request a new instance from spring) and that's it... I didn't say you can't close it, did I? – Morfic Apr 14 '17 at 10:04
  • Even if i do: openDialogButton.addClickListener(event -> { addWindow(applicationContext.getBean(LoginDialog.class)); }); (which would be acceptable but I still need to set properties on the window itself), the window doesn't close, so that made me think of it having to do with being a Spring Bean instead of a traditional object. Not sure if I'm doing anything wrong, but I'll probably ask another question. – Enrique Villarreal Apr 14 '17 at 10:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/141710/discussion-between-morfic-and-enrique-villarreal). – Morfic Apr 14 '17 at 10:18

0 Answers0