Requested bean is currently in creation: Is there an unresolvable circular reference?

SpringDependency InjectionAutowired

Spring Problem Overview


i am using spring 3, and i have two beans of view scope:

1- Bean1:

@Component("bean1")
@Scope("view")
public class Bean1 {

@Autowired
private Bean2 bean2;

}

2- Bean2:

@Component("bean2")
@Scope("view")
public class Bean2 {

@Autowired
private Bean1 bean1;

}

the view is a custom scope:

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
		<property name="scopes">
			<map>
				<entry key="view">
					<bean class="${project.groupId}.utils.ViewScope" />
				</entry>
			</map>
		</property>
	</bean>

and here's the code for the custom view scope:

public class ViewScope implements Scope {

	@SuppressWarnings("rawtypes")
	public Object get(String name, ObjectFactory objectFactory) {
		Map<String, Object> viewMap = FacesContext.getCurrentInstance()
				.getViewRoot().getViewMap();

		if (viewMap.containsKey(name)) {
			return viewMap.get(name);
		} else {
			Object object = objectFactory.getObject();
			viewMap.put(name, object);

			return object;
		}
	}

	public Object remove(String name) {
		return FacesContext.getCurrentInstance().getViewRoot().getViewMap()
				.remove(name);
	}

	public String getConversationId() {
		return null;
	}

	public void registerDestructionCallback(String name, Runnable callback) {
		// Not supported
	}

	public Object resolveContextualObject(String key) {
		return null;
	}
}

when opening the page that uses both beans, i get the exception:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'agencyBean': Requested bean is currently in creation: Is there an unresolvable circular reference?
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:252)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:844)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:786)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
	at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:329)
	at com.myapp.utils.ViewScope.get(ViewScope.java:20)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:844)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:786)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
	at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:329)
	at com.xeno.xecamp.webManagement.utils.ViewScope.get(ViewScope.java:20)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
	at org.springframework.beans.factory.access.el.SpringBeanELResolver.getValue(SpringBeanELResolver.java:56)
	at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
	at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
	at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:71)
	at org.apache.el.parser.AstValue.getTarget(AstValue.java:94)
	at org.apache.el.parser.AstValue.invoke(AstValue.java:244)
	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at com.sun.faces.facelets.tag.jsf.core.DeclarativeSystemEventListener.processEvent(EventHandler.java:128)
	at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2508)
	at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106)
	at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2139)
	at com.sun.faces.application.ApplicationImpl.invokeComponentListenersFor(ApplicationImpl.java:2087)
	at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:286)
	at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:244)
	at org.springframework.faces.webflow.Jsf2FlowApplication.publishEvent(Jsf2FlowApplication.java:94)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:108)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:118)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:99)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:60)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:57)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:471)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
	at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:110)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:304)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:619)

please advise how to fix this exception.

EDIT: i tried to use the setter injection as referenced in the answer here

https://stackoverflow.com/questions/5632596/understanding-spring-context-initialization-order

but it doesn's work too.

1- Bean1:

@Component("bean1")
@Scope("view")
public class Bean1 {


private Bean2 bean2;

@Autowired
public void setBean2 (Bean2 bean2) {
    this.bean2= bean2;
}

}

2- Bean2:

@Component("bean2")
@Scope("view")
public class Bean2 {


private Bean1 bean1;

@Autowired
public void setBean1 (Bean1 bean1) {
    this.bean1= bean1;
}

}

but it gives me the exception:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.myapp.beans.Bean1] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

Spring Solutions


Solution 1 - Spring

I think you could use Spring's

> @Lazy

annotation on one of the autowired fields to break circular dependency.

I'm not sure if this works/exists in mentioned Spring version.

Solution 2 - Spring

Spring uses an special logic for resolving this kind of circular dependencies with singleton beans. But this won't apply to other scopes. There is no elegant way of breaking this circular dependency, but a clumsy option could be this one:

@Component("bean1")
@Scope("view")
public class Bean1 {

    @Autowired
    private Bean2 bean2;

    @PostConstruct
    public void init() {
        bean2.setBean1(this);
    }
}

@Component("bean2")
@Scope("view")
public class Bean2 {

    private Bean1 bean1;

    public void setBean1(Bean1 bean1) {
        this.bean1 = bean1;
    }
}

Anyway, circular dependencies are usually a symptom of bad design. You would think again if there is some better way of defining your class dependencies.

Solution 3 - Spring

In my case, I was defining a bean and autowiring it in the constructor of the same class file.

@SpringBootApplication
public class MyApplication {
    private MyBean myBean;

    public MyApplication(MyBean myBean) {
        this.myBean = myBean;
    }

    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

My solution was to move the bean definition to another class file.

@Configuration
public CustomConfig {
    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

Solution 4 - Spring

i encountered this error in quite a stupid way

@Autowired
// private Bean bean;

public void myMethod() {
  return;
}

what happened is that I commented a line for some reason and left the annotation which made spring think that the method needs to be autowired

Solution 5 - Spring

IMPORTANT: Read the EDIT at the end.

I also encountered this Exception after I upgraded Spring to 2.6.6 (this may or may not be relevant).

ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'webSecurityConfig': 
Requested bean is currently in creation: Is there an unresolvable circular reference?

Keep in mind that my class was extending WebSecurityConfigurerAdapter. This is a configuration class using @Configuration & @EnableWebSecurity annotation.

Anyway the solution that worked for me was this: https://errorsfixing.com/error-creating-bean-with-name-securityconfig-requested-bean-is-currently-in-creation/

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    ..."some code"...
}

After the change, that method looks like this:

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    ..."same code"...
}

So I've just changed the @Autowired to @Override and renamed the method to configure().

EDIT:

This change brought some unexpected problems for me. My configuration allows multiple AuthenticationProviders. Also there are multiple sub classes that extend WebSecurityConfigurerAdapter defined in my SecurityConfig class.

The problem: in most (well, actually all) cases the wrong AuthenticationProvider was called.

The sollution: I had to go back to @Autowired and configureGlobal :/ The circular dependency can be "ignored" by adding the following flag in your application.yml spring configuration:

spring:
  main:
    allow-circular-references: true

Solution 6 - Spring

My solution was to move the bean definition to another class of configuration

@Configuration
public class EncoderConfig {
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

Solution 7 - Spring

In general, the way to deal with circular dependencies is to use setter injection.

I tried the setter injection code that you posted, and it worked for me. I would imagine the reason you are getting the exception is because Bean1 and Bean2 are in the com.myapp.beans package, and you don't have component scanning enabled for that package.

You'd need to add the following to your spring configuration:

<context:component-scan base-package="com.bullethq.accounts.web"/>

or move the beans to a package which is being automatically scanned by Spring.

Solution 8 - Spring

@Resource annotation on field level also could be used to declare look up at runtime

Solution 9 - Spring

1. Disable Non-Test Security-Config for tests

@EnableWebSecurity
@Profile("!test")
public class SecurityConfig extends WebSecurityConfigurerAdapter { ... }

2. Add Test-Security Config in Test-Folder

@TestConfiguration
public class TestSecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.antMatcher("**/*").anonymous();
  }
}

3. Add TestConfig to Integration Test

@SpringBootTest(webEnvironment = RANDOM_PORT)
@ContextConfiguration(classes = TestSecurityConfig.class)
public class IntegrationTest { ... }

Solution 10 - Spring

In general, the most appropriated way to avoid this problem, (also because of better Mockito integration in JUnit) is to use the Setter/Field Injection as described at https://www.baeldung.com/circular-dependencies-in-spring and at https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html

@Component("bean1")
@Scope("view")
public class Bean1 {
    private Bean2 bean2;

    @Autowired
    public void setBean2(Bean2 bean2) {
        this.bean2 = bean2;
    }
}

@Component("bean2")
@Scope("view")
public class Bean2 {
    private Bean1 bean1;

    @Autowired
    public void setBean1(Bean1 bean1) {
        this.bean1 = bean1;
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMahmoud SalehView Question on Stackoverflow
Solution 1 - SpringFazoMView Answer on Stackoverflow
Solution 2 - SpringsinuhepopView Answer on Stackoverflow
Solution 3 - SpringRenato BackView Answer on Stackoverflow
Solution 4 - SpringmasadwinView Answer on Stackoverflow
Solution 5 - Springf1v3View Answer on Stackoverflow
Solution 6 - SpringAhmed amaniView Answer on Stackoverflow
Solution 7 - SpringJohn FarrellyView Answer on Stackoverflow
Solution 8 - SpringАртур КурицынView Answer on Stackoverflow
Solution 9 - SpringFzumView Answer on Stackoverflow
Solution 10 - SpringlinuxaticoView Answer on Stackoverflow