#Springboot error: Is there an unresolvable circular reference?
144 messages · Page 1 of 1 (latest)
⌛ This post has been reserved for your question.
Hey @hazy geyser! Please use
/closeor theClose Postbutton 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.
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 🙏
Can you show the complete error message?
Is there something before or after?
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
move that out of the WebSecurityConfig
to another @Configuration class
@Configuration
public class PasswordEncoderConfig {
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
yes, like that
then
@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());
}
}```
?
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
i'll check that
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
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```
do not specify a version for any Spring Boot Starter dependencies
reload the project and try again
let's do it again with new method
don't extend WebSecurityConfigurerAdapter any more
but instead create a bean like this:
@Bean
SecurityFilterChain setupHttpSecurity(HttpSecurity http) throws Exception {
@Bean
SecurityFilterChain setupHttpSecurity(HttpSecurity http) throws Exception {
return http.authorizeRequests().requestMatchers("/resources/**", "/registration").permitAll().anyRequest()
.authenticated().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll().and()
.build();
}```
smthg like that?
yes
then replaced java @Bean public AuthenticationManager customAuthenticationManager() { return authenticationManager(); }
by
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}```
probably
last question, do you think i should use .jsp files ?
i need to check how does it work
you have an HTML file with tags like
<div th:if="${someExpression}">
...
</div>
okey, like "if connected and have role admin, then show header"
but i wanted to use react instead
i need to check how interactions work, with front and backend, and secure everything with tokens
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
whatever i do, i get this response
or maybe you need certain permissions to access /authenticate
mhh i don't think?
@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));
}```
maybe check your security config?
or maybe the authenticate method throws an exception
using a debugger might help you
how can i be dumb like that
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
yeah
which endpoint is that?
i fixed this 🙂
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'
Can you show the whole stack trace?
And what version of Spring Boot are you using?
3.0
mhhhh
Are you using io.jsonwebtoken:jjwt? In that case, try switching to io.jsonwebtoken:jjwt-api
done 🙂
does it work?
the newest version of it is 0.11.5
not the same error
just copy the dependency and do the same with jjwt-impl instead of jjwt-api
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"
Did you do that?
Can you show the whole stack trace and the whole build.grade?
fixed by adding " implementation 'io.jsonwebtoken:jjwt-api:0.11.0'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.0'
implementation 'io.jsonwebtoken:jjwt-gson:0.11.0'"
make sure to reload the project in your IDE
seems working
Now that you have shown your token, I can access your API ... assuming I would have access to your computer
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
yeah, connect yourself to localhost:8080
try new JwtResponse("Bearer " + token).getToken());
maybe
not sure
might be wrong
my localhost has other stuff on port 8080
it works
but still getting the warn
it return the class
i'll check that later
it's not a big issue
then when'll get 3000 warns i'll check lol
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?
you can create your own UserDetailService or AuthenticationManager doing that
and you can use UsernamePasswordAuthenticationToken for E-Mails
and you can use UsernamePasswordAuthenticationToken for E-Mails
i should ?
not sure whether you should but you could