Spac Valentin
Spac Valentin

Reputation: 96

Spring: Can't inject String into xml defined bean as a constructor arg

I am trying to inject a simple String into as a constructor arg into a bean which extends org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint. This is the class:

    @Component
    public class AuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    public AuthenticationEntryPoint(String url) {
        super(url);
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {        
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }
}

In my security-context.xml, I have defined my bean as follows:

<beans:bean id="authenticationEntryPoint" class="a.b.s.AuthenticationEntryPoint" >
    <beans:constructor-arg index="0" type="java.lang.String" value="/login"/>
</beans:bean>

From what I know, this should work, but I get the following error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'authenticationEntryPoint' defined in file [/a/b/c/d/target/app/WEB-INF/classes/a/b/s/AuthenticationEntryPoint.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [java.lang.String] found for dependency [java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

What is strange is that it works with the following configuration:

<beans:bean id="loginUrl" class="java.lang.String">
    <beans:constructor-arg value="/login"/>
</beans:bean>
<beans:bean id="authenticationEntryPoint" class="a.b.s.AuthenticationEntryPoint" >
    <beans:constructor-arg index="0" type="java.lang.String" value="/login"/>
</beans:bean>

So, only declaring a String bean and not using it makes the app run. Can someone explain to me why is this happening?

L.E: I am using Spring context 4.3.0 and Spring security 4.1.0

Fix: Because it is defined in xml and also annotated with @Component, Spring makes 2 instances of the same type, so the error came when Spring tried to call the constructor while scanning the package and it had no autowired String to pass as constructor arg. I solved it by simply removing the @Component from the AuthenticationEntry‌​Point class.

We can now delete this post

Upvotes: 2

Views: 4835

Answers (2)

abubi abubi
abubi abubi

Reputation: 51

It seams a bug. If you have 2 instances of same bean , how to inject a different string for each instance if the label id is inside the bean.

Upvotes: 0

mszymborski
mszymborski

Reputation: 1654

The problem is caused by your @Component annotation - it gets picked up during component scanning, and you don't provide the string for that bean definition, causing container configuration to fail.

To fix that you have to remove one of the configurations, and should you decide to keep the annotation-based config, also inject the string using the @Value annotation.

Upvotes: 2

Related Questions