1

I am working on a Spring-MVC application in which I am autowiring a field, but it is getting set as NULL. I checked the solutions on net for the same problem, as they describe, I should not create a new instance of classes when working, rather get it from spring. I tried that as well, but it always complains the resource is not found.

Here is the class :

@Service
@Transactional
public class GoogleAuthorization{

    @Autowired
    private DriveQuickstart driveQuickstart;  // This guy is null

    public void saveCredentials(final String authCode) throws IOException {

        GoogleTokenResponse response = flow.newTokenRequest(authCode).setRedirectUri(CALLBACK_URI).execute();
        Credential credential = flow.createAndStoreCredential(response, null);
        System.out.println(" Credential access token is "+credential.getAccessToken());
        System.out.println("Credential refresh token is "+credential.getRefreshToken());
// It fails at below point.
        this.driveQuickstart.storeCredentials(credential);
    }

Controller code :

@RequestMapping(value = "/getgooglelogin")
    public String getGoogleLogin(HttpServletRequest request, HttpServletResponse response, HttpSession session,Model model) {

       /* ApplicationContext applicationContext = new ClassPathXmlApplicationContext("../WEB-INF/spring/root-context.xml");
        GoogleAuthorization helper = (GoogleAuthorization) applicationContext.getBean("helper");*/
        GoogleAuthorization helper = new GoogleAuthorization();
}

I tried getting it via the root-context.xml as you can see above, but no matter what path I would put, it could not find it.

DriveQuickStartImpl :

@Service
@Transactional
public class DriveQuickstartImpl implements DriveQuickstart{
// All these below guys work just fine. 
@Autowired
    private PersonService personService;

    @Autowired
    private GoogleDriveService googleDriveService;

    @Autowired
    private GroupAttachmentsService groupAttachmentsService;

    @Autowired
    private GroupAccountService groupAccountService;
}

What am I doing wrong. Any help would be nice. Thanks a lot.

Update

Image for where root-context.xml belongs :

enter image description here

We are Borg
  • 5,117
  • 17
  • 102
  • 225
  • Do you use component scan? Otherwise, you have to explicitly tell spring what should be injected and where. Have a look at my explanation about `@Autowired` in another question: http://stackoverflow.com/a/19419296/2083523 – Avi Jul 08 '15 at 09:37

3 Answers3

1

Problem is here:

 GoogleAuthorization helper = new GoogleAuthorization();

As you created with GoogleAuthorization with new, Spring container wont be aware of the class which we might think as a spring bean and as a result it fails to Autowire it. Make sure your class in which @Autowiring is done is a spring bean. Trying instantiating GoogleAuthorization using FileSystemXmlApplicationContext as :

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(
                "src/main/webapp/WEB-INF/spring/root-context.xml");

GoogleAuthorization helper = (GoogleAuthorization)applicationContext.getBean("helper");
Arpit Aggarwal
  • 27,626
  • 16
  • 90
  • 108
  • Where do I get the applicationContext from? Did you see the Controller code I had posted, I tried the same by searching the XML file, but XML file was not found no matter what path I used. – We are Borg Jul 08 '15 at 09:26
  • org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [root-context.xml]; nested exception is java.io.FileNotFoundException: class path resource [root-context.xml] cannot be opened because it does not exist. – We are Borg Jul 08 '15 at 09:33
  • I will update the main post with screenshot for project structure. – We are Borg Jul 08 '15 at 09:33
  • Its solved, I injected the bean in Controller itself. – We are Borg Jul 08 '15 at 09:39
  • Great, I am about to ask you question why you are trying to read the configuration file from `Classpath` in Web Application because normally it's a way to use in standalone application. – Arpit Aggarwal Jul 08 '15 at 09:42
1

Just autowire the GoogleAuthorization helper (you can do this as you are already in a Spring-managed controller):

@Service
@Transactional
public class DriveQuickstartImpl implements DriveQuickstart{

    // Other stuff...

    @Autowired 
    private GoogleAuthorization helper;


    @RequestMapping(value = "/getgooglelogin")
public String getGoogleLogin(HttpServletRequest request, HttpServletResponse response, HttpSession session,Model model) {

       // use "helper"
}

If you autowire the helper, it is injected and managed by Spring. So Spring will build and autowire it correctly.

Thomas Uhrig
  • 30,811
  • 12
  • 60
  • 80
1

if you create an instance with 'new' on your own there will be no spring wiring at all.

if you use Spring in a Web-App Context you could use the ContextLoaderListener to initialize your Spring-Context.

    <!-- inside WEB-INF/web.xml -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!-- path to your Spring context configuration-->
        <!-- for example -->
        <param-value>/WEB-INF/spring-webapp-config.xml</param-value>
    </context-param>

you can then inject the GoogleAuthorization Bean in your controller as well, so there is no need to get hold of the application context to do a 'lookup' ... if you use spring try to let spring do the wiring instead of relying on 'lookups'.

André R.
  • 1,627
  • 10
  • 14