0
votes

homeControler

    package com.book.controller;

import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.book.entity.User;
import com.book.entity.security.UserToken;
import com.book.entity.security.service.SecurityService;
import com.book.entity.security.service.UserTokenService;

@Controller
public class HomeController {
    @Autowired
    private UserTokenService userTokenService;
    @Autowired
    private SecurityService securityService;

    @RequestMapping("/")
    public String getHome() {
        return "index";
    }

    @RequestMapping("/myaccount")
    public String myAccount() {
        return "myAccount";
    }

    @RequestMapping("/login")
    public String login(Model model) {
        model.addAttribute("classActiveLogin", true);
        return "myAccount";
    }

    @RequestMapping("/forgetPassword")
    public String forgetPassword(Model model) {
        model.addAttribute("classActiveForgetPassword", true);
        return "myAccount";
    }

    @RequestMapping("/newUser")
    public String newUser(Locale locale, @RequestParam("token") String token, Model model) {

        UserToken userToken = userTokenService.getPasswordResetToken(token);
        if (userToken == null) {
            String msg = "Invalid Token";
            model.addAttribute("msg", msg);
            return "redirect:/badRequest";
        }

        User user = userToken.getUser();
        String username = user.getUsername();

        UserDetails userDetails = securityService.loadUserByUsername(username);

        Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(),
                userDetails.getAuthorities());

        SecurityContextHolder.getContext().setAuthentication(authentication);

        model.addAttribute("classActiveEdit", true);
        return "myProfile";
    }
}

User Token

package com.book.entity.security;

import java.util.Calendar;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

import com.book.entity.User;

@Entity
public class UserToken {

    private static final int EXPIRATION = 60 * 24;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String token;

    @OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
    @JoinColumn(nullable=false, name="user_id")
    private User user;

    private Date expiryDate;

    public UserToken(final String token, final User user) {
        super ();

        this.token = token;
        this.user = user;
        this.expiryDate = calculateExpiryDate(EXPIRATION);
    }

    private Date calculateExpiryDate (final int expiryTimeInMinutes) {
        final Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(new Date().getTime());
        cal.add(Calendar.MINUTE, expiryTimeInMinutes);
        return new Date(cal.getTime().getTime());
    }

    public void updateToken(final String token) {
        this.token = token;
        this.expiryDate = calculateExpiryDate(EXPIRATION);
    }

    @Override
    public String toString() {
        return "P_Token [id=" + id + ", token=" + token + ", user=" + user + ", expiryDate=" + expiryDate + "]";
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Date getExpiryDate() {
        return expiryDate;
    }

    public void setExpiryDate(Date expiryDate) {
        this.expiryDate = expiryDate;
    }

    public static int getExpiration() {
        return EXPIRATION;
    }



}

UserTokenService

package com.book.entity.security.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.book.entity.User;
import com.book.entity.security.UserToken;
import com.book.entity.security.repo.PasswordResetRepo;
import com.book.entity.security.repo.UserTokenRepo;

@Service("userTokenService")
public class UserTokenService implements UserTokenRepo{

    @Autowired
    private PasswordResetRepo repo;

    @Override
    public UserToken getPasswordResetToken(final String token) {
        return repo.findByToken(token);
    }

    @Override
    public void createPasswordResetTokenForUser(final User user, final String token) {
        final UserToken myToken = new UserToken(token, user);
        repo.save(myToken);
    }
}

UserTokenRepo

package com.book.entity.security.repo;

import com.book.entity.User;
import com.book.entity.security.UserToken;

public interface UserTokenRepo {

    UserToken getPasswordResetToken(final String token);

    void createPasswordResetTokenForUser(final User user, final String token);

}

SecurityService

package com.book.entity.security.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.book.entity.User;
import com.book.entity.security.repo.SecurityUserRepository;

@Service
public class SecurityService implements UserDetailsService {
    @Autowired
    private SecurityUserRepository securityUserRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = securityUserRepository.findByUsername(username);

        if (null == user) {
            throw new UsernameNotFoundException("Username not found");
        }

        return user;
    }
}

PasswordResetRepo

package com.book.entity.security.repo;

import java.util.Date;
import java.util.stream.Stream;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import com.book.entity.User;
import com.book.entity.security.UserToken;


public interface PasswordResetRepo extends JpaRepository<UserToken, Long > {

    UserToken findByToken(String token);

    UserToken findByUser(User user);

    Stream<UserToken> findAllByExpiryDateLessThan(Date now);

    @Modifying
    @Query("delete from P_Token t where t.expirydate <= ?1")
    void deleteAllExpiredSince(Date now);
}

Error:--> org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'homeController': Unsatisfied dependency expressed through field 'userTokenService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userTokenService': Unsatisfied dependency expressed through field 'repo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'passwordResetRepo': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: antlr/RecognitionException

2
Can you provide the code for PasswordResetRepo? Is it marked as component?Cristian Colorado
its an interfaceJahadul Rakib

2 Answers

2
votes

May be problem lays on HomeController bellow code:

@Autowired
    private UserTokenService userTokenService;

Replace this code with bellow code:

@Autowired
        private UserTokenRepo userTokenService;

Your main error portion is:

Unsatisfied dependency expressed through field 'repo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'passwordResetRepo': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: antlr/RecognitionException

Here it is failed to create bean passwordResetRepo cause antlr/RecognitionException

Its solution is java.lang.ClassNotFoundException: antlr.RecognitionException shows antlr lib missing.

Add it and itss done :)

You can try to add the following dependency. It will solve your issue.

<dependency>
 <groupId>org.antlr</groupId>
 <artifactId>antlr-complete</artifactId>
 <version>3.5.2</version>
</dependency>  

Another possible consideration:

Please check all JPA query on PasswordResetRepo repository. Sometimes if query not matched with entity variable name then Spring can't create bean for that repository

Hope this will solve your problem.

Thanks :)

1
votes

Take a look at the stacktrace. The issue is: spring IoC container is failing to create homeController bean; because the container is failing to create userTokenService bean; and that is because the container is failing to create passwordResetRepo bean with java.lang.NoClassDefFoundError.

Adding the following in your config file should solve your problem:

<jpa:repositories base-package="com.book.entity.security.repo" />

As you are using Spring Boot, please check this guide on Accessing Data with JPA.

From the above mentioned guide:

By default, Spring Boot will enable JPA repository support and look in the package (and its subpackages) where @SpringBootApplication is located. If your configuration has JPA repository interface definitions located in a package not visible, you can point out alternate packages using @EnableJpaRepositories and its type-safe basePackageClasses=MyRepository.class parameter.