Fork me on GitHub

Upgrade guide

Sometimes (and hopefully not too often) we have to introduce breaking changes into Ninja’s behavior. This document describes which steps are needed to upgrade your application to the latest Ninja version. Simply start with your current version and then work your way up to the top of the document.

to 6.8.2

Flyway has been updated to prior version 8.2.2. As mentioned in the Flyway documentation there is a small change with MySQL. Since the version 8.2.x, MySQL Driver is not included any more in Flyway distribution due to License. MariaDB will be used as fallback driver if no MySQL driver is present on the Classpath.

If you still want to use a MySQL with MySQL Driver, you have to add new dependencies on your project.


to 6.7.0

JPA and Flyway have been migrated to a separate maven module. You can check the configuration inside

But in general you have to do the following:


Modify your Module java to start-up the database support:

public class Module extends AbstractModule {
    private final NinjaProperties ninjaProperties;
    public Module(NinjaProperties ninjaProperties) {
        this.ninjaProperties = ninjaProperties;
    protected void configure() { 
        install(new JpaModule(ninjaProperties));
        install(new MigrationClassicModule());

        // ... likely more modules...

to 6.6.0

  • Use ?no_enc instead of noescape. Due to changes in our html templating engine we changed the way how to render unescaped content. Make sure to use something like ${yourVariableThatShouldNotBeEscaped?no_esc} instead of <#noescape>${yourVariableThatShouldNotBeEscaped}</#noescape>.

to 6.3.X

Some inner methods of the Ninja base class have a new signature, with more precise exception types. If you overrided some of them, or if you implemented your own Ninja class without extending the NinjaDefault one, you should be able to fix them easily.

to 6.3.0

Postoffice is now a separate dependency. Make sure to add the dependency to your pom.xml file and add the module to See details in

to 6.0.1

FluentLenium update causes backward incompatibility

Refer to the FluentLenium migration guide or force usage of fluentlenium-core 0.10.3 in your project dependencies.

to 6.0.0

  • Java 8 is required.
  • Maven 3.3.9 is required.
  • Replace all usages of Guava’s Optional with Java8 Optional. Your compiler will guide you.

to 5.4.0

Guice bindings for template engines like Freemarker were modified to be bound differently than in previous versions. If you use a custom template engine via a third party module then it may need to be bound into Guice slightly different. This is how template engines typically were bound:

public class CustomTemplateEngineModule extends AbstractModule {
    protected void configure() {

This is how template engines need to be bound as of v5.4.0:

public class CustomTemplateEngineModule extends AbstractModule {
    protected void configure() {

to 3.3.0

Vastly improved conf.Ninja

Results you now generate can be customized and are usging content-negotiation. A json request will get a json error message. Html request will get an html error message. Please have a look at interface ninja.Ninja and ninja.NinjaDefault. They show how the improved approach works.

to 3.2.0

i18n handling in templates has changed.

Let’s say you used $i18n{“my.message.key”} and your was missing a value for key “my.message.key”. Before that version the template would not render but throw an exception instead. From now on this behavior is relaxed and the key itself will be rendered instead (+ a logged error message). In the case above you’ll find “my.message.key” inside the rendered template.

to 3.0.0

Session and Flash scopes

SessionCookie and FlashCookie changed their names. SessionCookie is now called Session and FlashCookie is called FlashScope.

Context object reflects this by providing getSession() and getFlashScope() methods.

Changes in serving of static assets

AssetsController’s serve method has been deprecated for good. The replacement are AssetsController’s serveStatic and serveWebJars methods.


router.GET().route("/assets/.*").with(AssetsController.class, "serve");

NEW (direct replacement):

router.GET().route("/assets/webjars/{fileName: .*}").with(AssetsController.class, "serveWebJars");
router.GET().route("/assets/{fileName: .*}").with(AssetsController.class, "serveStatic");

This also means that you can now serve static assets from arbitrary directories or even files from root like:

router.GET().route("/robots.txt").with(AssetsController.class, "serveStatic");

to 2.4.0

  • Ninja now uses “ninja.mode=prod” by default (and no longer dev). Many users complained that it is quite strange to configure the prod mode when running Ninja as war inside a servlet container. Therefore Ninja assumes now mode prod by default.

The downside of this is that you have to set the mode for dev now manually if you need it. Ninja’s SuperDevMode handles this for you and you can simply use “mvn ninja:run” to start Ninja in dev mode.

But if you are using e.g. Jetty’s maven plugin you have to set the system property like that:


The archetypes are already equipped with the new versions.

to 2.3.0

  • File naming convention for message files have changed. Previously it was or Now it is or Please rename them in your application and you are ready to go.

This change allows you to use a lot more i18n translation tools than before. For instance IntelliJ and Netbeans now automatically detect the files as i18n files and help you with translating them efficiently.

From 1.6 to 2.0.0

1) Ninja’s testing artifacts have changed. Please rename the original ninja-core-test to ninja-test-utilities in your pom.xml. You end up with the following artifact:


2) We have improved the default way xml is rendered and parsed and are now using “module.setDefaultUseWrapper(false)” of Jackson that produces output more similar to the Json renderers. This handles rendering lists and collections in a much better way. You can change that via annotation @JacksonXmlElementWrapper.useWrapping in your models Also see: the

From 1.5.1 to 1.6

Please change any ftl.html accesses of the flash cookie from underscore syntax into “.” syntax. ${flash_error} becomes ${flash.error}. ${flash_success} becomes ${flash.success}. ${flash_anyMessage} becomes ${flash.anyMessage}. This is now much more consistent with the general way we access stuff inside any ftl.html file.

From 1.4 to 1.5.1

If you are using Results.redirectTemporary(…) / Results.redirect(…) or Results.noContent() AND if you are using a http body to indicate something (like a hyperlink text) you have to set result.render(null) to remove the NoHttpResult. Otherwise nothing will change for you. You simply don’t need a html template by default any more.

From 1.3 to 1.4

Improvements in i18n. You can now use the following snipplet to include i18n into your templates: ${i18n(“myMessageKey”)}. Using ${i18nMyMessageKey} will be deprecated soon. Don’t use it.

With the new i18n facilities you can now also format your messages with variables of your template:

${i18n(“myMessageKey”, myVariable)}.

From 1.2 to 1.3

In your project’s pom.xml please replace artifactId ninja-core with ninja-servlet. You end up with the following dependency:


From 1.1 to 1.2

  • Please use “ninja.Messages” instead of “ninja.Lang” for getting messages.
  • Your web.xml must be adapted and should resemble:
<web-app xmlns=""





From 1.0 to 1.1

no changes needed.