0
votes

I am new to building web services and I started using spring boot to build one. I created the following controller class

package controller;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import model.Time;
import service.FeedService;

@RestController
public class FeedController extends ScheduledThreadPoolExecutor{

    public FeedController(int corePoolSize) {
        super(corePoolSize);
        // TODO Auto-generated constructor stub
    }
    int difference;
    int a;
    boolean schedule;
    //static as the variable is accessed across multiple threads
    @Autowired
    static FeedService fs;

    @RequestMapping(value="/test")
    public String test(){
        return "test";
    }



    @RequestMapping(value = "/schedule", method = RequestMethod.GET)
    public int ScheduleFeed(@RequestParam(value = "difference",required = false) String y) throws InterruptedException, ExecutionException{
//      if(y != null){
//          difference = Integer.parseInt(y);
            difference = 0;
            NewScheduledThreadPoolTest.mymethod(difference);
            return difference;

//      }else{
//          return -1;
//      }
    }

    @RequestMapping(value = "/inquireSchedule", method = RequestMethod.GET)
    public ResponseEntity<Time> RequestFeed(){
        if(schedule == true){
            schedule = fs.setFalse();
            return new ResponseEntity<Time>(HttpStatus.OK);
        }
        return new ResponseEntity<Time>(HttpStatus.BAD_REQUEST);

    }
    //schedule the task to happen after a certain number of times
    static class NewScheduledThreadPoolTest {
        public static void mymethod(int difference, final String... args) throws InterruptedException, ExecutionException {
            // creates thread pool with 1 thread
            System.out.println("hello world");
            final ScheduledExecutorService schExService = Executors.newScheduledThreadPool(2);
            // Object creation of runnable thread.
            final Runnable ob = new NewScheduledThreadPoolTest().new myclass();
            // Thread scheduling ie run it after "difference" hours before and then after every 24 hours later on
            schExService.scheduleWithFixedDelay(ob, difference, 24, TimeUnit.SECONDS);
            // waits for termination for 30 seconds only
            schExService.awaitTermination(30, TimeUnit.SECONDS);
            // shutdown now.
            schExService.shutdownNow();
            System.out.println("Shutdown Complete");
        }

    class myclass implements Runnable{

        @Override
        public void run() {
            try{
            // the mechanism to give a positive feedback to the arduino service
                fs.setTrue();
                System.out.println("hello world");
            }catch(Exception e){
                System.out.println("task failed");
                e.printStackTrace();
            }
        }}
    }
}

Trying to run my web service causes it to throw the following exception:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'feedController' defined in file [D:\Rishit\Java workspaces\FeedNemo\target\classes\controller\FeedController.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [int] found for dependency [int]: 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 [int] found for dependency [int]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at com.example.DemoApplication.main(DemoApplication.java:17) [classes/:na] Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [int] found for dependency [int]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1406) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1057) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] ... 19 common frames omitted

However, If I remove the "ScheduledThreadPoolExecutor" and the constructor, it runs fine. Can someone please explain what is the problem with extending the class?

Note:

1) Extending the class was suggested in the below mentioned post as a solution to my initial problem. Initially, my runnable was not running without any sort of notification or error message

2) The below post makes use of abusive language. However this was the only one that provided a solution to my initial problem. The initial problem is specified just to give a clarity of why I extended the above class and may not be directly related to my current problem. Please do not open if you find such language offensive.

http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/

1
Where do you define the argument the constructor expects?Dave Newton
After examination, it doesn't look like the problem is in the code you posted, because it's referring to some other field, presumably one in the superclass. Convert to constructor injection and the problem will probably disappear.chrylis -cautiouslyoptimistic-
@DaveNewton Sorry I did not understand your question properly. The constructor takes in corePoolSize only. There are no other arguments defined anywhere else.Rishit Shah

1 Answers

-1
votes

Do not make bean members static. The fact that they're referenced from multiple threads is irrelevant; it's Spring's job to make sure that the dependencies are populated.

Also, prefer constructor injection to field injection; it makes these sorts of issues dramatically less likely.