Question

Different between our WAS in dev and our local was

Our application is using Spring-Security with Spring version 3.1.0-release.

It starts in a JSP file, we are trying to show the connected username:

On WAS in DEV, we have a NotReadablePropertyException : "Bean property 'principal' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?"

This is because the AuthenticationTag is using a BeanWrapper (BeanWrapperImpl)

At line 729 (Spring 3.1.0-RELEASE) of file BeanWrapperImpl the error is throw,

727:PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
728:if (pd == null || pd.getReadMethod() == null) {
729:                throw new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);
730:}

So pd is null or pd.getReadMethod() is null. In normal cases getReadMethod return this : Object Method[public java.lang.Object org.springframework.security.authentication.UsernamePasswordAuthenticationToken.getPrincipal()]

update after debugging and adding some logs in the class, it seems that "pd" is null

I wrote this code in pure java to identify the error

    logger.info(session.getAttribute("SPRING_SECURITY_CONTEXT").getClass().toString());
    final SecurityContextImpl sci = ((SecurityContextImpl) session.getAttribute("SPRING_SECURITY_CONTEXT"));
    logger.info(sci.getAuthentication().getClass().toString());
    final Authentication auth = sci.getAuthentication();
    logger.info(auth.getPrincipal().getClass().toString());
    final User u = (User) auth.getPrincipal();
    logger.info(u.getUsername());
    logger.info(SecurityContextHolder.getContext().getAuthentication().getName());

    logger.info("use beanWrapper :");
    final BeanWrapperImpl wrapper = new BeanWrapperImpl(auth);
    String property = "principal";
    Object result = wrapper.getPropertyValue(property);
    logger.info("property : " + property + " value :[" + result.toString() + "]");
    property = "principal.username";
    result = wrapper.getPropertyValue(property);
    logger.info("property : " + property + " value :[" + result.toString() + "]");

log on our WAS in dev :

[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.context.SecurityContextImpl
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.authentication.UsernamePasswordAuthenticationToken
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.userdetails.User
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-12 12:23:19,843] INFO  [WebContainer : 8] [c.b.e.e.w.c.IndexController] use beanWrapper :

<500 error>

logs on our local was :

[2012-01-13 08:51:10,062] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.context.SecurityContextImpl
[2012-01-13 08:51:10,062] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.authentication.UsernamePasswordAuthenticationToken
[2012-01-13 08:51:10,062] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.userdetails.User
[2012-01-13 08:51:10,062] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-13 08:51:10,073] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-13 08:51:10,073] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] use beanWrapper :
[2012-01-13 08:51:10,095] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] property : principal value :[org.springframework.security.core.userdetails.User@99ac08b4: Username: superadmin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SuperAdmin]
[2012-01-13 08:51:10,095] INFO  [WebContainer : 4] [c.b.e.e.w.c.IndexController] property : principal.username value :[superadmin]

Our WAS in dev is a full version,

Our local WAS is a light,free developper version

UPDATE

After coding a workaround to get the userName the problem happen further down the road, still with the BeenWrapperImpl

org.springframework.beans.NotReadablePropertyException: Invalid property 'codeAndName' of bean class [com.data.model.Country]: Bean property 'codeAndName' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:729)
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:721)
    at org.springframework.web.servlet.tags.form.OptionWriter.doRenderFromCollection(OptionWriter.java:216)
    at org.springframework.web.servlet.tags.form.OptionWriter.renderFromCollection(OptionWriter.java:186)
    at org.springframework.web.servlet.tags.form.OptionWriter.writeOptions(OptionWriter.java:139)
    at org.springframework.web.servlet.tags.form.OptionsTag.writeTagContent(OptionsTag.java:169)

UPDATE 2 :

problem is more isolated : without any depenency to spring security, only springmvc,

when a been putted in beanWrapper has no setter corresponding to the getter, it throws a NotReadablePropertyException only on the was in dev.

when there is a setter, then there is no issue. assuming that the class UsernamePasswordAuthenticationToken is a class from spring security.class.

Was it helpful?

Solution

one solution found :

probleme is due to the Introduction of ExtendedBeanInfo inf spring3.1

...

cf : https://github.com/SpringSource/spring-framework/commit/2f5085aef1e9ac3655a1b1250b6ceca9d0ca3398#diff-0

so the solution, is to take the previous version of CachedIntrospectionResults and put it in the package "org.springframework.beans" so that it will be overwritten,

but you have to be sure that application classpath is take first.

OTHER TIPS

I was having the same issue when trying to set a nested property using BeanWrapper. The issue was that the property did not have a setter, even though I did not think the setter was necessary. Adding the setter fixed my issue. Thanks for providing the updates Benoit! My bean:

public class Bean {
    private InnerBean innerBean = new InnerBean();
    public InnerBean getInnerBean() {
        return this.innerBean;
    }
}

My BeanWrapper code that was failing:

BeanWrapper wrapper = new BeanWrapperImpl(new Bean());
wrapper.setPropertyValue("innerBean.property","some value");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top