Search code examples
scalatomcatweb-applicationslift

cloudbees+lift application = broken navigation


I've been using Lift as the framework for a personal website, and in an effort to move the server off of my computer, I've turned to Cloudbees. I deployed my app to the cloud as a .war file and started browsing.

edit - Apparently this has nothing to do with Cloudbees. It's a Tomcat issue.

Locally, my app will serve localhost:8008/demos as the demos.html page. But on Cloudbees, [URL]/demos automatically redirects to [URL]/demos/ and gives a 404. If I visit [URL]/demos.html directly, it seems to work fine.

I would like to avoid the explicit ".html" suffix on my pages. How can I get this to work so that things behave the way they do when I run locally?


Solution

  • Alright, I've got this figured out, so I'm going to post my own answer for other peoples' future reference.

    The Problem

    Cloudbees uses Tomcat (not Jetty, which is what gets used with the sbt web plugin via container:start). As implied by Where does Tomcat append / to directory paths? Tomcat will append a / to paths that it thinks are directories.

    With an app structure like

    src/main/webapp
     - demos.html
     - demos
       - some-demo.html
    

    And a lift sitemap definition that included

    Menu.i("Demos") / "demos" submenus (
      Menu.i("Some Demo") / "demos" / "some-demo"
    )
    

    Tomcat was seeing the url "/demos" and seeing my "demos" folder, and assuming that my url was a mistake, adding the trailing slash.

    The Solution

    Work around the problem with a bit of rearrangement. First, move demos.html into the demos folder and rename it to index.html.

    src/main/webapp
     - demos
       - index.html (formerly demos.html)
       - some-demo.html
    

    Adjust the SiteMap to reflect this change

    Menu.i("Demos") / "demos" / "index" submenus (...)
                                ^ added an extra path step
    

    Now my auto-generated sitemap will point directly to /demos/ and Tomcat happily serves my demos/index.html file in that place.