The last couple of months, at Xenit we've been working hard to get Dynamic Extensions up and running on Alfresco 6.0 and 6.1. Alfresco's Spring Global Virtual Hack-a-thon was the perfect opportunity to step up our game and kick off the final sprint towards a Dynamic Extensions 2.0 release.
what dynamic EXTENSIONs is and how developers will benefit from it
Let's take a step back first and have a look at what the Dynamic Extensions (DE) Alfresco integration actually is.
In a standard Alfresco environment, a server restart is required to install Alfresco Platform extensions. The traditional way of building Alfresco Platform extensions includes a considerable amount of configuration boilerplate. When building an Alfresco extension, a developer generally spends time in two major sprints: building the extension - solving your actual problem - () and getting the extension registered and configured correctly - writing piles of error prone XML and restarting Alfresco a bunch of times in the process.
In general, developing an Alfresco extension points involves:
- Write some code that solves your problem - with nice unit tests;
- Wire it all together with (error-prone) XML: Spring beans configuration, webscript descriptors, share-custom-config.xml,- those are all non-trivial to test in isolation;
- Shut down Alfresco, deploy your module, restart Alfresco;
- Wait for more than 60 seconds;
- Repeat step 2. to 4. until you fixed all your problems in the xml configs (so Alfresco actually starts up) and tested your extension.
Dynamic Extensions aims to improve on the status-quo, by enhancing the Alfresco platform with two major capabilities:
- Annotation-based building of Alfresco extensions: DE minimizes the configuration boilerplate by providing an annotation-based API to build Alfresco extensions. This means you can effectively build Alfresco extensions, like custom actions, webscripts, policies by only adding some annotations and without any additional xml configuration. Everything is in code, which brings additional value like type safety and testability.
- Live deployment and redeployment of Alfresco DE modules: because DE is built with OSGi technology, every Dynamic-Extension-based module has its own class-loader. This means it can be installed, uninstalled and reinstalled on a running Alfresco! This is ideal for quick development iterations!
If you have already built Alfresco extensions before, those two capabilities should certainly interest you. With Dynamic Extensions, you should be able to focus on your solution more and significantly reduce the time spent writing and debugging configurations. During developer iterations, developers don't need to restart their Alfresco server over and over again. Instead they can just redeploy the new version of their module onto the already running Alfresco.
With Dynamic Extensions. a developer needs to:
- Write some code that solves your problem - with nice unit tests (basically unchanged);
- Use DE-provided annotations to safely wire it all together (below few examples)
- Hot deploy your module (no Alfresco restart required) - you DON’T need to wait 60+ seconds for a restart, a module is installed sub-second;
- Quickly iterate on your solution.
What developers need to know
1. Enabling Spring annotations processing and providing annotations for Alfresco's extensions points
Dynamic Extensions enables Spring's annotation-based configuration, which means we don't need to dive into XML anymore. Additionally, Dynamic Extensions introduces its own set of annotations, exposing the main Alfresco extension points: webscript, actions, workflows, scheduled job and so on. You can use this annotation-based API to automatically wire up Alfresco extensions to the official extension points.
For example, creating a Java-backed web script, can be as easy as adding the @WebScript and @Uri("/api") annotations to a Java class. There is no Spring XML module-context configuration to register your class as a bean. There is no webscript descriptor xml to register your webscript and maps the URL.
2. Adding an OSGi container to the Alfresco Platform
Dynamic Extensions leverages OSGi to provide isolation between DE-based Alfresco extension modules - called bundles in OSGi terminology - that actually provides the hot-deploy functionality.
OSGi is a framework for Java in which units of resources called bundles can be installed. Bundles can export services or run processes, and have their dependencies managed, such that a bundle can be expected to have its requirements managed by the container. Each bundle can also have its own internal class-path, so that it can serve as an independent unit, should that be desirable. All of this is standardized such that any valid OSGi bundle can theoretically be installed in any valid OSGi container (Source: OSGi for beginners).
For developers of custom Dynamic Extensions modules, knowledge of the OSGi specifications and the OSGi framework is not a requirement. What they do need to know is that DE modules are OSGi bundles and they need a few directions in the MANIFEST.MF to work. If you use the Dynamic Extensions Gradle plugin, that is all taken care of.
about dynamic extensions 2.0
Dynamic Extensions is around for quite some time and has already proven its worth during the years. So why did we need Dynamic Extensions 2.0?
Short answer: Alfresco 6 support and an improved Gradle plugin.
Long answer: although it may look like Alfresco hasn’t changed that much in Alfresco 6, there were some important upgrades under the hood. The switch from Spring 3 to Spring 5 probably had the most impact for Dynamic Extensions. What we needed was an integration that is compatible with Alfresco 5 (Spring 3) and Alfresco 6 (Spring 5) which could be transparently used by developers. To accomplish this, Dynamic Extensions offers developers a common API that can be used to build modules. On the other hand, Dynamic Extensions 2.0 has different run-time artifacts in which is taken care of the fundamental changes between different Alfresco versions. The major challenge for Dynamic Extensions 2.0, was building this different run-time environments and making sure this all is completely transparent for developers of Dynamic Extensions modules.
To make sure all the amazing Dynamic Extensions functionalities actually work on the different Alfresco versions, we invested time in an integration testing setup which actually starts the supported Alfresco versions with Dynamic Extensions installed.
The Dynamic Extensions Gradle plugin needed some love, and got it! Since version 2.0, we removed the inclusion of some transitive dependencies which put a lot of - unwanted - dependencies on the compile class-path when using the plugin. Furthermore the install-Bundle task has been internally updated. With this task it is possible to upload (a new version of) a bundle onto a running Alfresco from the command line, speeding up your development productivity even more.
Last but not least, we converted a lot of the Dynamic Extensions code from Kotlin to Java. The idea is that this will make it easier to understand, debug and contribute to the Dynamic Extensions framework!
Needless to say: many thanks to all the contributors who had their part in this milestone for the Dynamic Extensions Alfresco integration!