Skip to content
Rapid development of Alfresco repository extensions in Java. Deploy your code in seconds, not minutes. Life is too short for endless server restarts.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github release 1.7.4 Mar 8, 2018
alfresco-bom-repo/eu/xenit/alfresco/alfresco-community-bom Update alfresco-bom repo & use enforcedPlatform for BOM dependencies May 20, 2019
alfresco-dynamic-extensions-repo Re-enable publishing of the Gradle plugin to the Maven repository May 20, 2019
alfresco-integration Update alfresco-bom repo & use enforcedPlatform for BOM dependencies May 20, 2019
annotations-runtime Update alfresco-bom repo & use enforcedPlatform for BOM dependencies May 20, 2019
annotations Update alfresco-bom repo & use enforcedPlatform for BOM dependencies May 20, 2019
blueprint-integration Update alfresco-bom repo & use enforcedPlatform for BOM dependencies May 20, 2019
blueprint-override Use Gradle 5.4.1 May 9, 2019
buildSrc/src/main/java/eu/xenit/dynamicextensionsalfresco Include Alfresco 61 support Apr 26, 2019
control-panel Update alfresco-bom repo & use enforcedPlatform for BOM dependencies May 20, 2019
documentation Update links to example-de project May 27, 2019
event-bus Partialy move from Osgi to Bnd plugin May 9, 2019
gradle-plugin
gradle/wrapper Use Gradle 5.4.1 May 9, 2019
integration-tests Use HttpMethod.POST for the /OnCreateNodePolicy test endpoint May 27, 2019
webscripts Update alfresco-bom repo & use enforcedPlatform for BOM dependencies May 20, 2019
.gitignore Force include gradlew.bat Jun 28, 2018
.travis.yml Adapt travis.yml and Jenkinsfile to working with release branch May 20, 2019
CHANGELOG.md Prepare for 2.0.2 development cycle May 21, 2019
Jenkinsfile Another try in fixing the signing and publishing of artifacts May 20, 2019
LICENSE rename base package Jan 12, 2014
README.md Include License and Maven Central badges in README May 22, 2019
build.gradle Prepare for 2.0.2 development cycle May 21, 2019
gradle.properties Remove kotlin dependencies Apr 18, 2019
gradlew Upgrade to gradle 4.8.1 Jun 28, 2018
gradlew.bat Use Gradle 5.4.1 May 9, 2019
publish.gradle Another try in fixing the signing and publishing of artifacts May 20, 2019
settings.gradle Include integration tests to reproduce #263 May 23, 2019

README.md

Dynamic Extensions for Alfresco

Apache License 2 Build Status Maven Central

Add OSGi based hot-deploy functionality and Spring annotation based configuration to Alfresco.

Introduction

Rapid development of Alfresco repository extensions in Java. Deploy your code in seconds, not minutes. Life is too short for endless server restarts.

Dynamic Extensions adds an OSGi container to the Alfresco repository, enabling live deployment of Java code, with no need to restart the server. Alfresco itself is not "OSGi-fied" in any way; the OSGi container runs on top of the core Alfresco platform.

Standard Alfresco Platform Extensions use Spring XML based configuration. With Dynamic Extensions, developers have the ability to create Alfresco Platform Extensions using Spring's annotations based configuration.

Installing Dynamic Extensions in Alfresco

Dynamic Extensions (DE) is distributed as an Alfresco Module Package (AMP) extension that can be installed in Alfresco.

Installing the Dynamic Extensions AMP

To support multiple Alfresco versions, different AMPs for each minor Alfresco version update are build and distributed.
E.g. if you are working with Alfresco 6.0.7-ga, you should use the alfresco-dynamic-extensions-repo-60 artifact.

Maven Central Coordinates

All required artifacts, including the AMP to be installed in Alfresco, are available in Maven Central.

<dependency>
    <groupId>eu.xenit</groupId>
    <artifactId>alfresco-dynamic-extensions-repo-${alfresco-version}</artifactId>
    <version>${latest-dynamic-extensions-version}</version>
    <type>amp</type>
</dependency>
alfrescoAmp "eu.xenit:alfresco-dynamic-extensions-repo-${alfrescoVersion}:${dynamicExtensionsVersion}@amp"

These artifacts can be used to automatically install Dynamic Extensions in Alfresco using e.g. the Alfresco Maven SDK or the Alfresco Docker Gradle Plugins

Manual download and install

Supported Alfresco versions

Dynamic Extensions is systematically integration-tested against:

  • Alfresco Enterprise 6.1
  • Alfresco Community 6.1
  • Alfresco Enterprise 6.0
  • Alfresco Community 6.0
  • Alfresco Enterprise 5.2
  • Alfresco Enterprise 5.1
  • Alfresco Enterprise 5.0

Known Alfresco issues that impact Dynamic Extensions

Alfresco 6.1 - wrong version of 'Commons annotations' usedWhen using DE on Alfresco 6.1, it is possible that it fails to startup due to following error:
Caused by: java.lang.NoSuchMethodError: javax.annotation.Resource.lookup()Ljava/lang/String;
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.<init>(CommonAnnotationBeanPostProcessor.java:621)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.lambda$buildResourceMetadata$0(CommonAnnotationBeanPostProcessor.java:383)
at org.springframework.util.ReflectionUtils.doWithLocalFields(ReflectionUtils.java:719)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.buildResourceMetadata(CommonAnnotationBeanPostProcessor.java:365)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.findResourceMetadata(CommonAnnotationBeanPostProcessor.java:350)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(CommonAnnotationBeanPostProcessor.java:298)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1044)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:550)

The root cause is for this problem is that Alfresco has multiple implementations of the JSR 250 specification, 'Common Annotations' in the WEB-INF/lib/ folder:

  1. javax.annotation:javax.annotation-api
  2. javax.annotation:jsr250-api
  3. org.apache.geronimo.specs:geronimo-annotation_1.0_spec

Only the first one is up to date and contains the correct implementation of the Resource class. The other two versions contain an old implementation of the Resource class, causing the provided error to be thrown by Spring internally.

This is only an issue as of Java 11 (Alfresco 6.1) because earlier versions had an correct implementation of the Resource class embedded in the distribution, and the bootstrap classloader has the highest priority.

This issue has been reported to Alfresco: MNT-20557. Waiting for Alfresco to fix the issue, following workarounds can be used to make DE work on Alfresco 6.1:

  • Remove the jsr250-api and geronimo-annotation_1.0_spec jars from the WEB-INF/lib folder of the Alfresco webapp.
  • Install this hotfix AMP in your Alfresco distribution, which will overwrite the jsr250-api and geronimo-annotation_1.0_spec jars with empty jars.

Example Dynamic Extensions based Alfresco Platform extension

This example Web Script examines a node and passes information to a Freemarker template:

@Component
@WebScript
public ExampleWebScript {

  @Autowired
  private NodeService nodeService;

  @Uri("/show-node")
  // Example: http://localhost/alfresco/service/show-node?nodeRef=workspace://SpacesStore/12345
  public Map<String, Object> displayNodeName(@RequestParam NodeRef nodeRef) {
    Map<String, Object> model = new HashMap<String, Object>();
    model.put("properties", nodeService.getProperties(nodeRef));    
    return model; // Model is passed to Freemarker template.
  }
}

Note that this is an annotation Web Script. These types of Web Script are configured through Java annotations instead of *.desc.xml descriptors. Annotation Web Scripts are similar to Spring MVC's annotation-based controllers.

Here's the accompanying Freemarker template fragment:

<table>
  <#list properties?keys as name>    
    <tr>
      <th>${name}</th>
      <td>${properties[name]!''}</td>
    </tr>
  </#list>
</table>

This is all the code that is required; there's no need for Spring XML config or Web Script XML descriptors. Hot-reloading and reducing configuration overhead are not particularly novel concepts in the Java development world at large. Essentially, Dynamic Extensions modernizes the development of Alfresco repository extensions.

The example above may be trivial, but the point is that, behind the scenes, services are still wired together through Spring and handled by the Web Script framework. Conceptually there is no real difference between a Dynamic Extension and a regular Alfresco extension. There's just less overhead and more convenience.

Documentation

Please checkout the documentation for further instructions.

License

This project is licensed under the Apache V2 License - see the LICENSE file for details.

Useful links

You can’t perform that action at this time.