#Springboot error: Is there an unresolvable circular reference?

144 messages · Page 1 of 1 (latest)

hazy geyser
#

Hello guys,
I'm trying to create a SpringBoot projet, but have some issues with.

I get this error:Is there an unresolvable circular reference?
=> with by WebSecurityConfig, i know that it comes from my architecture, I tried to use "@Lazy" but still don't understand how it works exactly, and where i should place them.

sinful garnetBOT
#

This post has been reserved for your question.

Hey @hazy geyser! Please use /close or the Close Post button above when you're finished. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

hazy geyser
#

So:

@Controller
public class UserController {

    private final UserService userService;


    private final UserValidator userValidator;


    public UserController( UserService userService, UserValidator userValidator) {
        this.userService = userService;
        this.userValidator = userValidator;
    }```
#

UserController

#
@Component
public class UserValidator implements Validator {
    private final UserService userService;

    public UserValidator(UserService userService) {
        this.userService = userService;
    }
``` UserValidator
#
@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final RoleRepository roleRepository;

    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    public UserServiceImpl(UserRepository userRepository, RoleRepository roleRepository,
                           BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }```UserServiceImpl
#
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    private final UserRepository userRepository;

    public UserDetailsServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }```UserDetailsServiceImpl
#
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserDetailsService userDetailsService;

    public WebSecurityConfig(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/resources/**", "/registration").permitAll().anyRequest().authenticated()
                .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
    }

    @Bean
    public AuthenticationManager customAuthenticationManager() throws Exception {
        return authenticationManager();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }


}```WebSecurityConfig
#

Springboot error: Is there an unresolvable circular reference?

#

PLEASE PING ME 🙏

ashen tusk
ashen tusk
#

Is there something before or after?

ashen tusk
#
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
#

move that out of the WebSecurityConfig

#

to another @Configuration class

hazy geyser
ashen tusk
#

yes, like that

hazy geyser
#

then

hazy geyser
# ashen tusk yes, like that
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserDetailsService userDetailsService;
    

    private final PasswordEncoderConfig passwordEncoderConfig;

    public WebSecurityConfig(UserDetailsService userDetailsService, PasswordEncoderConfig passwordEncoderConfig) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoderConfig = passwordEncoderConfig;
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/resources/**", "/registration").permitAll().anyRequest().authenticated()
                .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
    }

    @Bean
    public AuthenticationManager customAuthenticationManager() throws Exception {
        return authenticationManager();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoderConfig.bCryptPasswordEncoder());
    }


}```
#

?

ashen tusk
#

You can directly inject the BCryptPasswordEncoder into your WebSecurityConfig

#

but that would work as well

#

like

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserDetailsService userDetailsService;
    

    private final PasswordEncoder passwordEncoder;

    public WebSecurityConfig(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoder = passwordEncoder;
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/resources/**", "/registration").permitAll().anyRequest().authenticated()
                .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
    }

    @Bean
    public AuthenticationManager customAuthenticationManager() throws Exception {
        return authenticationManager();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }


}

should be an alternative option

hazy geyser
#

okey,

#

it looks that it solved the problem

#

but, new problem ahah

ashen tusk
#

Can you show your pom.xml?

#

I think you are using both Java EE and Jakarta EE

hazy geyser
ashen tusk
#

If you are using Spring 6.x or Spring Boot 3.x, you should be using Jakarta EE exclusively

#

If you are using Spring 5.x or Spring Boot 2.x, you should be using Java EE exclusively

#

it seems like you are using Spring 6/Spring Boot 3 together with Java EE

hazy geyser
# ashen tusk If you are using Spring 6.x or Spring Boot 3.x, you should be using Jakarta EE e...

yep,

    // https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    implementation "mysql:mysql-connector-java"
    implementation "org.apache.tomcat.embed:tomcat-embed-jasper"
    implementation "org.springframework.boot:spring-boot-starter-data-jpa"
    implementation "org.springframework.boot:spring-boot-starter-security"
    implementation "org.springframework.boot:spring-boot-starter-thymeleaf:3.0.1"
    implementation "org.springframework.boot:spring-boot-starter-validation:3.0.1"
    implementation "org.springframework.boot:spring-boot-starter-web"
    implementation "org.webjars:bootstrap-datepicker:1.0.1"
    implementation "org.webjars:bootstrap:3.3.6"
    implementation "org.webjars:jquery:1.9.1"
    implementation 'org.springframework.boot:spring-boot-starter-data-rest'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.security:spring-security-config:5.7.3'
    implementation 'org.springframework.security:spring-security-web:5.7.3'
    implementation 'org.springframework.session:spring-session-core'
    implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
    implementation('io.jsonwebtoken:jjwt:0.2')
    runtimeOnly 'com.mysql:mysql-connector-j'
#

but when i remove implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'

#
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
       ^
  class file for javax.servlet.Filter not found```
ashen tusk
#

do not specify a version for any Spring Boot Starter dependencies

ashen tusk
#

reload the project and try again

hazy geyser
#

bruh

#

that was removed from newer versions

ashen tusk
#

yeah, that class might have been removed

#

I remember that

hazy geyser
#

let's do it again with new method

ashen tusk
#

don't extend WebSecurityConfigurerAdapter any more

#

but instead create a bean like this:

    @Bean
    SecurityFilterChain setupHttpSecurity(HttpSecurity http) throws Exception {
hazy geyser
#

smthg like that?

ashen tusk
#

yes

hazy geyser
#

then replaced java @Bean public AuthenticationManager customAuthenticationManager() { return authenticationManager(); }

#

by

#
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
            throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }```
ashen tusk
#

probably

hazy geyser
ashen tusk
#

No

#

use thymeleaf, it will make your life significantly less painful

hazy geyser
ashen tusk
#

you have an HTML file with tags like

<div th:if="${someExpression}">
  ...
</div>
hazy geyser
#

but i wanted to use react instead

ashen tusk
#

so what's the problem?

#

just use React

hazy geyser
#

i need to check how interactions work, with front and backend, and secure everything with tokens

ashen tusk
#

so what's the problem?

hazy geyser
# ashen tusk so what's the problem?

okay, so tried to do a JwtAuth,

    @RequestMapping(value = "/authenticate", method = RequestMethod.POST)
    public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest) throws Exception {
        

        authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());

        final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());

        final String token = jwtTokenUtil.generateToken(userDetails);

        return ResponseEntity.ok(new JwtResponse(token));
    }```
#

but 0 response, like if program didn't listen to

ashen tusk
#

you did get a response

#

maybe it isn't a valid JwtRequest

hazy geyser
ashen tusk
#

or maybe you need certain permissions to access /authenticate

hazy geyser
#
@RestController
@CrossOrigin
public class JwtAuthenticationController {

    private final AuthenticationManager authenticationManager;

    private final JwtTokenUtil jwtTokenUtil;

    private final UserDetailsService userDetailsService;

    private final UserService userService;

    public JwtAuthenticationController(AuthenticationManager authenticationManager, JwtTokenUtil jwtTokenUtil,
                                       UserDetailsService userDetailsService, UserService userService) {
        this.authenticationManager = authenticationManager;
        this.jwtTokenUtil = jwtTokenUtil;
        this.userDetailsService = userDetailsService;
        this.userService = userService;
    }

    @RequestMapping(value = "/authenticate", method = RequestMethod.POST)
    public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest) throws Exception {


        authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());

        final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());

        final String token = jwtTokenUtil.generateToken(userDetails);

        return ResponseEntity.ok(new JwtResponse(token));
    }```
ashen tusk
#

or maybe the authenticate method throws an exception

#

using a debugger might help you

hazy geyser
#

how can i be dumb like that

ashen tusk
#

What was it?

#

antMatcher()/.anonymous() missing?

hazy geyser
# ashen tusk `antMatcher()`/`.anonymous()` missing?
 return http.authorizeRequests().requestMatchers("/resources/**", "/registration", "/authenticate", "/register")
                .permitAll().and().formLogin().loginPage("/login").permitAll().and()
                .logout().permitAll().and().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class).build();```
#

"/authenticate", "/register" missed

#

eheh

ashen tusk
#

yeah

ashen tusk
hazy geyser
#

need to fix that now 😦

#

java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter

#
    implementation 'jakarta.xml.bind:jakarta.xml.bind-api:'
    implementation 'org.glassfish.jaxb:jaxb-runtime'
ashen tusk
#

Can you show the whole stack trace?

hazy geyser
ashen tusk
#

And what version of Spring Boot are you using?

hazy geyser
#

3.0

ashen tusk
#

yeah that uses Jakarta EE

#

javax.xml is from Java EE

hazy geyser
ashen tusk
#

Are you using io.jsonwebtoken:jjwt? In that case, try switching to io.jsonwebtoken:jjwt-api

ashen tusk
#

does it work?

hazy geyser
#

i'm starting

#

nop

ashen tusk
#

the newest version of it is 0.11.5

hazy geyser
#

not the same error

ashen tusk
#

ah ok

#

other error can either be good or bad

hazy geyser
#

"Have you remembered to include the jjwt-impl.jar"

#

seems to be good

ashen tusk
#

just copy the dependency and do the same with jjwt-impl instead of jjwt-api

#

at least that's what I'd guess

hazy geyser
# ashen tusk at least that's what I'd guess

"Unable to find an implementation for interface io.jsonwebtoken.io.Serializer using java.util.ServiceLoader. Ensure you include a backing implementation .jar in the classpath, for example jjwt-impl.jar, or your own .jar for custom implementations.] with root cause"

ashen tusk
#

Can you show the whole stack trace and the whole build.grade?

hazy geyser
ashen tusk
#

make sure to reload the project in your IDE

hazy geyser
ashen tusk
#

seems working

#

Now that you have shown your token, I can access your API ... assuming I would have access to your computer

hazy geyser
#

Mhhh, i did that "return ResponseEntity.ok("Bearer " + new JwtResponse(token).getToken());" but i get 2023-01-14T13:48:09.184+01:00 WARN 20297 --- [nio-8080-exec-2] c.e.emailer.security.JwtRequestFilter : JWT Token does not begin with Bearer String

hazy geyser
ashen tusk
#

try new JwtResponse("Bearer " + token).getToken());

#

maybe

#

not sure

#

might be wrong

ashen tusk
hazy geyser
#

but still getting the warn

ashen tusk
#

maybe only new JwtResponse(token)

#

idk

#

or "Bearer "+token

hazy geyser
#

i'll check that later

#

it's not a big issue

#

then when'll get 3000 warns i'll check lol

hazy geyser
#

Okay, then, so auth with username works, but can i do the same with email? like if user enter an email, it'll check if it's good ? Because UsernamePasswordAuthenticationToken exists, but nothing for emails?

ashen tusk
#

you can create your own UserDetailService or AuthenticationManager doing that

#

and you can use UsernamePasswordAuthenticationToken for E-Mails

hazy geyser
#

and you can use UsernamePasswordAuthenticationToken for E-Mails
i should ?

ashen tusk
#

not sure whether you should but you could