Module "com.inductiveautomation.alarm-notification" threw exception during setup()

I migrate a module very close to ignition-sdk-examples/slack-alarm-notification at ignition-8.3 · inductiveautomation/ignition-sdk-examples · GitHub
with an AlarmNotificationProfileExtensionPoint

At startup I have an error on IA alarm-notification related to my added module, but I don't found what I missed ?

image

com.inductiveautomation.ignition.common.gson.JsonSyntaxException: com.inductiveautomation.ignition.common.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 4 path $
	at com.inductiveautomation.ignition.common.gson.JsonParser.parseReader(JsonParser.java:76)
	at com.inductiveautomation.ignition.common.gson.JsonParser.parseString(JsonParser.java:51)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.parseLenient(SchemaUtil.java:420)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.lambda$addJsonSchemaMetadata$7(SchemaUtil.java:296)
	at java.base/java.util.Optional.map(Unknown Source)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.addJsonSchemaMetadata(SchemaUtil.java:296)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.fromTypeInternal(SchemaUtil.java:239)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.fromType(SchemaUtil.java:196)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.fromType(SchemaUtil.java:180)
	at java.base/java.util.Optional.map(Unknown Source)
	at com.inductiveautomation.ignition.gateway.config.ExtensionPoint.settingsSchema(ExtensionPoint.java:126)
	at com.inductiveautomation.ignition.gateway.config.DefaultResourceRouteDelegate$ExtensionPointBuilder.lambda$buildConfigSchema$3(DefaultResourceRouteDelegate.java:510)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.toList(Unknown Source)
	at com.inductiveautomation.ignition.gateway.config.DefaultResourceRouteDelegate$ExtensionPointBuilder.buildConfigSchema(DefaultResourceRouteDelegate.java:513)
	at com.inductiveautomation.ignition.gateway.config.DefaultResourceRouteDelegate$ExtensionPointBuilder.build(DefaultResourceRouteDelegate.java:545)
	at com.inductiveautomation.ignition.gateway.config.DefaultResourceTypeMeta$ExtensionPointBuilder.build(DefaultResourceTypeMeta.java:1126)
	at com.inductiveautomation.ignition.alarming.notification.AlarmNotificationManagerImpl.createAlarmNotificationMeta(AlarmNotificationManagerImpl.java:46)
	at com.inductiveautomation.ignition.alarming.notification.AbstractNotificationManager.<init>(AbstractNotificationManager.java:47)
	at com.inductiveautomation.ignition.alarming.notification.AlarmNotificationManagerImpl.<init>(AlarmNotificationManagerImpl.java:18)
	at com.inductiveautomation.ignition.alarming.AlarmNotificationGatewayHook.createNotificationManager(AlarmNotificationGatewayHook.java:95)
	at com.inductiveautomation.ignition.alarming.AlarmNotificationGatewayHook.setup(AlarmNotificationGatewayHook.java:102)
	at com.inductiveautomation.ignition.gateway.modules.ModuleInstance.setup(ModuleInstance.java:676)
	at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.runStartupPhase(ModuleManagerImpl.java:499)
	at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.setup(ModuleManagerImpl.java:441)
	at com.inductiveautomation.ignition.gateway.IgnitionGateway.startupInternal(IgnitionGateway.java:1211)
	at com.inductiveautomation.ignition.gateway.redundancy.RedundancyManagerImpl.startup(RedundancyManagerImpl.java:352)
	at com.inductiveautomation.ignition.gateway.IgnitionGateway.initRedundancy(IgnitionGateway.java:787)
	at com.inductiveautomation.ignition.gateway.IgnitionGateway.lambda$initInternal$1(IgnitionGateway.java:712)
	at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$ThrowableCatchingRunnable.run(BasicExecutionEngine.java:550)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: com.inductiveautomation.ignition.common.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 4 path $
	at com.inductiveautomation.ignition.common.gson.stream.JsonReader.syntaxError(JsonReader.java:1659)
	at com.inductiveautomation.ignition.common.gson.stream.JsonReader.checkLenient(JsonReader.java:1465)
	at com.inductiveautomation.ignition.common.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1416)
	at com.inductiveautomation.ignition.common.gson.stream.JsonReader.doPeek(JsonReader.java:547)
	at com.inductiveautomation.ignition.common.gson.stream.JsonReader.peek(JsonReader.java:433)
	at com.inductiveautomation.ignition.common.gson.JsonParser.parseReader(JsonParser.java:71)
	at com.inductiveautomation.ignition.common.gson.JsonParser.parseString(JsonParser.java:51)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.parseLenient(SchemaUtil.java:420)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.lambda$addJsonSchemaMetadata$7(SchemaUtil.java:296)
	at java.base/java.util.Optional.map(Unknown Source)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.addJsonSchemaMetadata(SchemaUtil.java:296)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.fromTypeInternal(SchemaUtil.java:239)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.fromType(SchemaUtil.java:196)
	at com.inductiveautomation.ignition.gateway.dataroutes.openapi.SchemaUtil.fromType(SchemaUtil.java:180)
	at java.base/java.util.Optional.map(Unknown Source)
	at com.inductiveautomation.ignition.gateway.config.ExtensionPoint.settingsSchema(ExtensionPoint.java:126)
	at com.inductiveautomation.ignition.gateway.config.DefaultResourceRouteDelegate$ExtensionPointBuilder.lambda$buildConfigSchema$3(DefaultResourceRouteDelegate.java:510)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.toArray(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.toList(Unknown Source)
	at com.inductiveautomation.ignition.gateway.config.DefaultResourceRouteDelegate$ExtensionPointBuilder.buildConfigSchema(DefaultResourceRouteDelegate.java:513)
	at com.inductiveautomation.ignition.gateway.config.DefaultResourceRouteDelegate$ExtensionPointBuilder.build(DefaultResourceRouteDelegate.java:545)
	at com.inductiveautomation.ignition.gateway.config.DefaultResourceTypeMeta$ExtensionPointBuilder.build(DefaultResourceTypeMeta.java:1126)
	at com.inductiveautomation.ignition.alarming.notification.AlarmNotificationManagerImpl.createAlarmNotificationMeta(AlarmNotificationManagerImpl.java:46)
	at com.inductiveautomation.ignition.alarming.notification.AbstractNotificationManager.<init>(AbstractNotificationManager.java:47)
	at com.inductiveautomation.ignition.alarming.notification.AlarmNotificationManagerImpl.<init>(AlarmNotificationManagerImpl.java:18)
	at com.inductiveautomation.ignition.alarming.AlarmNotificationGatewayHook.createNotificationManager(AlarmNotificationGatewayHook.java:95)
	at com.inductiveautomation.ignition.alarming.AlarmNotificationGatewayHook.setup(AlarmNotificationGatewayHook.java:102)
	at com.inductiveautomation.ignition.gateway.modules.ModuleInstance.setup(ModuleInstance.java:676)
	at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.runStartupPhase(ModuleManagerImpl.java:499)
	at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.setup(ModuleManagerImpl.java:441)
	at com.inductiveautomation.ignition.gateway.IgnitionGateway.startupInternal(IgnitionGateway.java:1211)
	at com.inductiveautomation.ignition.gateway.redundancy.RedundancyManagerImpl.startup(RedundancyManagerImpl.java:352)
	at com.inductiveautomation.ignition.gateway.IgnitionGateway.initRedundancy(IgnitionGateway.java:787)
	at com.inductiveautomation.ignition.gateway.IgnitionGateway.lambda$initInternal$1(IgnitionGateway.java:712)
	at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$ThrowableCatchingRunnable.run(BasicExecutionEngine.java:550)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Ignition version: Dev
Java version: Or

The value you're supplying with the DefaultValue or DefaultValueKey annotation is not well formed JSON:

        // Add Default Value
        Optional.ofNullable(field.getAnnotation(DefaultValue.class))
            .map(DefaultValue::value)
            .or(() ->
                Optional.ofNullable(field.getAnnotation(DefaultValueKey.class))
                    .map(DefaultValueKey::value)
                    .map(BundleUtil::i18n))
            .map(string -> parseLenient(fieldType, string))
            .ifPresent(fieldSchema::defaultValue);

Thanks, I was suspected some "illegal" annotation but I have not comment all the suspected annotation.

Now it's ok, removing those, I will confirm my @Description is malformed


//        @DefaultValue("sI/7ewBCeWunDs6JXXtSHg==")
        @DefaultValue("")
//        @Description("Must be encoded. For example : use \"sI/7ewBCeWunDs6JXXtSHg==\" for \"password\"")
        @Description("")

//        @DefaultValue("http://192.168.1.1/cgi")
        @DefaultValue("")


oops I miss one field was FormFieldType.SECRET

@FormField(FormFieldType.SECRET)
@DefaultValue("")
SecretConfig routerPassword,

That's the DefaultValue "sI/7ewBCeWunDs6JXXtSHg==" that cause the exception.

@paul-griffith can we put a default string password value ? we need to encode it ?

@DefaultValue("\"sI/7ewBCeWunDs6JXXtSHg==\"")

Might work, to make it a valid JSON string.

strange ?

        @FormCategory("Settings")
        @FormField(FormFieldType.SECRET)
        @Label("RouterPassword")
        @Required
        @DefaultValue("sI/7ewBCeWunDs6JXXtSHg==")
        @Description("Must be encoded. For example : use sI/7ewBCeWunDs6JXXtSHg== for password")
        SecretConfig routerPassword,

trigger the exception

        @FormCategory("Settings")
        @FormField(FormFieldType.SECRET)
        @Label("RouterPassword")
        @Required
        @DefaultValue("123456")
        @Description("Must be encoded. For example : use sI/7ewBCeWunDs6JXXtSHg== for password")
        SecretConfig routerPassword,

is OK

despide seems not to be a default password:

Nevermid, default password is definitely not a good practice

Whatever you specify for DefaultValue (if your field's type is not String) is getting parsed to JSON.
JSON doesn't support unquoted strings, but a numeric literal is valid JSON, so it makes sense to me that 123456 works but your b64 string didn't.

1 Like

Ok I see.