If you have auto-linked auto components that point to package resource, like:
defined in the grandparent markup, where the grandparent and parent are from different packages, then they do get rendered correctly.
Problem is this: AutoLinkResolver checks that the package resource actually exists. It checks by creating a PackageResourceReference and attempts to get the reference from that. The class used as the context for the PackageResourceReference is the class which owns the markup in which the auto-link appeared. The key is the original reference (href or src) in the tag. So far everything is correct.
Wicket knows which class owned the markup by using ComponentTag#getMarkupClass(). It is therefore important that ComponentTag#getMarkupClass() always returns the correct class. But it doesn't.
When we have a three level merged markup (child, parent, grandparent), this happens: parent markup is merged into grandparent using MergedMarkup. All ComponentTags that were originally from grandparent are called :#setMarkupClass(GrandParent.class), so that they will know they came from the grandparent. So far so good.
Now, in order to get the child markup stream, we merge child markup onto the parent markup. Now, all ComponentTags in the parent markup are setMarkupClass(Parent.class). Problem is, this is not true. Some of these ComponentTags actually came from the grandparent, so the ComponentTag ends up returning the incorrect class (Parent.class instead of GrandParent.class) in #getMarkupClass().
Because ComponentTag#getMarkupClass() can return the wrong value, if the Parent and GrandParent are in different packages, then a resource that would be loadable by the grandparent is no longer loadable, because we are using the parent, which cannot find it.
Solution, fix MergedMarkup to only setMarkupClass() if getMarkupClass() == null.