Search code examples
javaspringspring-bootspring-mvcspring-security

Implementing variable from application.properties returns null


I need to use the value from two variables that are in main/resources/application.properties, both are "custom.data.jwt.secret" and "custom.data.jwt.expiration", the first contains characters and the second numbers.

I attempted all 3 of this answer and did not find other different answers, all return null:

ConfigProperties.java

package com.XX.ZZ.security;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@ConfigurationProperties(prefix = "custom.data.jwt")
@Configuration("JwtData")
public class ConfigProperties {
    private String jwt_secret;
    private long jwt_expiration;

    public String getJwt_secret() {
        return jwt_secret;
    }

    public void setJwt_secret(String jwt_secret) {
        this.jwt_secret = jwt_secret;
    }

    public long getJwt_expiration() {
        return jwt_expiration;
    }

    public void setJwt_expiration(long jwt_expiration) {
        this.jwt_expiration = jwt_expiration;
    }
}

TokenUtils.java

package com.XX.ZZ.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import java.util.*;

public class TokenUtils {

    @Autowired
    private static ConfigProperties configProp;

    private static final String jwt_secret = configProp.getJwt_secret();
    private static final long jwt_expiration = configProp.getJwt_expiration();

    public static String createToken(String name, String email){
        long expirationTime = jwt_expiration * 1000;
        Date expirationDate = new Date(System.currentTimeMillis() + expirationTime);

        Map<String, Object> extra = new HashMap<>();
        extra.put("name", name);

        return Jwts.builder()
                .setSubject(email)
                .setExpiration(expirationDate)
                .addClaims(extra)
                .signWith(Keys.hmacShaKeyFor(jwt_secret.getBytes()))
                .compact();
    }

    public static UsernamePasswordAuthenticationToken getAuthentication(String token){
        try {
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(jwt_secret.getBytes())
                    .build()
                    .parseClaimsJws(token)
                    .getBody();

            String email = claims.getSubject();

            return new UsernamePasswordAuthenticationToken(email,null, Collections.emptyList());
        } catch (JwtException e){
            return null;
        }
    }
}

Error: java.lang.NullPointerException: Cannot invoke "com.XX.ZZ.security.ConfigProperties.getJwt_secret()" because "com.XX.ZZ.security.TokenUtils.configProp" is null


ConfigProperties.java

package com.XX.ZZ.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.core.env.Environment;

@Component
@PropertySource("classpath:application.properties")
public class ConfigProperties {

    @Autowired
    private Environment env;

    public String getConfigValue(String configKey){
        return env.getProperty(configKey);
    }
}

TokenUtils.java

package com.XX.ZZ.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import java.util.*;

public class TokenUtils {

    @Autowired
    private static ConfigProperties configProp;

    private static final Long jwt_expiration = Long.valueOf(configProp.getConfigValue("custom.data.jwt.expiration"));
    private static final String jwt_secret = configProp.getConfigValue("custom.data.jwt.secret");

    // same code as the first attempt
}

Error: java.lang.NullPointerException: Cannot invoke "com.XX.ZZ.security.ConfigProperties.getConfigValue(String)" because "com.XX.ZZ.security.TokenUtils.configProp" is null


TokenUtils.java

package com.XX.ZZ.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import java.util.*;

public class TokenUtils {

    @Value("${custom.data.jwt.secret}")
    private static String jwt_secret;
    @Value("${custom.data.jwt.expiration}")
    private static long jwt_expiration;

    // same code as the first attempt
}

Error: java.lang.NullPointerException: Cannot invoke "String.getBytes()" because "com.XX.ZZ.security.TokenUtils.jwt_secret" is null


Solution

  • Pass the variables as method params since this class is a static class. I hope you are passing these values from an non-static class. In that class, get the values from application properties as follow.

    @Component
    public class CallerClass{
    
        @Value("${custom.data.jwt.secret}")
        private String jwt_secret;
        @Value("${custom.data.jwt.expiration}")
        private long jwt_expiration;
    
      public void validateToken(){
         TokenUtils.isValid(jwt_secret, jwt_expiration);  
      }
    
    }
    
    public static  class TokenUtils{
    
       public static boolean isValid(String jwtSecret, long jwtExp){
        //implementation
    
       }
       
    }