Programmatically Add Script

getInstance() is deprecated. Is there a supported method? Also, I am doing this in the startup method. Should I be doing this somewhere else?

It's been deprecated since (at least) 2011. As the person who would be in charge of ever dealing with removing it...it's not ever going to get removed.

There's no way to get the private app field from the ClientContextImpl you get delivered on startup:

public void startup(ClientContext context, LicenseState activationState) throws Exception {
        super.startup(context, activationState);
        ClientHook.context = context;
        visionDesktop = new VisionDesktop(context) {
            @Override
            protected VisionClientContext initContext(ClientContext clientContext) {
                return this.getAdapterContext();
            }
        };
        DesktopListener desktopListener = new DesktopListener() {...

This is what I have. I initially tried FPMIApp.getInstance().getAdapterContext() but got a static reference in a non-static context issue. This code (using this.getAdapterContext()) throws the following:

Cannot invoke "com.inductiveautomation.ignition.client.model.ClientContext.getRootPaneContainer()" because "context" is null

And if I use FPMIApp.getInstance().getAdapterContext() to get the VisionClientContext, then get the VisionDesktop from that, I get the following error:

java.lang.NullPointerException: Cannot invoke "com.inductiveautomation.factorypmi.application.FPMIApp.getAdapterContext()" because the return value of "com.inductiveautomation.factorypmi.application.FPMIApp.getInstance()" is null

This is even after an earlier usage of the ‘context’ field in a scriptModule initialization. What am I doing wrong?

You are trying to create your own VisionDesktop. That can't be right.

But even when I don’t try to create my own and retrieve it via getAdapterContext(), my context object is null. Here is that code:

super.startup(context, activationState);
        ClientHook.context = context;
        FPMIApp app = FPMIApp.getInstance();
        VisionClientContext vcc = app.getAdapterContext();
        VisionDesktop vd = vcc.getPrimaryDesktop();
        DesktopListener desktopListener = new DesktopListener() {

This line is returning null?

I don't see how that's possible - that context field in VisionDesktop is final and assigned in the constructor. I could see a possibility of getInstance() returning null, because we're way in the weeds of startup timing stuff and this is a lot less defined than gateway startup ordering, but I can't see how getAdapterContext could return null.

Sorry I wasn’t speaking clearly. getInstance()is returning null.

I found a solution. I abstracted the creation of the DesktopListener to a function that returns it as a CompleteableFuture, then called that function from withing ClientHook.startup().