2

I'm using Wicket 7 and I recently got the following exception:

org.apache.wicket.core.request.handler.ComponentNotFoundException:
Component 'navbar:navbarAvatar:navAvatarPanel:4:navAvatarArea:menuPanel:menuItem:menuLink' has been removed from page.

This error comes from my top navigation bar I built. The navigation bar has a sub-menu (navAvatarPanel) which contains additional menu links (menuLink). The links are added to an ArrayList and displayed within a ListView using a fragment.

Here's my code:

NavBarPanel.java

public class NavBarPanel extends Panel {
    public NavBarPanel(String id) {
        super(id);
        /* ... */

        WebMarkupContainer navBarAvatar = new WebMarkupContainer(NavbarAvatar$wicketId) {
            private static final long serialVersionUID = -2447768280463773678L;

            @Override
            public boolean isVisible() {
                return session.isSignedIn();
            }
        };

        List<Panel> avatarMenuItems = new ArrayList<Panel>();
        avatarMenuItems.add(new MenuLink(Logout$wicketId, "Logout", WelcomeWebPage.class, menuModel));
        /* adding additional links at this point ... */

        navBarAvatar.add(new ListView<Panel>("navAvatarPanel", avatarMenuItems) {
            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(ListItem<Panel> item) {
                final Panel panel = item.getModelObject();
                item.add(new MenuFragment(panel, "navAvatarArea"));
            }
        });

        this.add(navBarAvatar);
    }
}

public class MenuFragment extends Fragment {
    private static final long serialVersionUID = 5735397386662232792L;

    public MenuFragment(Panel panel, String area) {
        super(area, "menuFragment", NavBarPanel.this);

        add(panel);
    }
}

NavBarPanel.html

<wicket:panel>
    <!-- ... -->
    <div wicket:id="navbarAvatar" class="navbar-avatar">
        <ul>
            <wicket:container wicket:id="navAvatarPanel">
                <wicket:container wicket:id="navAvatarArea"/>
            </wicket:container>
        </ul>
    </div>
    <!-- ... -->
    <wicket:fragment wicket:id="menuFragment">
        <wicket:container wicket:id="menuPanel"></wicket:container>
    </wicket:fragment>
</wicket:panel>

MenuLink.java

public MenuLink(String markupId, String label, Class<? extends Page> page, MenuModel model) {
    super("menuPanel");
    this.markupId = markupId;
    this.page = page;
    this.model = model;
    this.initComponentTree(label);
}

private void initComponentTree(final String label) {
    WebMarkupContainer menuItem = new WebMarkupContainer("menuItem");

    Link<Void> menuLink = new Link<Void>("menuLink") {
        private static final long serialVersionUID = 1L;

        @Override
        public void onClick() {
            MenuLink.this.menuOnClick(label);
        }
    };

    menuLink.add(new Label("menuLabel", label));
    menuLink.setMarkupId(this.markupId);

    menuItem.add(menuLink);

    this.add(menuItem);
}

MenuLink.html

<wicket:panel>
    <li wicket:id="menuItem">
        <a wicket:id="menuLink">
            <span wicket:id="menuLabel">[label]</span>
        </a>
    </li>
</wicket:panel>

I have no idea where this error comes from. I also had no success finding some more information about this exception.

rockarolla
  • 135
  • 8

1 Answers1

1

My guess is that the http session has expired and the menu item cannot be found because the whole menu is not there due to isVisible = session.isSignedIn();.

If this is the case then Wicket should be improved to give a better exception message telling which Component exactly cannot be found, not the requested component path.

P.S. It is recommended to use onConfigure() {setVisible(...)} instead of overriding isVisible() because the latter is called several times during rendering and might be slower.

martin-g
  • 17,243
  • 2
  • 23
  • 35
  • If that's the case, wouldn't it be easy to reproduce the error by replacing 'isVisible = session.isSignedIn();' with 'isVisible = false;' or even preventing the error by replacing it with 'isVisible = true;'? But that's either not working/helping in my case. – rockarolla Feb 07 '18 at 11:35
  • Thanks for the onConfigure recommendation! – rockarolla Feb 07 '18 at 11:36
  • You need to render the page with the menu, then you need to change your code to `isVisible = false` and you need to update the bytecode without restarting the application, then click on a menu item and see what happens. – martin-g Feb 07 '18 at 12:42