2

I defined 2 classes.

AndroidPush.java

public class AndroidPush {

    private static String SERVER_KEY = "XXXXX";
    private static String DEVICE_TOKEN = "XXXXX";
    public static void main(String[] args) throws Exception {
        String title = args[0];
        String message = args[1];
        sendPushNotification(title, message);
    }
    private static void sendPushNotification(String title, String message) throws Exception {
        String pushMessage = "{\"data\":{\"title\":\"" +
                title +
                "\",\"message\":\"" +
                message +
                "\"},\"to\":\"" +
                DEVICE_TOKEN +
                "\"}";
        URL url = new URL("https://fcm.googleapis.com/fcm/send");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Authorization", "key=" + SERVER_KEY);
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        OutputStream outputStream = conn.getOutputStream();
        outputStream.write(pushMessage.getBytes());
    }
}

And

NotificationProcessing.java

public class NotificationProcessing {

    private static NotificationRepo notificationRepo;

    @Autowired
    public NotificationProcessing(NotificationRepo notificationRepo) {
        NotificationProcessing.notificationRepo = notificationRepo;
    }

    public static void addNotification(Offer offer) throws Exception {
        Notification notification = new Notification();
        notification.setId(null);
        notification.setMessage("There is new offer: " + offer.getTitle());
        notification.setLink("/offers/" + offer.getId());
        notificationRepo.save(notification);

        String[] arguments = new String[] {"New Offer", notification.getMessage()};
        AndroidPush.main(arguments);
    }
}

I call my repository inside static method like Francisco Speath answered on this question @Autowired and static method

But then, if I try to call my method and store notification I am getting this error:

java.lang.NullPointerException: null

on this line: notificationRepo.save(notification);

I suppose this is because using repository inside of static method, but if I remove static from everywhere and try to access addNotification() method there is another error:

non-static method cannot be referenced from a static context

I'm calling this addNotification() method inside my RestController

@RequestMapping(method = RequestMethod.POST)
public Offer newOffer (@RequestBody Offer offer) {
    NotificationProcessing.addCampaignNotification(offer);
    return repo.save(offer);
}

So what is solution for using repository inside static method?

Ante Ereš
  • 623
  • 4
  • 8
  • 24
  • Why do you want to use `addNotification` as a static method? – aBnormaLz Dec 21 '18 at 14:59
  • sincerely, I don't want to use this method as a static, but if I remove static there is this second ERROR : "non-static method cannot be referenced from a static context" and I am not able to run application at all. So if there is any suggestion to avoid this error when I am not using static and explanation why is it happening, it would be useful – Ante Ereš Dec 21 '18 at 15:04

3 Answers3

3

The referenced question handles about how to reference an instance field injected by Spring from a static method.
As static modifiers don't have any access to instance fields, it may make sense.
But that is not the standard, it is a workaround for legacy code or libraries where it sounds complicated or not possible to make the static method an instance method.

I suppose this is because using repository inside of static ethod, but if I remove static from everywhere and try to access addNotification() method there is another error:

non-static method cannot be referenced from a static context

You are on the wrong way.
To use bean dependencies you need to inject them where you need them in other beans.
You will never define methods with static modifier in a bean and invoke it from another bean by prefixing the class.
Beans are instances. These are not related to the class itself.

Besides if notificationRepo.save(notification); triggers a NullPointerException, it means a single thing : your class is not a bean spring because here the Spring context will not be successfully loaded if the notificationRepo dependency cannot be resolved :

@Autowired
public NotificationProcessing(NotificationRepo notificationRepo) {
    NotificationProcessing.notificationRepo = notificationRepo;
}

Long story short, annotate your class to make it a Spring Bean and remove all these static modifiers :

@Component
public class NotificationProcessing {
    ...
}

And inject this in this way in the controller :

private NotificationProcessing notificationProcessing;

public MyController(NotificationProcessing notificationProcessing){
  this.notificationProcessing = notificationProcessing;
}

@RequestMapping(method = RequestMethod.POST)
public Offer newOffer (@RequestBody Offer offer) {
    notificationProcessing.addCampaignNotification(offer);
    return repo.save(offer);
}
davidxxx
  • 125,838
  • 23
  • 214
  • 215
0

Constructor is invoked when you create an instance of your object so it looks illogical to mark a constructor with @Autowired and use the injected instances from the static context. As I see NotificationProcessing is not marked as @Component so I'm not sure that it is handled by the container at all.

I'd recommend you removing the static modifiers from notificationRepo and addNotification(), marking the class as @Component and invoke addNotification() from the injected instance of NotificationProcessing.

Anton Hlinisty
  • 1,441
  • 1
  • 20
  • 35
0

I think you should change NotificationProcessing.addCampaignNotification(offer); to notificationProcessing.addCampaignNotification(offer); and inject the notificationProcessing into your controller by adding the following constructor:

@Autowired
public YourController(NotificationProcessing notificationProcessing) {
    this.notificationProcessing= notificationProcessing;
}
aBnormaLz
  • 809
  • 6
  • 22