Playframework: [RuntimeException: java.lang.reflect.InvocationTargetException]

10,296

I have to assume a lot but if this is what your stacktrace looked like:

play.api.Application$$anon$1: Execution exception[[RuntimeException: java.lang.reflect.InvocationTargetException]]
                at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10.jar:2.2.3]
                at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10.jar:2.2.3]
                at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10.jar:2.2.3]
                at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3$$anonfun$applyOrElse$3.apply(PlayDefaultUpstreamHandler.scala:264) [play_2.10.jar:2.2.3]
                at scala.Option.map(Option.scala:145) [scala-library.jar:na]
                at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$3.applyOrElse(PlayDefaultUpstreamHandler.scala:264) [play_2.10.jar:2.2.3]
        ...
        Caused by: java.lang.NullPointerException: null
                at models.User.authenticate(User.java:26) ~[na:na]
                at controllers.Application$Login.validate(Application.java:50) ~[na:na]
                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05]
                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_05]
                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_05]
                at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_05]

then the cause of the problem is actually hinted at by the NPE in your User class. If you enter bogus credentials, your finder will not find anything and return null in AccountDetails.authenticate().

So in the method below you do not check for null and try and get the userId, which causes the NPE:

public static User authenticate(String email, String password) {
  String tempId = AccountDetails.authenticate(email, password).userId;

  return find.ref(tempId);
}

If you just check for null properly you will get the desired functionality:

public static User authenticate(String email, String password) {
    User user = null;

    AccountDetails accountDetails = AccountDetails.authenticate(email, password);
    if (accountDetails != null) {
        user = find.ref(accountDetails.userId);
    }

    return user;
}
Share:
10,296
ac-lap
Author by

ac-lap

Updated on June 12, 2022

Comments

  • ac-lap
    ac-lap almost 2 years

    I'm trying to create a simple login based on the Zentask sample --zentask - playframework, however when I click the login button which calls the Application.authenticate actions, it gives runtime exception. I have marked the line with -- error

    [RuntimeException: java.lang.reflect.InvocationTargetException]
    

    Application.java

    public class Application extends Controller {
    
    .........
    
    public static class Login 
    {
        public String email;
        public String password;
    
        public String validate() 
        {
            if (User.authenticate(email, password) == null) {
              return "Invalid user or password";
            }
            return null;
        }
    }
    
       public static Result authenticate() 
        {
            Form<Login> loginForm = form(Login.class).bindFromRequest();  //--- error
            if(loginForm.hasErrors()) {
                return badRequest(login.render(loginForm));
            } else {
                session("email", loginForm.get().email);
                return redirect(
                    routes.Application.index()
                );
            }
        }
    }
    

    I understand it has something to do with the validate function in Login Class, because when I remove the call to User.authenticate in the validate function it works without error. But I am unable to figure it out.

    The user class is as -

    @Entity
    public class User extends Model
    {
        @Id
        @Constraints.Required
        @Formats.NonEmpty
        public String userId;
    
        @OneToOne(cascade=CascadeType.PERSIST)
        AccountDetails accDetails;
    
    
        public static Model.Finder<String,User> find = new Model.Finder<String,User>(String.class, User.class);
    
    
    
        // Authenticate the user details
        public static User authenticate(String email, String password) 
        {
            String tempId = AccountDetails.authenticate(email, password).userId;
    
            return find.ref(tempId);
        }
    
        .. . . . . . .
    
    }
    

    and the AccountDetails Class -

    @Entity
    public class AccountDetails extends Model
    {
        @Id
        String userId;
    
        @Constraints.Required
        String emailId;
    
        @Constraints.Required
        String password;
    
        public static Model.Finder<String,AccountDetails> find = 
                new Model.Finder<String,AccountDetails>(String.class, AccountDetails.class);
    
    
        public static AccountDetails authenticate(String email, String password) 
        {       
            return find.where()
                .eq("email", email)
                .eq("password", password)
                .findUnique();
        }
    
    }
    
    • Admin
      Admin over 10 years
      No import declarations, no exception stack trace, fragmental code. It is quite hardcore to answer such question except you already dealt with such problem.