DesignerHook: Handling case where Vision has been disabled

Is there a canonical pattern for handling the case where a module has Vision components and the customer has disabled Vision? We just had a customer do that and they can’t start Designer due to our module, here’s the exception:

ModuleLoadException: Error loading hook class "com.seeq.ignition.designer.DesignerHook" for module "Seeq". caused by NoClassDefFoundError: com/inductiveautomation/vision/api/designer/palette/PaletteItem caused by ClassNotFoundException: com.inductiveautomation.vision.api.designer.palette.PaletteItem

How do you isolate the code and handle this exception (and then skip any Vision-related stuff)? Do I need to create a separate JAR?

You should just need to check if Vision is installed before you start referencing its classes or adding components or whatever. Something like this EventStreams module does: ignition-sdk-examples/event-stream-source/event-stream-source-gateway/src/main/java/com/inductiveautomation/ignition/examples/eventstream/source/gateway/ExampleSourceGatewayHook.java at dc086e3da35512409c2e2869674faa984f6926e6 · inductiveautomation/ignition-sdk-examples · GitHub

Basically, just try to get the Vision module from the ModuleManager and check if it's null or not.

edit: same idea in the DesignerModuleHook: ignition-sdk-examples/event-stream-source/event-stream-source-designer/src/main/java/com/inductiveautomation/ignition/examples/eventstream/source/designer/ExampleSourceDesignerHook.java at dc086e3da35512409c2e2869674faa984f6926e6 · inductiveautomation/ignition-sdk-examples · GitHub

1 Like

Complete example for you, from my NoteChart module. It conditionally adds the Vision components and/or Reporting component based on module presence:

    public void startup(DesignerContext context, LicenseState activationState) throws Exception {
        // Add my component to its own palette, but only if Vision is loaded.
        Object vision = context.getModule("com.inductiveautomation.vision");
        if (vision != null) {
            // Add the BeanInfo package to the search path
            context.addBeanInfoSearchPath("com.automation_pros.notechart.beaninfos");

            VisionDesignerInterface sdk = (VisionDesignerInterface) vision;
            logger.debug("Adding EasyNoteChart and NoteChart to Designer's 'Charts' Palette Group");
            Palette palette = sdk.getPalette();

            PaletteItemGroup group = palette.getGroup("Charts");
            group.addPaletteItem(new JavaBeanPaletteItem(EasyNoteChart.class));
            group.addPaletteItem(new JavaBeanPaletteItem(NoteChart.class));

        }
        Object reporting = context.getModule("com.inductiveautomation.reporting");
        if (reporting != null) {
            RMArchiver.registerClass(ReportNoteChart.ARCHIVE_NAME, ReportNoteChart.class);
            DesignerShapeRegistry.get(context).register(ReportNoteChart.class);
        }
    }
1 Like

Awesome, thanks all. I’ll test shortly

The context.getModule("com.inductiveautomation.vision") approach works great!

1 Like