Can not set field to com.sun.proxy.$Proxy

38,951

Solution 1

Can not set 'FileValidator' field 'FileController.validator' to 'com.sun.proxy.$Proxy101'

FileValidator is a class, not an interface.

com.sun.proxy.$Proxy101 is an interface proxy, not a class proxy.

There are two main ways to solve this. Either inject the validator via an interface, e.g:

@Autowired @Qualifier("fileValidator")
private Validator fileValidator;

or enable class-proxies, e.g:

@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Application {

Those are just examples, there will be other ways to implement those two solutions.

Solution 2

Autowire the interface of FileValidator(class) in your class FileController. Doing this will not require you to specify @Qualifier as mentioned below:

@Autowired
IFileValidator filevalidator;
Share:
38,951

Related videos on Youtube

FunnyJava
Author by

FunnyJava

Updated on March 29, 2020

Comments

  • FunnyJava
    FunnyJava over 3 years

    For file upload I am trying to inject and use a Validator in my Spring Controller like this:

    @RestController
    @RequestMapping("/api")
    public class FileController{
    
        @Autowired
        private MessageSource messageSource;
    
        @Autowired
        FileValidator validator;
    
        @InitBinder("file")
        public void initBinderFile(WebDataBinder binder) {
            binder.setValidator(validator);
        }
    
        @RequestMapping(value = "/fileUpload2", method = RequestMethod.POST, produces = {"text/plain"})
        @PreAuthorize("hasAuthority('ADMINISTRATOR')")
        public String singleFileUpload2(@Valid @ModelAttribute("file") File file, BindingResult result) throws IOException {
            if (result.hasErrors()) {
                String errorString = "";
                for (ObjectError error : result.getAllErrors()) {
                     errorString = errorString.concat(messageSource.getMessage(error.getCode(), new String[]{}, Locale.ENGLISH)+"\n");
                }
                return errorString;
            } else {
                MultipartFile multipartFile = file.getFile();
    
                String fileName = multipartFile.getOriginalFilename();
                System.out.println("Fetching file: "+fileName);
    
                return messageSource.getMessage("upload.file.success", new String[]{}, Locale.ENGLISH);
            }
        }
    
    }
    

    Here is my Validator:

    @Component
    public class FileValidator implements Validator {
    
        @Override
        public boolean supports(Class<?> clazz) {
            return File.class.isAssignableFrom(clazz);
        }
    
        @Override
        public void validate(Object obj, Errors errors) {
            File file = (File) obj;
    
            if (file.getFile().getSize() == 0) {
                errors.rejectValue("file", "missing.file");
            } else try {
                if (file.getFile().getBytes().length > 2097152l) {
                    errors.rejectValue("file", "upload.file.error.size");
                }
                if(!file.getFile().getContentType().equalsIgnoreCase("text/html")){
                     errors.rejectValue("file", "incorrect.file.type");
                }
            } catch (IOException ex) {
                errors.rejectValue("file", "upload.file.error");
            } 
        }
    }
    

    Here is the File object that I am trying to validate:

    public class File {
    
        private String name;
        private MultipartFile file;
    
        public File() {
        }
    
        public File(MultipartFile file) {
            this.file = file;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public MultipartFile getFile() {
            return file;
        }
    
        public void setFile(MultipartFile file) {
            this.file = file;
        }
    
    }
    

    And here is the error that I get when I try to start my application:

        org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fileController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.enterprise.springapp.web.validators.FileValidator com.eurodyn.springapp.web.FileController.validator; nested exception is java.lang.IllegalArgumentException: Can not set com.enterprise.springapp.web.validators.FileValidator field com.enterprise.springapp.web.FileController.validator to com.sun.proxy.$Proxy101
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
        at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
        at com.enterprise.springapp.SpringApp.main(SpringApp.java:30) [classes/:na]
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.enterprise.springapp.web.validators.FileValidator com.enterprise.springapp.web.FileController.validator; nested exception is java.lang.IllegalArgumentException: Can not set com.enterprise.springapp.web.validators.FileValidator field com.enterprise.springapp.web.FileController.validator to com.sun.proxy.$Proxy101
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        ... 17 common frames omitted
    Caused by: java.lang.IllegalArgumentException: Can not set com.enterprise.springapp.web.validators.FileValidator field com.enterprise.springapp.web.FileController.validator to com.sun.proxy.$Proxy101
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:1.8.0_45]
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:1.8.0_45]
        at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) ~[na:1.8.0_45]
        at java.lang.reflect.Field.set(Field.java:764) ~[na:1.8.0_45]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE]
        ... 19 common frames omitted
    2016-06-09 15:12:39.909  WARN 4896 --- [           main] o.s.boot.SpringApplication               : Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' is defined)
    

    I don't know what's happening. Can anyone help?

    • a better oliver
      a better oliver over 7 years
      1. Never use @Autowired on fields. 2. There is a configuration for web security so it doesn't make much sense to put @PreAuthorize("hasAuthority('ADMINISTRATOR')") on a controller method. The combination of that two points is the cause of your problem.
  • FunnyJava
    FunnyJava over 7 years
    Thank you very much for your help! I applied the 2nd solution and it worked.
  • a better oliver
    a better oliver over 7 years
    The problem is not FileValidator but FileController.
  • OrangeDog
    OrangeDog over 7 years
    @zeroflagL the problem is how they are interacting - it's not just one or the other.
  • a better oliver
    a better oliver over 7 years
    No. Spring tries to create a proxy for FileController and then cannot set the validator. The error message cannot be more explicit.
  • OrangeDog
    OrangeDog over 7 years
    @zeroflagL The $Proxy101 refers to the proxy of a FileValidator bean, which cannot be assigned to a FileValidator-typed field because it implements Validator instead of extending FileValidator.
  • a better oliver
    a better oliver over 7 years
    Why should there be a proxy for FileValidator?
  • OrangeDog
    OrangeDog over 7 years
    Why is it trying to assign a proxy to FileController.validator?
  • OrangeDog
    OrangeDog over 7 years
    Anyway, regardless whether either or both of the classes would need re-factoring, the solution of enabling class-proxies will always work.

Related