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.
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.
Postoffice is now a separate dependency. Make sure to add the dependency to your pom.xml file and add the module to Modules.java. See details in http://www.ninjaframework.org/documentation/sending_mail.html
Refer to the FluentLenium migration guide http://fluentlenium.org/migration/from-0.13.2-to-1.0-or-3.0/ or force usage of fluentlenium-core 0.10.3 in your project dependencies.
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 { @Override protected void configure() { bind(TemplateEngine.class).to(CustomTemplateEngine.class); } }
This is how template engines need to be bound as of v5.4.0:
public class CustomTemplateEngineModule extends AbstractModule { @Override protected void configure() { bind(CustomTemplateEngine.class); } }
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.
Let’s say you used $i18n{“my.message.key”} and your messages.properties 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.
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.
AssetsController’s serve method has been deprecated for good. The replacement are AssetsController’s serveStatic and serveWebJars methods.
OLD:
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”);
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:
<plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> .... <systemProperties> <systemProperty> <name>ninja.mode</name> <value>dev</value> </systemProperty> </systemProperties> </configuration> </plugin>
The archetypes are already equipped with the new versions.
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.
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:
<dependency> <groupId>org.ninjaframework</groupId> <artifactId>ninja-test-utilities</artifactId> <version>X.X.X</version> <scope>test</scope> </dependency>
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 https://github.com/FasterXML/jackson-dataformat-xml
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.
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.
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)}.
In your project’s pom.xml please replace artifactId ninja-core with ninja-servlet. You end up with the following dependency:
<dependency> <groupId>org.ninjaframework</groupId> <artifactId>ninja-servlet</artifactId> <version>1.3</version> </dependency>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>ninja</display-name> <listener> <listener-class>ninja.servlet.NinjaServletListener</listener-class> </listener> <filter> <filter-name>guiceFilter</filter-name> <filter-class>com.google.inject.servlet.GuiceFilter</filter-class> </filter> <filter-mapping> <filter-name>guiceFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>