Search code examples
javajavabeansnosuchmethoderror

Getting java.lang.NoSuchMethodException: Property 'xx' has no setter method in class 'class xx' while using PropertyUtils.setSimpleProperty function


I am using PropertyUtils.setSimpleProperty to invoke my setter method dynamically, but for some reason I keep on getting error. Need your assistance to figure out the root cause. Here is my code:

class FileDt {
    String reportName=null;
    String reportLocation=null;

    public String getReportName() {
        return reportName;
    }
    public void setReportName(String reportName) {
        this.reportName = reportName;
    }
    public String getReportLocation() {
        return reportLocation;
    }
    public void setReportLocation(String reportLocation) {
        this.reportLocation = reportLocation;
    }
}

class Foo {
    public static void main (String... args) {
        FileDt dt = newFileDt();
        // #1
        PropertyUtilsBean.setSimpleProperty(dt, "reportName", "abc.html");
        // #2
        PropertyUtilsBean.setSimpleProperty(dt, "reportLocation", "c://");
    }
}

Both of these methods throw exception

  1. Caused by: java.lang.NoSuchMethodException: Property 'reportName' has no setter method in class 'class FileDt' at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2096)

  2. Caused by: java.lang.NoSuchMethodException: Property 'reportLocation' has no setter method in class 'class FileDt' at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2096)


Solution

  • PropertyUtilsBean.setSimpleProperty(Object bean, String name, Object value)) works with public methods only. It looks like your class uses package scope (missing public keyword in class definition).

    Running following example:

    import org.apache.commons.beanutils.PropertyUtils;
    
    import java.lang.reflect.InvocationTargetException;
    
    class FileDt {
        String reportName;
        String reportLocation;
    
        public String getReportName() {
            return reportName;
        }
    
        public void setReportName(String reportName) {
            this.reportName = reportName;
        }
    
        public String getReportLocation() {
            return reportLocation;
        }
    
        public void setReportLocation(String reportLocation) {
            this.reportLocation = reportLocation;
        }
    
        public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            FileDt dt = new FileDt();
            // #1
            PropertyUtils.setSimpleProperty(dt, "reportName", "abc.html");
            // #2
            PropertyUtils.setSimpleProperty(dt, "reportLocation", "c://");
        }
    }
    

    throws an exception you have described:

    Exception in thread "main" java.lang.NoSuchMethodException: Property 'reportName' has no setter method in class 'class FileDt'
        at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2096)
        at org.apache.commons.beanutils.PropertyUtils.setSimpleProperty(PropertyUtils.java:928)
        at FileDt.main(FileDt.java:28)
    

    Making your class public solves the problem:

    import org.apache.commons.beanutils.PropertyUtils;
    
    import java.lang.reflect.InvocationTargetException;
    
    public class FileDt {
        String reportName;
        String reportLocation;
    
        public String getReportName() {
            return reportName;
        }
    
        public void setReportName(String reportName) {
            this.reportName = reportName;
        }
    
        public String getReportLocation() {
            return reportLocation;
        }
    
        public void setReportLocation(String reportLocation) {
            this.reportLocation = reportLocation;
        }
    
        public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            FileDt dt = new FileDt();
            // #1
            PropertyUtils.setSimpleProperty(dt, "reportName", "abc.html");
            // #2
            PropertyUtils.setSimpleProperty(dt, "reportLocation", "c://");
        }
    }