Extending from ConfigPanel: MissingResourceException

I am trying to create a simple config page for my module but I am running into what seem to be localization issues.

I am setting up the config panel similar to the “Home Connect” example.

I have the following code in my gateway hook:

[code] public static final ConfigCategory CONFIG_CATEGORY = new ConfigCategory(“lrs”, “LRS.nav.header”, 750);

@Override
public List<ConfigCategory> getConfigCategories() {
    return Collections.singletonList(CONFIG_CATEGORY);
}

public static final IConfigTab LRS_CONFIG_ENTRY = DefaultConfigTab.builder()
        .category(CONFIG_CATEGORY)
        .name("lrs_manager")
        .i18n("LRS.nav.settings.title")
        .page(LRSSettingsPage.class)
        .terms("LRS settings")
        .build();

@Override
public List<? extends IConfigTab> getConfigPanels() {
    return Arrays.asList(
            LRS_CONFIG_ENTRY
    );
}[/code]

And the following class LRSSettingsPage.java

[code]public class LRSSettingsPage extends ConfigPanel{

public LRSSettingsPage(final IConfigPage configPage) {
	
	super("LRSSettingsPage.lrsTitle", configPage, null);
	
}

}
[/code]

and the following properties files stored in maven’s default resources folder:

LRS.properties

nav.header=LRS Management nav.settings.title=Settings

LRSSettingsPage.properties

lrsTitle=My LRS Title

I am able to compile and build and package the module just fine however it seems the properties files are not being discovered properly. When I install the module the menu tab has question marks around it and displays the wrong string. Also, when attempting to open the config page the following error happens:

[code]org.apache.wicket.WicketRuntimeException: Exception in rendering component: [Component id = main-title]

at org.apache.wicket.Component.internalRenderComponent(Component.java:2562)

at org.apache.wicket.markup.html.WebComponent.onRender(WebComponent.java:56)

at org.apache.wicket.Component.internalRender(Component.java:2365)

at org.apache.wicket.Component.render(Component.java:2293)

at org.apache.wicket.MarkupContainer.renderNext(MarkupContainer.java:1388)

at org.apache.wicket.MarkupContainer.renderAll(MarkupContainer.java:1553)

at org.apache.wicket.MarkupContainer.renderComponentTagBody(MarkupContainer.java:1528)

at org.apache.wicket.MarkupContainer.renderAssociatedMarkup(MarkupContainer.java:685)

at org.apache.wicket.markup.html.panel.AssociatedMarkupSourcingStrategy.renderAssociatedMarkup(AssociatedMarkupSourcingStrategy.java:76)

at org.apache.wicket.markup.html.panel.PanelMarkupSourcingStrategy.onComponentTagBody(PanelMarkupSourcingStrategy.java:112)

at org.apache.wicket.Component.internalRenderComponent(Component.java:2535)

at org.apache.wicket.MarkupContainer.onRender(MarkupContainer.java:1491)

at org.apache.wicket.Component.internalRender(Component.java:2365)

at org.apache.wicket.Component.render(Component.java:2293)

at org.apache.wicket.MarkupContainer.renderNext(MarkupContainer.java:1388)

at org.apache.wicket.MarkupContainer.renderAll(MarkupContainer.java:1553)

at org.apache.wicket.MarkupContainer.renderComponentTagBody(MarkupContainer.java:1528)

at org.apache.wicket.MarkupContainer.onComponentTagBody(MarkupContainer.java:1482)

at org.apache.wicket.markup.html.panel.DefaultMarkupSourcingStrategy.onComponentTagBody(DefaultMarkupSourcingStrategy.java:71)

at org.apache.wicket.Component.internalRenderComponent(Component.java:2535)

at org.apache.wicket.MarkupContainer.onRender(MarkupContainer.java:1491)

at org.apache.wicket.Component.internalRender(Component.java:2365)

at org.apache.wicket.Component.render(Component.java:2293)

at org.apache.wicket.MarkupContainer.renderNext(MarkupContainer.java:1388)

at org.apache.wicket.MarkupContainer.renderAll(MarkupContainer.java:1553)

at org.apache.wicket.MarkupContainer.renderComponentTagBody(MarkupContainer.java:1528)

at org.apache.wicket.MarkupContainer.onComponentTagBody(MarkupContainer.java:1482)

at org.apache.wicket.markup.html.panel.DefaultMarkupSourcingStrategy.onComponentTagBody(DefaultMarkupSourcingStrategy.java:71)

at org.apache.wicket.Component.internalRenderComponent(Component.java:2535)

at org.apache.wicket.MarkupContainer.onRender(MarkupContainer.java:1491)

at org.apache.wicket.Component.internalRender(Component.java:2365)

at org.apache.wicket.Component.render(Component.java:2293)

at org.apache.wicket.MarkupContainer.renderNext(MarkupContainer.java:1388)

at org.apache.wicket.MarkupContainer.renderAll(MarkupContainer.java:1553)

at org.apache.wicket.Page.onRender(Page.java:884)

at org.apache.wicket.markup.html.WebPage.onRender(WebPage.java:142)

at org.apache.wicket.Component.internalRender(Component.java:2365)

at org.apache.wicket.Component.render(Component.java:2293)

at org.apache.wicket.Page.renderPage(Page.java:1021)

at org.apache.wicket.request.handler.render.WebPageRenderer.renderPage(WebPageRenderer.java:116)

at org.apache.wicket.request.handler.render.WebPageRenderer.respond(WebPageRenderer.java:244)

at org.apache.wicket.core.request.handler.RenderPageRequestHandler.respond(RenderPageRequestHandler.java:165)

at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:814)

at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:64)

at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:253)

at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:210)

at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:281)

at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:188)

at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:245)

at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668)

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)

at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1160)

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)

at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1092)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)

at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)

at org.eclipse.jetty.server.Server.handle(Server.java:518)

at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:308)

at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244)

at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)

at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)

at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)

at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:246)

at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:156)

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)

at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)

at java.lang.Thread.run(Thread.java:745)

Caused by: java.lang.RuntimeException: An error occurred while getting the model object for Component: [Component id = main-title, page = com.inductiveautomation.ignition.gateway.web.pages.Config, path = 139:config-contents:main-title.Label, isVisible = true, isVersioned = true, markup = [markup = jar:file:/C:/Program%20Files/Inductive%20Automation/Ignition/temp/gateway-api-7.9.07454527380445372076.jar!/com/inductiveautomation/ignition/gateway/web/components/ConfigPanel.html
, index = 0, current = ’
’ (line 0, column 0)]]

at org.apache.wicket.Component.getDefaultModelObject(Component.java:1620)

at org.apache.wicket.Component.getDefaultModelObjectAsString(Component.java:1643)

at org.apache.wicket.markup.html.basic.Label.onComponentTagBody(Label.java:113)

at org.apache.wicket.markup.html.panel.DefaultMarkupSourcingStrategy.onComponentTagBody(DefaultMarkupSourcingStrategy.java:71)

at org.apache.wicket.Component.internalRenderComponent(Component.java:2535)

… 71 common frames omitted

Caused by: java.util.MissingResourceException: Unable to find property: ‘LRSSettingsPage.lrsTitle’ for component: config-contents:main-title [class=com.inductiveautomation.ignition.gateway.web.components.ConfigPanel$2]. Locale: null, style: null

at org.apache.wicket.Localizer.getString(Localizer.java:237)

at org.apache.wicket.Localizer.getString(Localizer.java:149)

at org.apache.wicket.model.ResourceModel$AssignmentWrapper.load(ResourceModel.java:124)

at org.apache.wicket.model.ResourceModel$AssignmentWrapper.load(ResourceModel.java:94)

at org.apache.wicket.model.LoadableDetachableModel.getObject(LoadableDetachableModel.java:121)

at com.inductiveautomation.ignition.gateway.web.models.LateChainingModel.getObject(LateChainingModel.java:53)

at org.apache.wicket.Component.getDefaultModelObject(Component.java:1615)

… 75 common frames omitted[/code]

So it seems as though I am doing the localization wrong and maybe a few other things. How can I fix it so that a blank page will appear instead of an internal error (planning on editing the page after getting the page to actually load properly)?

LRS.properties needs to be loaded and unloaded by BundleUtil in your module’s GatewayHook.

LRSSettingsPage.properties does not need to be manually loaded, but you have to place it in a package structure that mirrors the one that the LRSSettingsPage class is in, so something like src/main/resources/com/foo/bar/LRSSettingsPage.properties

Thanks for your reply. Adding and removing the bundle seems to have made a slight improvement in the appearance of the menu tab title. However, I still get the same error when attempting to open the page.

My files are now organized in the following folders

class files: …\lrs\lrs-gateway\src\main\java\lrs
properties files: …\lrs\lrs-gateway\src\main\resources\lrs

Interestingly enough, two strings are stored in the LRS.properties file, yet only one is discovered.

Gatewayhook code added:

[code] public void setup(GatewayContext gatewayContext) {
BundleUtil.get().addBundle(“LRS”, getClass(), “LRS”);

}

public void shutdown() {

	 BundleUtil.get().removeBundle("LRS");

}

[/code]

I was mistaken about the settings page properties file - those keys should just be in the main LRS.properties file.

It’s settings records that are automatically loaded and must have a mirrored package structure (things that extend PersistentRecord).

If your bundle is being loaded correctly you should be able to reference the keys/values by at the path “LRS.path.to.key”, so:

LRS.nav.header
LRS.settings.title
LRS.lrsTitle

It works beautifully now, thanks!