2

I have the following:

@Service(DropboxService.NAME)
public class DropboxServiceBean implements DropboxService {

    @Inject
    private CustomConfig customConfig;


    private final String ACCESS_TOKEN = customConfig.getDropboxAppToken();
    DbxRequestConfig config = new DbxRequestConfig("dropbox/java-tutorial", "en_US");
    DbxClientV2 client = new DbxClientV2(config, ACCESS_TOKEN);

Does anyone know how I can get the values of the customConfig.getDropboxAppToken(); to load first. I keep getting the following error:

Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'myApp_DropboxService' defined in URL
[jar:file:/E:/Cuba/myApp/deploy/tomcat/webapps/app-core/WEB-INF/lib/app-core-0.1-SNAPSHOT.jar!/com/daryn/myApp/service/DropboxServiceBean.class]:
Instantiation of bean failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [com.daryn.myapp.service.DropboxServiceBean]: Constructor
threw exception; nested exception is java.lang.NullPointerException

Current code I am trying

ERROR: Error creating bean with name 'ecosmart_BackupService': Unsatisfied dependency expressed through field 'dropboxService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ecosmart_DropboxService': Invocation of init method failed; nested exception is java.lang.NullPointerException

@Service(DropboxService.NAME)
public class DropboxServiceBean implements DropboxService {

    @Inject
    private CustomConfig customConfig;


    private String ACCESS_TOKEN = "";
    DbxRequestConfig config;
    DbxClientV2 client;



    @PostConstruct
    public void postConstruct() {
        System.out.println("**************Running post construct");
        ACCESS_TOKEN = customConfig.getDropboxAppToken();
        config = new DbxRequestConfig("dropbox/java-tutorial", "en_US");
        client = new DbxClientV2(config, ACCESS_TOKEN);
    }
Daryn
  • 1,551
  • 1
  • 15
  • 21
  • Put that in a `@PostConstruct` annotated method. Injection can only take place after an object has been created. – M. Deinum Sep 19 '17 at 05:48
  • I have updated with trying @postconstruct. However, It still isn't working. Presumably because the bean is being instantiated before the CustomConfig bean has on boot up... – Daryn Sep 19 '17 at 06:25
  • You started with `myApp_DropboxService` and now you have a problem with `ecosmart_BackupService` so the problem is with the code in that class probably similar to this one. – Oleg Sep 19 '17 at 06:29
  • That's not the problem... I just changed the name. – Daryn Sep 19 '17 at 06:38
  • Which line throws `NullPointerException`? – Oleg Sep 19 '17 at 06:52
  • @Oleg ACCESS_TOKEN = customConfig.getDropboxAppToken(); It will run if I comment this out. I think it has something to do with the CustomConfig bean not being instantiated first - so it is null when this bean is instantiated. I have been looking at some google posts about ATDependsOn but can't figure out how to do it... Not sure if this is on the right track. – Daryn Sep 19 '17 at 07:01
  • 1
    An `@Autowired` or `@Inject`, when used properly, cannot be `null`. Your application will fail to start with a message that an auto wired dependency cannot be found. Which leads me to believe you are creating instances yourself or haven't setup things properly. – M. Deinum Sep 19 '17 at 07:05
  • @M.Deinum Yes, I think it has something to do with the CustomConfig. It CustomConfig is an interface which I built that extends an interface called config built into the platform - not really sure how it all works TBH. – Daryn Sep 19 '17 at 07:16
  • I have posted my workaround solution as an answer. Probably a bit ugly. And still have no idea why the CustomConfig would be null @PostConstruct :S ! – Daryn Sep 19 '17 at 07:55

2 Answers2

1

Spring injects fields only after the object was constructed and in your case ACCESS_TOKEN is initialized even before that.

You need to create a constructor and inject your bean in the constructor like so:

@Inject
public DropboxServiceBean(CustomConfig customConfig) {
  this.customConfig = customConfig;
  ACCESS_TOKEN = customConfig.getDropboxAppToken();
}
Oleg
  • 6,124
  • 2
  • 23
  • 40
  • Getting this: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.daryn.ecosmart.service.DropboxServiceBean]: Constructor threw exception; nested exception is java.lang.NullPointerException: accessToken – Daryn Sep 19 '17 at 06:02
  • @Daryn Update your question with your current code. – Oleg Sep 19 '17 at 06:06
  • @Daryn You need to move `new DbxClientV2(config, ACCESS_TOKEN);` inside the constructor. – Oleg Sep 19 '17 at 06:07
  • Have posted it as a new answer below. Am trying the @Postconstruct method as suggested above currently... – Daryn Sep 19 '17 at 06:14
  • @Daryn like said, update your question with that. As an answer it will get deleted. – eis Sep 19 '17 at 06:15
  • Have added to original question – Daryn Sep 19 '17 at 06:19
-1

Well, after much mucking around, here is my great solution. I have no idea why the CustomConfig would not intialise first...

@Service(DropboxService.NAME)
public class DropboxServiceBean implements DropboxService {        


    @Inject
    private CustomConfig customConfig;


    private String ACCESS_TOKEN = "";
    DbxRequestConfig config =new DbxRequestConfig("dropbox/java-tutorial", "en_US");
    DbxClientV2 client;

    public static boolean isInitiated = false;

    public void generateDbxClient(){
        ACCESS_TOKEN = customConfig.getDropboxAppToken();
        client = new DbxClientV2(config, ACCESS_TOKEN);
    }

    @Override
    @Transactional
    public void uploadFile(FileDescriptorExt file, String path) {

        if(isInitiated==false){
            System.out.println("generating client");
            generateDbxClient();
            isInitiated=true;
        }
Daryn
  • 1,551
  • 1
  • 15
  • 21