Changes in DD4T 2.1 for Java

Version 2.1 of DD4T has seen many improvements and changes with respect to the DD4T 2.0.X branch. While most changes are compatible with 2.0.X, it is recommended to upgrade your web application to the 2.1.X version. The main reason is that the 2.0.X releases will be discontinued and active development on it has stopped. Additionally, new versions of the DD4T Template Building Blocks may push new data formats or properties to the front end and these will only be incorporated in the DD4T 2.1 branch. New implementations are further encouraged to use the latest version, even if you already have published DD4T 1.0 XML or DD4T 2.0.X / 2.1.X Json in your Broker database, in order make use of the latest support for libraries, Tridion and fixed issues.

While numerous bugs and performance issues have been fixed in this release, a number of changes stand out and deserve a mention. A highlights reel follows below.

DD4T 1.0 XML compatibility

It is now possible to simultaneously serve DD4T 1.0 XML and DD4T 2.0.X / 2.1.X / 2.2.X Json from within the same web application. This comes in handy when you are upgrading your web app but are not in a position to republish all your content in one go. To enable this functionality, simply add the dd4t-compatibility dependency and make some changes in your Spring configuration:

<bean id="dd4t1Databinder" class="org.dd4t.databind.DefaultSerializer" />

<bean id="componentPresentationFactory" class="org.dd4t.core.factories.impl.ComponentPresentationFactoryImpl">
    <!-- removed other properties for brevity --> 
    <property name="dataBinders">
            <ref bean="dataBinder"/>
            <ref bean="dd4t1Databinder" />

<bean id="pageFactory" class="org.dd4t.core.factories.impl.PageFactoryImpl">
    <property name="dataBinders">
            <ref bean="dataBinder"/>
            <ref bean="dd4t1Databinder" />

With the configuration above, the framework determines whichever data format is requested and will use the right deserializer to process the data.

CacheProvider rework and EHCache 3.X.0

Caching and cache invalidation is hard. While the previous implementation for EHCache 2.8 was working fine, it had some limitations and quirks. Since Web 8.5 is making use of EHCache version 3, which was a complete overhaul and new namespace for the EHCache team as well, we created a separate EHCache3Provider intended to work with Web 8.5 and thereby preventing dependency collisions. In the Web 8.5 archetype this is now the default cache provider. DD4T now also adheres to the caching.enabled property in, so the full Spring configuration change looks like this:

<bean id="cacheProvider" class="org.dd4t.caching.providers.EHCache3Provider">
    <property name="enabled" value="${cache.enabled}" />

In addition, everything to do with caching moved to it’s own module and namespace (org.dd4t.caching), in order to keep things a bit more maintainable.

EHCache 3.X comes with a new XML configuration file. As can be seen, it is possible to also offload caches to disk. This is made possible because the entire DD4T content model now implements the Serializable interface as is mentioned below.

ViewModels link resolving

By popular demand, it is now possible to annotate properties in your view models to get a resolved link to the underlying Component. It is also possible to get a resolved link to a ComponentLink field in your parent component. If the ComponentLink field in your main component is actually a Multimedia link, it will attempt to get the Url property in the linked values of the Multimedia Component.

To get a resolved link for the parent component, simply declare a field in your model class with the following annotation:

// You can choose any name for the property
@ViewModelProperty(isComponentLinkUrl = true)
private String urlForThisComponent;

To get a resolved link to a Component link or Multimedia link field in your view model, do the following:

// MM link
@ViewModelProperty (entityFieldName = “multimedialink”, resolveLinkForComponentLinkField = true)
private String multimediaUrl;

// CL
@ViewModelProperty(entityFieldName = “componentlink”, resolveLinkForComponentLinkField = true)
private String componentLinkUrl;

Note that you can still get the actual values from the linked components at the same time.

Web 8.5 support and dependency overhaul

DD4T is now built against the 8.5 dependencies which are stored in Maven Central. Since most (if not all) required dependencies are now freely available, we took the opportunity to overhaul our own POM files to have a bit more rational dependency layout.

New archetypes

As a consequence of the dependency overhaul, we now have two archetypes to support both Tridion 20XX and Web 8:

Web 8:
mvn archetype:generate -DgroupId=com.example -DartifactId=testapp -DarchetypeGroupId=org.dd4t -DarchetypeArtifactId=dd4t-web8-archetype -DarchetypeVersion=1.1 -DarchetypeCatalog=remote
Tridion 2011 / 2013:
mvn archetype:generate -DgroupId=com.example -DartifactId=testapp8 -DarchetypeGroupId=org.dd4t -DarchetypeArtifactId=dd4t-spring-mvc-archetype -DarchetypeVersion=1.6 -DarchetypeCatalog=remote

Data serialization and deserialization

The JSon variant of the DD4T Content Model is now fully serializable again after it has been deserialized. This comes in handy if you want to store data somewhere else or want to pre process it. Since the content model now also implements the Serializable interface, it is now also possible to configure off-heap caches without losing information of the models currently in cache.

Finally, care is taken to keep increasing the quality of the code base. While not perfect, SonarQube is of the opinion that we’re still doing an OK job:

A full list of resolved issues can be found here. As always, we’re always looking for people to help out making DD4T better, so make sure to contact the team for questions, contributions or otherwise.

Happy DD4Ting!

About Raimond Kempees

Raimond Kempees is an independent CMS consultant and has for the past 10 years been involved in many fast-paced web projects all over the world, specializing among others in the SDL Tridion platform and building integrations on just about any development platform known to man.