Getting static web context resources to work on both bookmarkable and non-bookmarkable Wicket pages

StackOverflow https://stackoverflow.com/questions/10993336

Question

In a Wicket 1.4 app, I have some static CSS & JS resources under [project root]/WebContent/css and [project root]/WebContent/js respectively.

enter image description here

My Wicket HTML files are in src/resources/fi/company/product/pages with corresponding Java classes in src/main/fi/company/product/pages. (In the resulting WAR file, the HTML & property files are of course in the same places as Java classes.)

The HTML files contain references to the resources such as:

<head>
    <link rel="stylesheet" type="text/css" href="css/main.css"/>
    <script type="text/javascript" src="js/calendar.js"></script>
</head>

This works fine everywhere (or so we thought until recently). NB: my Java code does not reference these resources at all.

Looking at the source of a rendered page (whose URL is e.g. http://localhost:8080/report/42.4 or http://localhost:8080/?wicket:interface=:6:::: ), the resource reference appears as:

<link rel="stylesheet" type="text/css" href="../css/main.css"/> 

However, we just noticed that when the app is deployed somewhere else than (Tomcat) root, the resources break on non-bookmarkable pages.

In other words, when the URL is e.g.

http://localhost:8080/foobar/?wicket:interface=:2::::

and a page refers to

<link rel="stylesheet" type="text/css" href="../css/main.css"/>

...the browser tries to fetch the resource at the invalid URL

http://localhost:8080/css/main.css

Now, what is the simplest (yet non-hacky) way to get these static resources working, regarless of the deployment path?

I could switch to using bookmarkable pages exclusively (which would require changing the constructors of the pages), but I suppose that shouldn't be necessary...


Edit: Looks like I got CSS resources working (on most places) simply by using <wicket:link>, as advised in this answer:

<head>
    <wicket:link>
    <link rel="stylesheet" type="text/css" href="css/main.css"/>
    </wicket:link>
</head>

However, now the CSS references are broken on a page with an URL like http://localhost:8080/foobar/report/42.9

Wicket is trying to do something strange with the "css/main.css" path:

ERROR org.apache.wicket.RequestCycle - Can't instantiate page using constructor public fi.company.product.pages.ReportPage(org.apache.wicket.PageParameters) and argument 0 = "css" 1 = "main"
org.apache.wicket.WicketRuntimeException: Can't instantiate page using constructor public fi.company.product.pages.ReportPage(org.apache.wicket.PageParameters) and argument 0 = "css" 1 = "main"
    at org.apache.wicket.session.DefaultPageFactory.createPage(DefaultPageFactory.java:212)
    at org.apache.wicket.session.DefaultPageFactory.newPage(DefaultPageFactory.java:89)
    at org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.newPage(BookmarkablePageRequestTarget.java:305)

Edit 2: Actually I'm not sure if <wicket:link> is the right solution here, since these resource files are not "class path resources". I guess my question is, can you make this work while still using web context resources (i.e., without making these class path resources)?

Was it helpful?

Solution

Right, I solved it, and the solution turned out to be very surprising.

Earlier I wrote:

A curious thing is that without any changes, it seems I can no longer reproduce the problem...

That wasn't quite true, as I had made one small change (that I thought was inconsequential): I had deleted a file WebContent/index.jsp which in our project was a remnant that served no purpose.

Once it dawned on me that this could have fixed it, I did some more testing, and indeed:

For static resources to work as expected, you must not have an index.html or index.jsp file in the root web content directory (i.e., the parent of the CSS and JS resource dirs), as that in some cases breaks ../ references.

This probably isn't even Wicket-specific, but perhaps it is Tomcat-specific—if anyone knows more, feel free to chime in. I'm dubious whether this question ever helps anyone else, but still, glad I got it working!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top