Alfresco SDK 3.0 Beta - User Guide
Support for different versioning of Platform and Share UI
From Spring Loaded to JRebel or HotSwap
The end of Tomcat Virtual Webapp Context
Support for multiple Alfresco Versions
All-In-One (AIO) Project change
Generating from Maven Archetype
Using the Platform REST API Explorer
Hot reloading of Platform extensions
Basic Platform Web Script hot reloading
Reloading Web Resources (JRebel only)
Spring Context Reloading (JRebel only)
Hot reloading of Share extensions
Overriding Web Resources and Adding 3rd party Libraries (Using AMPs)
Using a custom context path for the Share webapp
Adding Custom Webapps when running
Adding Custom System Properties when running
Generating from Maven Archetype
Overriding Web Resources and Adding 3rd party Libraries (Using AMPs)
Adding Custom Webapps when running
Adding Custom System Properties when running
Generating from Maven Archetype
Overriding Web Resources and Adding 3rd party Libraries (Using AMPs)
Using a custom context path for the Share webapp
Adding Custom Webapps when running
Adding Custom System Properties when running
Generating from Maven Archetype
Updating the HelloWorld application
Upgrading previous SDK 2.2 projects to SDK 3
Alfresco SDK 3 is a major overhaul of the SDK and provides several improvements on previous SDKs.
The most significant change is that we now keep most of the build logic, run logic, and project configuration inside the Alfresco Maven Plugin. This means that the POMs will be a lot slimmer and they will also not depend on a parent SDK POM. This will make upgrades easier and you can now use your own Maven parent POM.
The plug-in now builds the project web applications as follows:
There are a couple of things we need to feed the plugin with, such as what version of the different WAR artifacts we want to use, database configuration, location of alf_data etc. This is still all done in the project POM properties section:
<properties>
<!-- Alfresco Maven Plugin version to use -->
<alfresco.sdk.version>3.0.0-SNAPSHOT</alfresco.sdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Alfresco Data directory, which will contain:
Content Store (i.e. the files we upload)
Database (i.e. the metadata for the uploaded files)
Search index (i.e. the indexed content and metadata)
Configured in alfresco-global.properties with the 'dir.root' property.
-->
<alfresco.data.location>${session.executionRootDirectory}/alf_data_dev
</alfresco.data.location>
<!-- Duplicated with alfresco.solrHome in the plugin,
we need them out here to do filtering -->
<solr.home>${alfresco.data.location}/solr</solr.home>
<solr.model.dir>${solr.home}/alfrescoModels</solr.model.dir>
<solr.content.dir>${solr.home}/index</solr.content.dir>
<!-- Properties used in dependency declarations, you don't need to change these -->
<alfresco.groupId>org.alfresco</alfresco.groupId>
<alfresco.share.war.artifactId>share</alfresco.share.war.artifactId>
<!-- Platform WAR artifact, change to 'alfresco-enterprise' if using Enterprise Edition -->
<alfresco.platform.war.artifactId>alfresco-platform</alfresco.platform.war.artifactId>
<!-- Alfresco Platform and Share webapp versions,
these are the original Alfresco webapps that will be
customized and then deployed and run by the tomcat maven plugin when
executing for example $ mvn clean install alfresco:run -->
<alfresco.platform.version>5.2.b-EA</alfresco.platform.version>
<alfresco.share.version>5.2.a-EA</alfresco.share.version>
<!-- Alfresco Surf version, if you change Share version you
might need to change Surf version -->
<alfresco.surf.version>6.6</alfresco.surf.version>
<!-- Aikau framework version, it is released separately, so it can be useful to be able
to bring in newer versions with bug fixes etc -->
<aikau.version>1.0.85</aikau.version>
<!-- JRebel Hot reloading of classpath stuff and web resource stuff -->
<jrebel.version>1.1.6</jrebel.version>
<!-- Environment to use, Alfresco Maven Plugin will
copy alfresco-global-*.properties files from this directory -->
<env>local</env>
<!-- Compile with Java 7, default is 5 -->
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
Note that the Platform (alfresco.war) and Share (share.war) artifacts are now released with their own individual version numbers. And the artifactId for the alfresco.war artifact has changed to alfresco-platform from version 5.2.
We control what modules (AMPs and JARs) that should be applied to each WAR and what webapps we want to run via Alfresco Maven plugin configuration:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition,
change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>community</alfrescoEdition>
<!-- We need the flat file H2 database to run the Repo -->
<enableH2>true</enableH2>
<!-- We always need the Platform/Repo webapp - alfresco.war -->
<enablePlatform>true</enablePlatform>
<!-- Enable Solr webapp so we can use search -->
<enableSolr>true</enableSolr>
<!-- We need Share webapp, so we got a UI for working with the Repo -->
<enableShare>true</enableShare>
<!--
JARs and AMPs that should be overlayed/applied to the Platform/Repository WAR
(i.e. alfresco.war)
-->
<platformModules>
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share-services</artifactId>
<version>${alfresco.share.version}</version>
<type>amp</type>
</moduleDependency>
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-platform-jar</artifactId>
<version>${project.version}</version>
</moduleDependency>
</platformModules>
<!--
JARs and AMPs that should be overlayed/applied to the Share WAR (i.e. share.war)
-->
<shareModules>
<moduleDependency>
<!-- Bring in a newer version, can coexist with older versions
in the WAR disttribution, newest version is picked -->
<groupId>${alfresco.groupId}</groupId>
<artifactId>aikau</artifactId>
<version>${aikau.version}</version>
</moduleDependency>
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-share-jar</artifactId>
<version>${project.version}</version>
</moduleDependency>
</shareModules>
</configuration>
</plugin>
The Alfresco product is no longer released under one common version, such as 5.1.e. The Platform (i.e. alfresco.war) and the Share UI (share.war) are now released with individual version numbers, such as Platform 5.2.a-EA and Share 5.1.g. SDK 3 supports specifying different versions for these artifacts.
Profiles are no longer used for running the project or for enabling Enterprise editions. The runner logic is built into the Alfresco Maven Plugin and to use an Enterprise version you will specify its version in the properties section, and bring in relevant specific Enterprise dependencies.
This means that the artifacts that are produced are always the same and not affected by what profile(s) that have been activated.
Next big change is that we have moved from AMPs to JAR modules as default project and artifact structure. AMPs are still produced via the Maven Assembly plugin, but the main module type we are working with is simple JAR modules.
JARs are the default artifact type that Maven works with, so using simple JAR modules solves a lot of problems. For example, by using simple JAR modules we solve the long standing problem of depending on modules and using classes in them. This was not possible with AMPs but is now easy to do with a standard Maven <dependency> declaration. Also, most IDEs and build tools are familiar with JARs.
We also avoid overwrite problems that can occur quite easily with AMPs, see the following picture:
It is also not trivial to uninstall an AMP as the files in the /config and /web directories are copied into the WAR. Looking at the same example using JAR modules:
We can see that things have improved, you still got possible JAR conflicts but at least you would be aware of them.
To summarize, JAR Modules have some advantages over AMPs:
Another change is that we no longer use Spring Loaded for hot reloading. Instead we use JRebel or the open source alternative HotSwap, which works a lot better and gives hot reloading of Spring context (only JRebel), classes, web resources, property files etc. in both the alfresco.war and the share.war. So now you can for example add a property to your Java backed Web Script controller bean and it is hot reloaded. You can even define new beans and they are hot reloaded. As you might know, in the latest SDK release 2.2.0 you could no longer use Spring Loaded for hot reloading of stuff in alfresco.war.
By using JRebel we could also remove the use of Tomcat Virtual Webapp contexts, which has been a bit confusing. The Virtual Webapp contexts were used to define where in the project structure the Tomcat server should look for web resources (e.g. scripts and images) and classes for a specific web application.
When you generated an AIO project the Virtual webapp contexts were set up correctly for the included Repository AMP and Share AMP, so it worked nicely as long as you did not add more AMPs, then you had to remember to update the virtual webapp context with these AMPs’ web resources and classes, which could be a bit confusing and error prone.
For the virtual webapp context solution to work, we had to exclude the web resources from the produced AMPs, otherwise they would not be picked up from the project structure when they were updated. This led to more confusion as if you took an AMP file that you had just tested in your AIO project (using mvn clean install -Prun) and installed it into a standard Alfresco installation, it would not work as it would be missing the /web folder.
With SDK 3 there is no longer the need to configure and use virtual webapp context files and the JARs and AMPs that are produced are always complete and ready to deploy into a stand-alone Alfresco installation.
With SDK 3 we also wanted to be able to support multiple versions of Alfresco to simplify upgrades and avoid a complicated compatibility matrix. The SDK 3 projects are by default generated with Platform version set to 5.2.a-EA and Share UI version set to 5.1.g.
However, you can also use SDK 3 with Alfresco version 4.2, 5.0, and 5.1. This is possible by having most of the build and run logic inside the Alfresco Maven Plugin.
The AIO project has been simplified as a result of build logic, run logic, and project configuration being moved into the Alfresco Maven Plugin. For more information about the new AIO project see this section.
In order to use the Alfresco SDK you will need a Java Development Kit (JDK) version 8 installed and a Maven version 3.3 installed. Optionally you will need JRebel for hot reloading of web resources, configuration, and classes.
Download JDK 8 from this site, and install by running installer.
Verify installation, both JDK and JRE:
$ javac -version
javac 1.8.0_91
$ java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
Make sure JAVA_HOME is setup correctly, so other tools like Maven will use correct version:
$ env|grep JAVA_HOME
JAVA_HOME=/usr/lib/jvm/java-8-oracle
Download Apache Maven from this site, and install.
Verify installation:
$ mvn -v
Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T12:57:37+01:00)
Maven home: /home/martin/apps/apache-maven-3.3.3
Java version: 1.8.0_91, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-oracle/jre
Default locale: en_GB, platform encoding: UTF-8
OS name: "linux", version: "4.2.0-38-generic", arch: "amd64", family: "unix"
Make sure MAVEN_OPTS and M2_HOME is setup correctly:
$ env|grep M2
M2_HOME=/home/martin/apps/apache-maven-3.3.3
$ env|grep MAV
MAVEN_OPTS=-Xms256m -Xmx1G
For hot reloading of classes and web resources the JRebel and HotSwap Java Agents can be used. JRebel is a commercial product while HotSwap is open source. Both products can reload classes and web resources. However, JRebel is more powerful than HotSwap and can for example also reload changes to the Spring XML context files.
You can try out JRebel using a trial license. Download JRebel from this site, and install (download the nightly build to get the latest features with Spring Context reload etc):
Update the MAVEN_OPTS config to look something like this:
MAVEN_OPTS=-Xms256m -Xmx1G -agentpath:/home/martin/apps/jrebel/lib/libjrebel64.so
Download HotSwap JVM and Java Agent from this site, and install (download the nightly build to get the latest features).
martin@gravitonian:~/Downloads/HotSwap$ sudo java -jar DCEVM-light-8u92-installer.jar
Verify DCEVM:
martin@gravitonian:~/Downloads/HotSwap$ java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Dynamic Code Evolution 64-Bit Server VM (build 25.71-b01-dcevmlight-1, mixed mode)
Update the MAVEN_OPTS config to look something like this:
export MAVEN_OPTS="-Xms256m -Xmx1G -XXaltjvm=dcevm -javaagent:/home/martin/apps/hotswap/hotswap-agent.jar"
The SDK 3 comes with three project archetypes: All-In-One, Platform JAR, and Share JAR. This is similar to previous SDKs. This section will go through how to use each one of these project Maven archetypes (i.e. project templates).
This section covers how to use the new SDK 3 All-in-One project.
To generate a project based on the AIO Maven archetype do the following (make sure Maven environment is setup properly😞
martin@gravitonian:~$ mvn archetype:generate -DarchetypeCatalog=https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -Dfilter=org.alfresco.maven.archetype:
[INFO] Scanning for projects...
...
Choose archetype:
1: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-amp-archetype (Sample project with full support for lifecycle and rapid development of AMPs (Alfresco Module Packages))
2: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-allinone-archetype (Sample multi-module project for All-in-One development on the Alfresco plaftorm. Includes modules for: Repository WAR overlay, Repository AMP, Share WAR overlay, Solr configuration, and embedded Tomcat runner)
3: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:share-amp-archetype (Share project with full support for lifecycle and rapid development of AMPs (Alfresco Module
Packages))
4: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-platform-jar-archetype (Sample project with full support for lifecycle and rapid development of Platform/Repository JARs and AMPs (Alfresco Module Packages))
5: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-share-jar-archetype (Share project with full support for lifecycle and rapid development of JARs and AMPs (Alfresco Module
Packages))
6: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:activiti-jar-archetype (Sample project with full support for lifecycle and rapid development of Activiti JARs)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 2
Choose org.alfresco.maven.archetype:alfresco-allinone-archetype version:
1: 1.0
2: 1.0.1
3: 1.0.2
4: 1.1.0
5: 1.1.1
6: 3.0.0-beta-4
7: 3.0.0-beta-5
Choose a number: 7: <hit enter>
Define value for property 'groupId': : org.alfresco.test
Define value for property 'artifactId': : aio
[INFO] Using property: version = 1.0-SNAPSHOT
Define value for property 'package': org.alfresco.test: : <hit enter>
Confirm properties configuration:
groupId: org.alfresco.test
artifactId: aio
version: 1.0-SNAPSHOT
package: org.alfresco.test
Y: : <hit enter>
Here we choose the second archetype (2) called alfresco-allinone-archetype. Then we specify Maven groupId and artifactId for the new project, this can be whatever you like. We use the same Java package path as groupId.
This generates a project structure as follows:
.
└── aio
├── aio-platform-jar
│ ├── pom.xml
│ └── src
│ ├── main
│ │ ├── assembly
│ │ │ ├── amp.xml
│ │ │ ├── file-mapping.properties
│ │ │ ├── lib
│ │ │ │ └── README.md
│ │ │ └── web
│ │ │ └── README.md
│ │ ├── java
│ │ │ └── org
│ │ │ └── alfresco
│ │ │ └── test
│ │ │ └── platformsample
│ │ │ ├── DemoComponent.java
│ │ │ ├── Demo.java
│ │ │ └── HelloWorldWebScript.java
│ │ └── resources
│ │ ├── alfresco
│ │ │ ├── extension
│ │ │ │ └── templates
│ │ │ │ └── webscripts
│ │ │ │ └── alfresco
│ │ │ │ └── tutorials
│ │ │ │ ├── helloworld.get.desc.xml
│ │ │ │ ├── helloworld.get.html.ftl
│ │ │ │ └── helloworld.get.js
│ │ │ └── module
│ │ │ └── aio-platform-jar
│ │ │ ├── alfresco-global.properties
│ │ │ ├── context
│ │ │ │ ├── bootstrap-context.xml
│ │ │ │ ├── service-context.xml
│ │ │ │ └── webscript-context.xml
│ │ │ ├── messages
│ │ │ │ └── content-model.properties
│ │ │ ├── model
│ │ │ │ ├── content-model.xml
│ │ │ │ └── workflow-model.xml
│ │ │ ├── module-context.xml
│ │ │ ├── module.properties
│ │ │ └── workflow
│ │ │ └── sample-process.bpmn20.xml
│ │ └── META-INF
│ │ └── resources
│ │ └── test.html
│ └── test
│ └── java
│ └── org
│ └── alfresco
│ └── test
├── aio-share-jar
│ ├── pom.xml
│ └── src
│ ├── main
│ │ ├── assembly
│ │ │ ├── amp.xml
│ │ │ ├── file-mapping.properties
│ │ │ ├── lib
│ │ │ │ └── README.md
│ │ │ └── web
│ │ │ └── README.md
│ │ ├── java
│ │ │ └── org
│ │ │ └── alfresco
│ │ │ └── test
│ │ └── resources
│ │ ├── alfresco
│ │ │ ├── module
│ │ │ │ └── aio-share-jar
│ │ │ │ └── module.properties
│ │ │ └── web-extension
│ │ │ ├── aio-share-jar-slingshot-application-context.xml
│ │ │ ├── messages
│ │ │ │ └── aio-share-jar.properties
│ │ │ ├── site-data
│ │ │ │ └── extensions
│ │ │ │ └── aio-share-jar-example-widgets.xml
│ │ │ └── site-webscripts
│ │ │ ├── com
│ │ │ │ └── example
│ │ │ │ └── pages
│ │ │ │ ├── simple-page.get.desc.xml
│ │ │ │ ├── simple-page.get.html.ftl
│ │ │ │ └── simple-page.get.js
│ │ │ └── org
│ │ │ └── alfresco
│ │ │ └── README.md
│ │ └── META-INF
│ │ ├── resources
│ │ │ └── aio-share-jar
│ │ │ └── js
│ │ │ └── tutorials
│ │ │ └── widgets
│ │ │ ├── css
│ │ │ │ └── TemplateWidget.css
│ │ │ ├── i18n
│ │ │ │ └── TemplateWidget.properties
│ │ │ ├── templates
│ │ │ │ └── TemplateWidget.html
│ │ │ └── TemplateWidget.js
│ │ └── share-config-custom.xml
│ └── test
│ └── java
│ └── org
│ └── alfresco
│ └── test
├── debug.bat
├── debug.sh
├── pom.xml
├── README.md
├── run.bat
├── run.sh
└── src
└── test
├── license
│ └── README.md
├── properties
│ └── local
│ ├── alfresco-global-enterprise.properties
│ ├── alfresco-global-h2.properties
│ ├── alfresco-global-mysql.properties
│ └── alfresco-global-postgresql.properties
└── resources
├── alfresco
│ └── extension
│ ├── dev-log4j.properties
│ └── disable-webscript-caching-context.xml
└── tomcat
└── context-solr.xml
As you can see, there are no longer any WAR projects, Runner project, or Solr Config project, just the two JAR module projects. All the webapp assembly and runner logic is now handled by the Alfresco Maven Plugin. So you are probably thinking, if there are no WAR projects, how do I configure what JARs and AMPs that should be applied to the standard alfresco.war and share.war?
The Alfresco Maven Plugin now provides extra configuration sections <platformModules> and <shareModules> where you can specify what modules should be applied to each WAR file:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition,
change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>community</alfrescoEdition>
<!-- We need the flat file H2 database to run the Repo -->
<enableH2>true</enableH2>
<!-- We always need the Platform/Repo webapp - alfresco.war -->
<enablePlatform>true</enablePlatform>
<!-- Enable Solr webapp so we can use search -->
<enableSolr>true</enableSolr>
<!-- We need Share webapp, so we got a UI for working with the Repo -->
<enableShare>true</enableShare>
<!--
JARs and AMPs that should be overlayed/applied to the Platform/Repository WAR
(i.e. alfresco.war)
-->
<platformModules>
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share-services</artifactId>
<version>${alfresco.share.version}</version>
<type>amp</type>
</moduleDependency>
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-platform-jar</artifactId>
<version>${project.version}</version>
</moduleDependency>
</platformModules>
<!--
JARs and AMPs that should be overlayed/applied to the Share WAR (i.e. share.war)
-->
<shareModules>
<moduleDependency>
<!-- Bring in a newer version, can coexist with older versions
in the WAR disttribution, newest version is picked -->
<groupId>${alfresco.groupId}</groupId>
<artifactId>aikau</artifactId>
<version>${aikau.version}</version>
</moduleDependency>
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-share-jar</artifactId>
<version>${project.version}</version>
</moduleDependency>
</shareModules>
</configuration>
</plugin>
To run the new AIO project with the JAR modules applied to respective WAR, step into the AIO directory and execute the following command:
$ cd aio/
aio$ mvn clean install alfresco:run
Note the new way of running the project via the alfresco plugin instead of via a Maven profile.
Access the webapps as usual:
http://localhost:8080/alfresco:
The generated AIO project comes with sample code such as Platform Web Script and Share Aikau page.
Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
The Aikau page can be accessed as follows (http://localhost:8080/share/page/user/admin/dashboard😞
The Aikau page also includes a sample Aikau widget.
If you would like to work with the Alfresco Enterprise Edition, then this requires just a few property changes and a license installation. You also need to have access to the private Alfresco Nexus repos. To configure access to private repos see these docs.
Install an enterprise license, otherwise the server will be in read-only mode. It goes into the following location in main resources (you will have to create directories):
└── src
└── main
└── resources
├── alfresco
│ └── extension
│ └── license
│ └── Ent5.1-AllEnabled-Exp01012017.lic
The license will be injected into the platform war before it is deployed to Tomcat.
Configure Enterprise version in aio/pom.xml, let’s use Platform version 5.1.1 and Share version 5.1.1 (the surf version is slightly older than the default one in SDK 3), also the platform artifactId changes for Enterprise edition:
<alfresco.platform.war.artifactId>alfresco-enterprise</alfresco.platform.war.artifactId>
<alfresco.platform.version>5.1.1</alfresco.platform.version>
<alfresco.share.version>5.1.1</alfresco.share.version>
<alfresco.surf.version>6.3</alfresco.surf.version>
If you are unclear of what Surf version that is used, then install the Alfresco version you will be using and do a search in WEB-INF/lib as follows:
martin@gravitonian:/opt/alfresco511/tomcat/webapps/share/WEB-INF/lib$ ls -l *surf*
-rw-rw-r-- 1 martin martin 870024 Jul 13 10:49 spring-surf-6.3.jar
-rw-rw-r-- 1 martin martin 38968 Jul 13 10:51 spring-surf-api-6.3.jar
Change the Alfresco Edition property in the Alfresco Maven plugin configuration to enterprise, this is also done in aio/pom.xml:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition,
change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>enterprise</alfrescoEdition>
. . .
Changing this to enterprise helps the Alfresco Maven plugin to pick up the correct database H2 scripts.
Note. there is no longer a need to update any of the run.* scripts to use an Enterprise edition. This was previously necessary when the Enterprise edition was enabled via a profile.
Now delete the alf_data_dev directory and restart:
aio$ rm -rf alf_data_dev/
aio$ mvn clean install alfresco:run
You should see evidence in the logs that your are running Enterprise edition and that license is found:
2016-08-18 18:41:33,583 INFO [service.descriptor.DescriptorService] [localhost-startStop-1] Alfresco license: Mode ENTERPRISE, cluster:enabled granted to ness51team limited to 486 days expiring Sun Jan 01 00:00:00 GMT 2017 (136 days remaining).
2016-08-18 18:41:33,583 INFO [service.descriptor.DescriptorService] [localhost-startStop-1] Server Mode :UNKNOWN
2016-08-18 18:41:33,591 INFO [service.descriptor.DescriptorService] [localhost-startStop-1] Alfresco started (Enterprise). Current version: 5.1.1 (r125847-b80) schema 9,029. Originally installed version: 5.1.1 (r125847-b80) schema 9,029.
Access the webapps as usual (username: admin, pwd: admin):
http://localhost:8080/alfresco
The generated AIO project comes with sample code such as Platform Web Script and Share Aikau page. Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
The Aikau page can be accessed as follows (http://localhost:8080/share/page/hdp/ws/simple-page😞
It shows how to create an Aikau page with a custom Aikau widget on it.
So, changing Alfresco version and running was very easy, basically just updating a few properties.
When you enabled the Enterprise edition via a profile in previous versions of the SDK some extra Enterprise libraries were brought in. Such as the following in the platform AMP:
<profile>
<id>enterprise</id>
<dependencies>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-enterprise-repository</artifactId>
<version>${alfresco.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
You will now have to add these manually in the Platform Jar Module (i.e. in aio/aio-platform-jar/pom.xml):
<dependencies>
<!-- The main Alfresco Repo dependency for compiling Java code in src/main/java -->
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-repository</artifactId>
</dependency>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-enterprise-repository</artifactId>
<version>${alfresco.platform.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
The AIO project has the REST API Explorer version 1.2 deployed when you are running the project. Access it via the http://localhost:8080/api-explorer URL:
With the API Explorer you can try out all the different APIs that are available to manage and manipulate the content in the repository.
Logging happens for each of the web applications. So when building customizations for the Platform application, logging levels for custom code will be configured in a Log4J config file for that application. And when building customizations for the Share application, logging levels for custom code will be configured in a Log4J file for that application.
When building customizations for the Platform/Repository it is likely that there will be a requirement to support logging at different levels. There are two samples where you can see how logging works. One is in the DemoComponent class where the following snippet of code logs some stuff:
protected void executeInternal() throws Throwable {
System.out.println("DemoComponent has been executed");
logger.debug("Test debug logging. Congratulation your JAR Module is working");
logger.info("This is only for information purpose. Better remove me from the log in Production");
}
Both the debug log and the info log will be printed when the Alfresco server is started, the aio/alfresco.log file contains the logging:
2016-09-19 13:49:22,474 INFO [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'aio-platform-jar2' version 1.0-SNAPSHOT.
DemoComponent has been executed
2016-09-19 13:49:22,483 DEBUG [test.platformsample.DemoComponent] [localhost-startStop-1] Test debug logging. Congratulation your JAR Module is working
2016-09-19 13:49:22,483 INFO [test.platformsample.DemoComponent] [localhost-startStop-1] This is only for information purpose. Better remove me from the log in Production
Note. the above logging will only happen the first time you start the server with this component/module installed. It only executes once. To see the log again, you would have to remove the alf_data_dev directory and restart.
There is also logging happening every time you call the Hello World Web Script. The Java controller in the HelloWorldWebScript class does the following logging:
protected Map<String, Object> executeImpl(
WebScriptRequest req, Status status, Cache cache) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("fromJava", "HelloFromJava");
logger.debug("Your 'Hello World' Web Script was called!");
return model;
}
Executing the Web Script at the http://localhost:8080/alfresco/service/sample/helloworld URL prints the following log:
2016-09-19 14:00:42,774 DEBUG [test.platformsample.HelloWorldWebScript] [http-bio-8080-exec-12] Your 'Hello World' Web Script was called!
Debug logging for these two classes, DemoComponent and HelloWorldWebScript, is turned on via the aio/src/test/resources/alfresco/extension/dev-log4j.properties Log4J configuration file. This file is just used during the development of customizations and is not shipped with the produced module artifacts (i.e. JARs). The logging configuration that controls the two sample components is at the end of the file and looks like this:
log4j.logger.org.alfresco.test.platformsample.DemoComponent=debug
log4j.logger.org.alfresco.test.platformsample.HelloWorldWebScript=debug
When building customizations for the Share user interface it is likely that there will be a requirement to support logging at different levels. This can be done by overriding the WEB-INF/classes/log4j.properties file that is used by the Share application. Unfortunately there is no mechanism to use a custom log4j.properties file somewhere on the classpath (like it is for the platform application with for example dev-log4j.properties).
The share-jar projects that are generated from the Maven archetypes does not contain any sample code with logging. So to demonstrate Share custom logging we have to implement something that we can do logging from. Let’s implement a simple evaluator in Java that does some logging. And it in turn will be used by a simple DocLib action.
Start with the evaluator class as follows:
package org.alfresco.test.doclibaction.evaluator;
import org.alfresco.web.evaluator.BaseEvaluator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONObject;
/**
* This evaluator does nothing more than a bit of logging, always returns true
*
* @author martin.bergljung@alfresco.com
*/
public class DummyEvaluator extends BaseEvaluator {
private static Log logger = LogFactory.getLog(DummyEvaluator.class);
@Override
public boolean evaluate(JSONObject jsonObject) {
logger.info("The Dummy DocLib Evaluator was called!");
return true;
}
}
This evaluator class file lives here in the AIO project: aio/aio-share-jar/src/main/java/org/alfresco/test/doclibaction/evaluator/DummyEvaluator.java
Now, the evaluator needs to be registered as a Spring bean, do this in the aio/aio-share-jar/src/main/resources/alfresco/web-extension/aio-share-jar-slingshot-application-context.xml file:
<!-- An evaluator that will just log a message, and then return true -->
<bean id="alfresco.tutorials.evaluator.dummy"
class="org.alfresco.test.doclibaction.evaluator.DummyEvaluator" />
Then define the DocLib action that uses this evaluator:
<config evaluator="string-compare" condition="DocLibActions">
<actions>
<action id="alfresco.tutorials.doclib.action.goToGoogle"
icon="google"
type="link"
label="Go to Google">
<param name="href">http://www.google.com</param>
<param name="target">_blank</param>
<evaluator>alfresco.tutorials.evaluator.dummy</evaluator>
</action>
</actions>
<actionGroups>
<actionGroup id="folder-browse">
<action index="910" id="alfresco.tutorials.doclib.action.goToGoogle" />
</actionGroup>
</actionGroups>
</config>
This config lives in the following file: aio/aio-share-jar/src/main/resources/META-INF/share-config-custom.xml
Last thing to do is to configure logging level for the evaluator class. Do this in the aio/src/test/resources/share/log4j.properties file at the end:
log4j.logger.org.alfresco.test.doclibaction.evaluator=debug
The aio/share.log file should now print logs every time you click around in the Document Library:
2016-10-10 11:53:30,611 INFO [org.alfresco.test.doclibaction.evaluator.DummyEvaluator] [http-bio-8080-exec-10] The Dummy DocLib Evaluator was called!
2016-10-10 11:53:30,628 INFO [org.alfresco.test.doclibaction.evaluator.DummyEvaluator] [http-bio-8080-exec-10] The Dummy DocLib Evaluator was called!
There will be one log for every folder listed.
As you might have noticed, the custom log4j.properties file with developer debug logging will always be part of the customized share.war. You might not always want this, such as if this war should be deployed to production. You can then use a property for the Alfresco Maven plugin to control when to override Share log4j.properties:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
...
<!-- We need Share webapp, so we got a UI for working with the Repo -->
<enableShare>true</enableShare>
<useCustomShareLog4jConfig>true</useCustomShareLog4jConfig>
Hot reloading is the ability to modify your application's code, and view the changes without having to restart Alfresco Tomcat. This allows for significant savings in development time that would otherwise be wasted restarting Tomcat. Hot reloading is the key to enabling Rapid Application Development (RAD) and Test Driven Development (TDD).
A Java Agent should be be installed as per this section.
You should have an AIO project generated, see above.
Start the AIO project as follows:
aio$ mvn clean install alfresco:run
You should see evidence in the logs that your are running with JRebel enabled:
2016-08-19 08:54:54 JRebel: #############################################################
2016-08-19 08:54:54 JRebel:
2016-08-19 08:54:54 JRebel: JRebel Agent 6.4.9-SNAPSHOT (201608150832)
2016-08-19 08:54:54 JRebel: (c) Copyright ZeroTurnaround AS, Estonia, Tartu.
…
2016-08-19 08:59:30 JRebel: Directory '/home/martin/src/sdk3/alfresco-sdk-tests/aio/aio-platform-jar/target/classes' will be monitored for changes
…
2016-08-19 09:02:44 JRebel: Monitoring Spring bean definitions in '/home/martin/src/sdk3/alfresco-sdk-tests/aio/aio-platform-jar/target/classes/alfresco/module/aio-platform-jar/context/service-context.xml'.
2016-08-19 09:02:44 JRebel: Monitoring Spring bean definitions in '/home/martin/src/sdk3/alfresco-sdk-tests/aio/aio-platform-jar/target/classes/alfresco/module/aio-platform-jar/context/bootstrap-context.xml'.
2016-08-19 09:02:44 JRebel: Monitoring Spring bean definitions in '/home/martin/src/sdk3/alfresco-sdk-tests/aio/aio-platform-jar/target/classes/alfresco/module/aio-platform-jar/context/webscript-context.xml'.
…
2016-08-19 09:06:40 JRebel: Directory '/home/martin/src/sdk3/alfresco-sdk-tests/aio/aio-share-jar/target/classes' will be monitored for changes.
2016-08-19 09:06:59 JRebel: Monitoring Spring bean definitions in '/home/martin/src/sdk3/alfresco-sdk-tests/aio/aio-share-jar/target/classes/alfresco/web-extension/aio-share-jar-slingshot-application-context.xml'.
When reading the logs we can see that JRebel is monitoring classes and Spring contexts for both the Platform JAR Module and the Share JAR module.
To use HotSwap you need to add a hotswap-agent.properties file to each custom module in the Maven project. This file is similar to rebel.xml, which is generated automatically by the JRebel Maven plugin, in that it specifies what classpaths and resources that the HotSwap agent should monitor for changes.
Add one of these properties files to the aio/aio-platform-jar/src/main/resources directory and one to the aio/aio-share-jar/src/main/resources directory. It Should look like this:
# Enable hotswap so that changes in this module will be automatically reloaded
# Watch for changed class files on watchResources path and reload class definition in the running application.
autoHotswap=true
#autoHotswap.port=8000
# Add a directory prior to application classpath (load classes and resources).
#
# This may be useful for example in multi module maven project to load class changes from upstream project
# classes. Set extraClasspath to upstream project compiler output and .class file will have precedence to
# classes from built JAR file.
# i.e. monitor /target/classes
# should work with extraClasspath=${project.build.outputDirectory}
# If not try
extraClasspath=/real/path/to/project/output/dir/classes
# Comma separated list of disabled plugins
# Use plugin name - e.g.
# Hotswapper, AnonymousClassPatch, WatchResources, Hibernate, Spring, Jersey2, Jetty, Tomcat,
# ZK, Logback, JSF, Seam, ELResolver, OsgiEquinox, Proxy, WebObjects, Weld, JBossModules, Resteasy, Gae
disabledPlugins=Hibernate,Spring
# Add a directory prior to webapp path (load webapp resources).
#
# Load web application resources (such as HTML, JSP, CSS, ...) from this directory prior to default processing.
# Use this setting to set to serve resources from source directory directly (e.g. src/main/webapp).
extraWebappContext=${project.build.outputDirectory}/META-INF/resources
# Load static web resources from different directory.
#
# This setting is dependent on application server plugin(Jetty, Tomcat, JBoss, ...)
webappDir=${project.build.outputDirectory}/META-INF/resources
# Watch for changes in a directory (resources only).
#
# Similar to extraClasspath this property adds classpath when searching for resources (not classes).
# While extra classpath just modifies the classloader, this setting does nothing until the resource
# is really changed.
#
# Sometimes it is not possible to point extraClasspath to your i.e. src/main/resources, because there are multiple
# replacements of resources in a building step (maven filtering resource option).
# This setting will leave i.e. src/target/classes as default source for resources, but after the resource is modified
# in src/main/resources, the new changed resource is served instead.
watchResources=${project.basedir}/src/main/resources
LOGGER.org.hotswap.agent=DEBUG
#LOGGER.org.hotswap.agent.plugin=TRACE
#LOGGER.org.hotswap.agent.watch=TRACE
#LOGGER.org.hotswap.agent.command=TRACE
Start the AIO project as follows:
aio$ mvn clean install alfresco:run
You should see evidence in the logs that your are running with HotSwap enabled:
martin@gravitonian:~/src/sdk3/alfresco-sdk-tests/aio$ mvn clean install alfresco:run
HOTSWAP AGENT: 10:23:44.131 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent {0.3.0-SNAPSHOT} - unlimited runtime class redefinition.
HOTSWAP AGENT: 10:23:44.601 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [Hotswapper, AnonymousClassPatch, WatchResources, Hibernate, Spring, Jersey2, Jetty, Tomcat, ZK, Logback, JSF, Seam, ELResolver, OsgiEquinox, Proxy, WebObjects, Weld, JBossModules, Resteasy, Gae]
[INFO] Scanning for projects...
The AIO project comes with a Platform/Repository Web Script that we can try out hot reloading on. The Web Script can be accessed as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
As an initial test of hot reloading we will make changes to the Java controller, JavaScript controller, and the FreeMarker template.
Start by changing the JavaScript controller available in the aio/aio-platform-jar/src/main/resources/alfresco/extension/templates/webscripts/alfresco/tutorials/helloworld.get.js file:
model["fromJS"] = "Goodbye from JS!";
Then, in a different console window, compile the code for the Platform JAR so we get the new file over into target/classes, where it will be picked up by JRebel (note. you might want to disable JRebel in this console to have the build go faster):
aio/aio-platform-jar$ mvn compile
Now, in the browser refresh the Web Script page:
Update the Web Script Template in the aio/aio-platform-jar/src/main/resources/alfresco/extension/templates/webscripts/alfresco/tutorials/helloworld.get.html.ftl file:
Message: '${fromJS}' AND '${fromJava}'
Compile the code:
aio/aio-platform-jar$ mvn compile
Now, in the browser refresh the Web Script page:
Let’s continue changing the Java controller in the aio/aio-platform-jar/src/main/java/org/alfresco/test/platformsample/HelloWorldWebScript.java file:
public class HelloWorldWebScript extends DeclarativeWebScript {
protected Map<String, Object> executeImpl(
WebScriptRequest req, Status status, Cache cache) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("fromJava", "GoodbyeFromJava");
return model;
}
}
Compile the code:
aio/aio-platform-jar$ mvn compile
Now, in the browser refresh the Web Script page:
Web resources, such as scripts and HTML, can also be reloaded. There is a sample HTML page in the Platform JAR module called test.html, it looks like this:
Update the content of the page as follows in the aio/aio-platform-jar/src/main/resources/META-INF/resources/test.html file:
<h1>This is a Platform webapp page</h1>
Test 123
Compile the code:
aio/aio-platform-jar$ mvn compile
Now, in the browser refresh the page:
TODO
Now let’s add another property to the Spring bean and have it display in the template.
IMPORTANT! This does not work with HotSwap as it does not support Spring XML Context reloading.
Update the bean definition as follows in the
aio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/context/webscript-context.xml file:
<beans>
<bean id="webscript.alfresco.tutorials.helloworld.get"
class="org.alfresco.test.platformsample.HelloWorldWebScript"
parent="webscript">
<property name="secretMessage" value="42" />
</bean>
</beans>
Then the Java bit in the aio/aio-platform-jar/src/main/java/org/alfresco/test/platformsample/HelloWorldWebScript.java file:
public class HelloWorldWebScript extends DeclarativeWebScript {
private String secretMessage;
protected Map<String, Object> executeImpl(
WebScriptRequest req, Status status, Cache cache) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("fromJava", "GoodbyeFromJava");
model.put("fromJava2", secretMessage);
return model;
}
public void setSecretMessage(String secretMessage) {
this.secretMessage = secretMessage;
}
}
And finally the template aio/aio-platform-jar/src/main/resources/alfresco/extension/templates/webscripts/alfresco/tutorials/helloworld.get.html.ftl file:
Message: '${fromJS}' '${fromJava}' '${fromJava2}'
Compile the code:
aio/aio-platform-jar$ mvn compile
Now, in the browser refresh the Web Script page:
Pretty cool, right!
Let’s take it one step further and create a new Web Script from scratch. Copy the one we just tested and rename the files as follows, in the same folder:
Then change the files as follows, start with helloworld2.get.desc.xml:
<webscript>
<shortname>Hello World Sample Webscript</shortname>
<description>Hands back a greeting</description>
<url>/sample/helloworld2</url>
<authentication>user</authentication>
<format default="html"></format>
<lifecycle>sample</lifecycle>
</webscript>
Then helloworld2.get.js:
model["fromJS"] = "Hello from JS 2!";
And add a new Java controller by copying the existing one:
And finally add this Java controller as a bean in aio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/context/webscript-context.xml:
<beans>
<bean id="webscript.alfresco.tutorials.helloworld.get"
class="org.alfresco.test.platformsample.HelloWorldWebScript"
parent="webscript">
<property name="secretMessage" value="42" />
</bean>
<bean id="webscript.alfresco.tutorials.helloworld2.get"
class="org.alfresco.test.platformsample.HelloWorldWebScript"
parent="webscript">
<property name="secretMessage" value="42" />
</bean>
</beans>
Compile the code:
aio/aio-platform-jar$ mvn compile alfresco:refresh-repo
Note here that because we have a brand new Web Script we need to refresh the web script container so it knows about it. This is done via the Alfresco Maven plugin and the alfresco:refresh-repo command.
Now, in the browser access this new Web Script on URL http://localhost:8080/alfresco/service/sample/helloworld2:
So this is pretty impressive, hot reloading of even new Spring beans and Web Scripts.
We have seen that hot reloading works great on the Platform side, now let’s look at the Share UI side. We got a sample Aikau page and widget that we can work with:
Let’s change the page title and layout. This is done in theaio/aio-share-jar/src/main/resources/alfresco/web-extension/site-webscripts/com/example/pages/simple-page.get.js file:
model.jsonModel = {
widgets: [{
id: "SET_PAGE_TITLE",
name: "alfresco/header/SetTitle",
config: {
title: "This is a sample GOODBYE page"
}
},
{
id: "MY_VERTICAL_WIDGET_LAYOUT",
name: "alfresco/layout/VerticalWidgets",
config: {
widgetWidth: 50,
widgets: [
{
id: "DEMO_SIMPLE_LOGO",
name: "alfresco/logo/Logo",
config: {
logoClasses: "alfresco-logo-only"
}
},
{
id: "DEMO_SIMPLE_MSG",
name: "tutorials/widgets/TemplateWidget"
}
]
}
}]
};
Step into the Share JAR module project and compile the code:
aio/aio-share-jar$ mvn compile alfresco:refresh-share
Note here that because we are making changes to the Surf Web Script controller we need to refresh the web script container so it knows about it. This is done via the Alfresco Maven plugin and the alfresco:refresh-share command. This command also clears certain dependency caches.
Now, in the browser access the Aikau page on URL http://localhost:8080/share/page/hdp/ws/simple-page:
All good so far. Let’s update the style, template, and JavaScript code for the Aikau widget and see how that goes:
aio/aio-share-jar/src/main/resources/META-INF/resources/aio-share-jar/js/tutorials/widgets/css/TemplateWidget.css:
.my-template-widget {
border: 3px #000000 solid;
padding: 1em;
width: 100px;
background-color: lightgreen;
}
aio/aio-share-jar/src/main/resources/META-INF/resources/aio-share-jar/js/tutorials/widgets/i18n/TemplateWidget.properties:
hello-label=Goodbye from i18n
aio/aio-share-jar/src/main/resources/META-INF/resources/aio-share-jar/js/tutorials/widgets/templates/TemplateWidget.html:
<div class="my-template-widget">${greeting} AND ${greeting2}</div>
aio/aio-share-jar/src/main/resources/META-INF/resources/aio-share-jar/js/tutorials/widgets/TemplateWidget.js:
define(["dojo/_base/declare",
"dijit/_WidgetBase",
"alfresco/core/Core",
"dijit/_TemplatedMixin",
"dojo/text!./templates/TemplateWidget.html"
],
function(declare, _Widget, Core, _Templated, template) {
return declare([_Widget, Core, _Templated], {
templateString: template,
i18nRequirements: [ {i18nFile: "./i18n/TemplateWidget.properties"} ],
cssRequirements: [{cssFile:"./css/TemplateWidget.css"}],
buildRendering: function example_widgets_TemplateWidget__buildRendering() {
this.greeting = this.message('hello-label');
this.greeting2 = 'Goodbye';
this.inherited(arguments);
}
});
});
Compile the code:
aio/aio-share-jar$ mvn compile alfresco:refresh-share
Refresh the Aikau page:
This shows that it is possible to work with hot reloading on the UI side too with good result.
TODO
There are a couple of cases when you need to use Alfresco Module Packages (AMPs) instead of JARs. One such case is when an out-of-the-box webapp resource, such as the favicon.ico needs to be overridden. There is no extension path you can use to override this icon, you basically need to replace the file in the original web application with your version.
This can be achieved by using an AMP file, which is overlayed on top of the webapp with the MMT tool, replacing any files on the same path. So to replace the <alfresco-install-dir>/tomcat/webapps/share/favicon.ico file in the Alfresco Share webapp, you need to add your version of the file, with the same name as the original, in the aio/aio-share-jar/src/main/assembly/web directory. Then it will then end up in the
/web directory in the AMP file and override the out-of-the-box favicon.ico file when AMP is applied to the Share.war.
For the Share AMP to be applied to the Share.war, and not just a JAR added to the WEB-INF/lib directory, the module dependency needs to be set to amp:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
...
<shareModules>
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>aikau</artifactId>
<version>${aikau.version}</version>
</moduleDependency>
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-share-jar</artifactId>
<version>${project.version}</version>
<type>amp</type>
</moduleDependency>
</shareModules>
Important! New web resources should not be located here, but instead in the usual place in the src/main/resources/META-INF/resources/<module-id>/ directory.
Another case when an AMP is needed is when your extension is dependent on a 3rd party library that cannot be found in the webapp’s WEB-INF/lib directory. So for example, if you are using a JAR called supercalc-2.0.jar in a platform extension, then this file is not part of the alfresco.war/WEB-INF/lib directory, and can therefore not be included as a provided Maven dependency.
To include Supercalc lib we need to add it to the aio/aio-platform-jar/src/main/assembly/lib directory. It will then be part of the AMP’s /lib folder and overlayed on top of the alfresco/WEB-INF/lib directory when the MMT tool is used to apply the AMP to the alfresco.war.
For the platform AMP to be applied to the Alfresco.war, and not just a JAR added to the WEB-INF/lib directory, the module dependency needs to be set to amp:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
...
<platformModules>
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share-services</artifactId>
<version>${alfresco.share.version}</version>
<type>amp</type>
</moduleDependency>
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-platform-jar</artifactId>
<version>${project.version}</version>
<type>amp</type>
</moduleDependency>
</platformModules>
In certain circumstances there might be a requirement to use a custom context path for the Share web application. To do this add the following extra property called shareContextPath:
<enableShare>true</enableShare>
<shareContextPath>/share-this</shareContextPath>
When working in larger projects it might sometimes be useful to be able to deploy a custom webapp together with the Alfresco webapps. As we no longer have any runner project with the Tomcat plugin configuration exposed, we now need to facilitate this in another way.
The Alfresco Maven Plugin configuration can now be used for this as in the following example:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
...
<tomcatCustomWebapps>
<tomcatCustomWebapp>
<groupId>com.exari</groupId>
<artifactId>exari-docgen-cmwar</artifactId>
<version>${project.version}</version>
<contextPath>/exari</contextPath>
<contextFile>${project.build.directory}/contexts/context-docgen.xml
</contextFile>
</tomcatCustomWebapp>
</tomcatCustomWebapps>
Note that the Alfresco webapps are always deployed via plugin properties, such as enablePlatform and enableSolr.
Sometimes when deploying custom webapps as per above description it might be necessary to supply extra system properties for the Tomcat plugin. As we no longer have any runner project with the Tomcat plugin configuration exposed, we now need to facilitate this in another way.
The Alfresco Maven Plugin configuration can now be used for this as in the following example:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
...
<tomcatSystemProperties>
<propName>PropVal</propName>
</tomcatSystemProperties>
This property definition will show up in the Maven build log as follows:
[INFO] Creating Tomcat server configuration at /home/martin/src/sdk3/alfresco-sdk-tests/aio-plugin/target/tomcat
[INFO] setting SystemProperties:
[INFO] java.io.tmpdir=/home/martin/src/sdk3/alfresco-sdk-tests/aio-plugin/target
[INFO] propName=PropVal
[INFO] solr.solr.home=/home/martin/src/sdk3/alfresco-sdk-tests/aio-plugin/alf_data_dev/solr
By default the AIO project is configured to run with the flat file H2 database. This is done via the <enableH2>true</enableH2> Alfresco Maven plugin property. When this property is set to true the H2 database and JDBC driver will automatically be loaded via the Tomcat Maven plugin. And the src/test/properties/local/alfresco-global-h2.properties file will be used as the alfresco-global.properties file.
Standalone database servers can also be used. The MySQL and PostgreSQL databases can be configured in a similar manner as the H2 database. Other Enterprise databases require a little bit more configuration.
See also official documentation for more information around database configuration.
To use a local MySQL database follow these steps:
$ mysql -u root -p
Enter password:
mysql> create database alfrescoaio default character set utf8;
Query OK, 1 row affected (0.00 sec)
mysql> grant all on alfrescoaio.* to 'alfresco'@'localhost' identified by 'alfresco' with grant option;
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on alfrescoaio.* to 'alfresco'@'localhost.localdomain' identified by 'alfresco' with grant option;
Query OK, 0 rows affected (0.00 sec)
aio$ rm -rf alf_data_dev/
aio$ mvn clean install alfresco:run
If you want to use a remote MySQL server then just open up the src/test/properties/local/alfresco-global-mysql.properties file and change the necessary properties.
To use a local PostgreSQL database follow these steps:
CREATE DATABASE alfrescoaio
WITH OWNER = postgres
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'English_United Kingdom.1252'
LC_CTYPE = 'English_United Kingdom.1252'
CONNECTION LIMIT = -1;
CREATE ROLE alfresco LOGIN
ENCRYPTED PASSWORD 'md5a963ed7949076827a104ff5522bc496f'
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE;
GRANT ALL ON DATABASE alfrescoaio TO public;
GRANT ALL ON DATABASE alfrescoaio TO postgres;
GRANT ALL ON DATABASE alfrescoaio TO alfresco;
Note. Encrypted password for user alfresco is ‘alfresco’
aio$ rm -rf alf_data_dev/
aio$ mvn clean install alfresco:run
To use an Enterprise database such as MS SQL Server or Oracle, follow these steps:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<alfrescoEdition>community</alfrescoEdition>
<!-- Enable MS SQL Server database -->
<enableEnterpriseDb>true</enableEnterpriseDb>
<tomcatDependencies>
<tomcatDependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</tomcatDependency>
</tomcatDependencies>
<enablePlatform>true</enablePlatform>
<enableSolr>true</enableSolr>
<enableShare>true</enableShare>
<enableApiExplorer>true</enableApiExplorer>
...
aio$ rm -rf alf_data_dev/
aio$ mvn clean install alfresco:run
As the project does not have any WAR POMs you are probably wondering if the customized WARs that we are running with are available somewhere. They are, in the AIO /target directory you will find the customized WARs:
aio/target$ ls -l
total 206540
drwxrwxr-x 3 martin martin 4096 Aug 18 10:30 Alfresco
drwxrwxr-x 2 martin martin 4096 Aug 18 10:23 Alfresco-WebScripts
drwxrwxr-x 2 martin martin 4096 Aug 18 10:22 apache-tomcat-maven-plugin
drwxrwxr-x 2 martin martin 4096 Aug 18 10:22 dependency-maven-plugin-markers
drwxrwxr-x 2 martin martin 4096 Aug 18 10:22 maven-archiver
drwxrwxr-x 3 martin martin 4096 Aug 18 10:22 modules
drwxrwxr-x 10 martin martin 4096 Aug 18 10:22 platform-war
-rw-rw-r-- 1 martin martin 148686740 Aug 18 10:22 platform.war
drwxrwxr-x 14 martin martin 4096 Aug 18 10:22 share-war
-rw-rw-r-- 1 martin martin 62757939 Aug 18 10:22 share.war
drwxrwxr-x 4 martin martin 4096 Aug 18 10:22 test-classes
drwxrwxr-x 6 martin martin 4096 Aug 18 10:22 tomcat
It is possible to use this AIO project with older Alfresco versions, such as 4.2, 5.0, and 5.1.
By default the SDK 3 AIO project is configured to use Alfresco Platform (alfresco.war) version 5.2.a-EA and Share (share.war) version 5.1.g.
Important! Start from a newly generated SDK 3 AIO project.
Now, let’s try with version 5.1. From this version the Platform webapp and the Share user interface webapp have different version numbering, and the artifactId for the Platform changes. It is not until version 5.2.a-EA of the platform that the version numbers deviate though. Let’s use version 5.1.e:
<alfresco.platform.version>5.1.e</alfresco.platform.version>
<alfresco.share.version>5.1.e</alfresco.share.version>
<alfresco.surf.version>6.3</alfresco.surf.version>
Note that the Platform and Share UI versions are the same for this release. The Surf version is different from what we have for 5.1.g (share.war), it is 6.3 for 5.1.e instead of 6.5. If you are unclear of what Surf version that is used, then install the Alfresco version you will be using and do a search in WEB-INF/lib as follows:
martin@gravitonian:/opt/alfresco51f/tomcat/webapps/share/WEB-INF/lib$ ls -l *surf*
-rw-rw-r-- 1 martin martin 870024 Apr 22 23:33 spring-surf-6.3.jar
-rw-rw-r-- 1 martin martin 38968 Apr 22 23:34 spring-surf-api-6.3.jar
Now delete the alf_data_dev directory and restart:
aio$ rm -rf alf_data_dev/
aio$ mvn clean install -DskipTests=true alfresco:run
Access the webapps as usual:
http://localhost:8080/alfresco
The generated AIO project comes with sample code such as Platform Web Script and Share Aikau page. Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
The Aikau page can be accessed as follows (http://localhost:8080/share/page/hdp/ws/simple-page😞
It includes a sample Aikau widget.
So, changing Alfresco version and running was very easy, basically just updating a few properties.
Important! Start from newly generated SDK 3 AIO project.
For Alfresco version 5.0 the alfresco.war, share.war, and surf artifacts have the same version number, such as 5.0.d. To use this version open up the aio/pom.xml file and update the following properties:
<alfresco.platform.war.artifactId>alfresco</alfresco.platform.war.artifactId>
<alfresco.platform.version>5.0.d</alfresco.platform.version>
<alfresco.share.version>5.0.d</alfresco.share.version>
<alfresco.surf.version>5.0.d</alfresco.surf.version>
Note that the platform war artifactId is different in older versions (Alfresco Maven plugin will handle this, but for consistency it is good to update it).
If you are unclear of what Surf version that is used, then install the Alfresco version you will be using and do a search in WEB-INF/lib as follows:
martin@gravitonian:/opt/alfresco50d/tomcat/webapps/share/WEB-INF/lib$ ls -l *surf*
-rw-rw-r-- 1 martin martin 831228 Mar 19 2015 spring-surf-5.0.d.jar
-rw-rw-r-- 1 martin martin 38980 Mar 19 2015 spring-surf-api-5.0.d.jar
Also, the Alfresco Share Services AMP that is applied to the platform war (i.e. alfresco.war) was introduced in version 5.1, so we need to remove it/comment it out from the Alfresco Maven Plugin configuration:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition,
change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>community</alfrescoEdition>
<!-- We need the flat file H2 database to run the Repo -->
<enableH2>true</enableH2>
<!-- We always need the Platform/Repo webapp - alfresco.war -->
<enablePlatform>true</enablePlatform>
<!-- Enable Solr webapp so we can use search -->
<enableSolr>true</enableSolr>
<!-- We need Share webapp, so we got a UI for working with the Repo -->
<enableShare>true</enableShare>
<!--
JARs and AMPs that should be overlayed/applied to the Platform/Repository WAR
(i.e. alfresco.war)
-->
<platformModules>
<!--
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share-services</artifactId>
<version>${alfresco.share.version}</version>
<type>amp</type>
</moduleDependency>
-->
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-platform-jar</artifactId>
<version>${project.version}</version>
</moduleDependency>
</platformModules>
<!--
JARs and AMPs that should be overlayed/applied to the Share WAR (i.e. share.war)
-->
<shareModules>
<moduleDependency>
<!-- Bring in a newer version, can coexist with older versions in
the WAR disttribution, newest version is picked -->
<groupId>${alfresco.groupId}</groupId>
<artifactId>aikau</artifactId>
<version>${aikau.version}</version>
</moduleDependency>
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-share-jar</artifactId>
<version>${project.version}</version>
</moduleDependency>
</shareModules>
</configuration>
</plugin>
Note. the Alfresco Maven Plugin is actually smart enough to know that you are not running a 5.1 version or newer, and will not apply the alfresco-share-services AMP from the above configuration even if you leave it in. It is just more clear when you comment it out. But if you are going to switch back and forth between versions you can leave the AMP config in, the plugin knows when to apply it and when not to.
The Spring Surf project at this time was part of the Spring Framework extensions (now it is an Alfresco project), so we need to update a few dependencies. In the aio/pom.xml comment out the Spring Surf related dependencies as they don’t have different versioning in 5.0.d:
<dependencyManagement>
<dependencies>
<!-- This will import the dependencyManagement for all artifacts in the
selected Alfresco platform.
NOTE: You still need to define dependencies in your POM, but you can
omit version as it's enforced by this dependencyManagement.
NOTE: It defaults to the latest version this SDK pom has been tested with,
but alfresco version can/should be overridden in your project's pom
-->
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-platform-distribution</artifactId>
<version>${alfresco.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Redefine the following Share dependencies as they
have different version numbers than platform.
They are defined in alfresco-platform-distribution... -->
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>${alfresco.share.war.artifactId}</artifactId>
<version>${alfresco.share.version}</version>
<type>war</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>${alfresco.share.war.artifactId}</artifactId>
<version>${alfresco.share.version}</version>
<classifier>classes</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-web-framework-commons</artifactId>
<version>${alfresco.share.version}</version>
<classifier>classes</classifier>
<scope>provided</scope>
</dependency>
<!-- Redefine the following surf dependencies as they have no resolvable version in the
alfresco-platform-distribution artifact
<dependency>
<groupId>org.alfresco.surf</groupId>
<artifactId>spring-surf</artifactId>
<version>${alfresco.surf.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.alfresco.surf</groupId>
<artifactId>spring-surf-api</artifactId>
<version>${alfresco.surf.version}</version>
<scope>provided</scope>
</dependency>-->
</dependencies>
</dependencyManagement>
Also, in the Share JAR project update the Spring Surf API dependency with the Spring Framework group ID, in the file aio/aio-share-jar/pom.xml:
<dependencies>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>${alfresco.share.war.artifactId}</artifactId>
<classifier>classes</classifier>
</dependency>
<dependency>
<groupId>org.springframework.extensions.surf</groupId>
<artifactId>spring-surf-api</artifactId>
</dependency>
Now delete the alf_data_dev directory and restart:
aio$ rm -rf alf_data_dev/
aio$ mvn clean install -DskipTests=true alfresco:run
Access the webapps as usual:
http://localhost:8080/alfresco
The generated AIO project comes with sample code such as Platform Web Script and Share Aikau page. Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
The Aikau page can be accessed as follows (http://localhost:8080/share/page/hdp/ws/simple-page😞
It includes a sample Aikau widget.
So again, changing Alfresco version and running was very easy, basically just updating a few properties and changing some other XML configuration.
Important! Start from newly generated SDK 3 AIO project.
So how about going all the way back to 4.2? Is that possible? Yes it is, it is going to require a bit more work but it is possible!
For Alfresco version 4.2 the alfresco.war and share.war artifacts have the same version number, such as 4.2.f. To use this version open up the aio/pom.xml file and update the following properties:
<alfresco.platform.war.artifactId>alfresco</alfresco.platform.war.artifactId>
<alfresco.platform.version>4.2.f</alfresco.platform.version>
<alfresco.share.version>4.2.f</alfresco.share.version>
Note that the platform war artifactId is different in older versions.
Also, the Alfresco Share Services AMP that is applied to the platform war (i.e. alfresco.war) was introduced in version 5.1, so we need to remove it/comment it out from the Alfresco Maven Plugin configuration:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition,
change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>community</alfrescoEdition>
<!-- We need the flat file H2 database to run the Repo -->
<enableH2>true</enableH2>
<!-- We always need the Platform/Repo webapp - alfresco.war -->
<enablePlatform>true</enablePlatform>
<!-- Enable Solr webapp so we can use search -->
<enableSolr>true</enableSolr>
<!-- We need Share webapp, so we got a UI for working with the Repo -->
<enableShare>true</enableShare>
<!--
JARs and AMPs that should be overlayed/applied to the Platform/Repository WAR
(i.e. alfresco.war)
-->
<platformModules>
<!--
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share-services</artifactId>
<version>${alfresco.share.version}</version>
<type>amp</type>
</moduleDependency>
-->
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-platform-jar</artifactId>
<version>${project.version}</version>
</moduleDependency>
</platformModules>
<!--
JARs and AMPs that should be overlayed/applied to the Share WAR (i.e. share.war)
-->
<shareModules>
<moduleDependency>
<!-- Bring in a newer version, can coexist with older versions in
the WAR disttribution, newest version is picked -->
<groupId>${alfresco.groupId}</groupId>
<artifactId>aikau</artifactId>
<version>${aikau.version}</version>
</moduleDependency>
<!-- Bring in custom Modules -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>aio-share-jar</artifactId>
<version>${project.version}</version>
</moduleDependency>
</shareModules>
</configuration>
</plugin>
Note. the Alfresco Maven Plugin is actually smart enough to know that you are not running a 5.1 version or newer, and will not apply the alfresco-share-services AMP from the above configuration even if you leave it in. It is just more clear when you comment it out. But if you are going to switch back and forth between versions you can leave the AMP config in, the plugin knows when to apply it and when not to.
The way we depend on Share classes and files from the Share AMP is different in version 4.2.f. In the Share JAR project update the dependencies completely, so they look like this instead, in the file aio/aio-share-jar/pom.xml:
<!--
Include libs that the Share JAR extension will use.
They are mostly provided by Alfresco during runtime so scope should be set as provided
(if in doubt then check for the lib in tomcat/webapps/share/WEB-INF/lib,
if it's there then it's provided).
-->
<dependencies>
<!-- Include JAR that has classes such as BaseEvaluator -->
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share</artifactId>
<version>${alfresco.share.version}</version>
<scope>provided</scope>
<exclusions>
<!-- Exclude org.alfresco:alfresco-web-framework-commons:jar:classes:4.2.f
dependency -->
<exclusion>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-web-framework-commons</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Bring in the correct version of alfresco-web-framework-commons -->
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-web-framework-commons</artifactId>
<version>${alfresco.share.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
Update indexing subsystem to Solr 1, in aio/src/test/properties/local/alfresco-global.properties update the following property:
index.subsystem.name=solr
Set database configuration parameters, need to emulate PostgreSQL, in aio/pom.xml:
<alfresco.db.params>MODE=PostgreSQL;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;MVCC=TRUE</alfresco.db.params>
Finally, change Alfresco module versions to not use SNAPSHOT versions as these are not supported in 4.2, update both the aio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/module.properties file and the aio/aio-share-jar/src/main/resources/alfresco/module/aio-share-jar/module.properties file:
module.version=1.0
Now delete the alf_data_dev directory and restart:
aio$ rm -rf alf_data_dev/
aio$ mvn clean install -DskipTests=true alfresco:run
Access the webapps as usual:
http://localhost:8080/alfresco (Alfresco Explorer is available in 4.2):
The generated AIO project comes with sample code such as Platform Web Script and Share Aikau page.
Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
The Aikau page can be accessed as follows (http://localhost:8080/share/page/hdp/ws/simple-page😞
It includes a sample Aikau widget.
So again, changing Alfresco version and running was not that complicated, it’s a bit more work for 4.2 but doable.
This section covers how to use the new SDK 3 Platform JAR Module project.
To generate a project based on the Platform JAR Maven archetype do the following (make sure Maven environment is setup properly😞
martin@gravitonian:~$ mvn archetype:generate -DarchetypeCatalog=https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -Dfilter=org.alfresco.maven.archetype:
...
Choose archetype:
1: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-amp-archetype (Sample project with full support for lifecycle and rapid development of AMPs (Alfresco Module Packages))
2: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-allinone-archetype (Sample multi-module project for All-in-One development on the Alfresco plaftorm. Includes modules for: Repository WAR overlay, Repository AMP, Share WAR overlay, Solr configuration, and embedded Tomcat runner)
3: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:share-amp-archetype (Share project with full support for lifecycle and rapid development of AMPs (Alfresco Module
Packages))
4: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-platform-jar-archetype (Sample project with full support for lifecycle and rapid development of Platform/Repository JARs and AMPs (Alfresco Module Packages))
5: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-share-jar-archetype (Share project with full support for lifecycle and rapid development of JARs and AMPs (Alfresco Module
Packages))
6: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:activiti-jar-archetype (Sample project with full support for lifecycle and rapid development of Activiti JARs)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 4
Define value for property 'groupId': : org.alfresco.test
Define value for property 'artifactId': : platform-jar
[INFO] Using property: version = 1.0-SNAPSHOT
Define value for property 'package': org.alfresco.test: : <hit enter>
Confirm properties configuration:
groupId: org.alfresco.test
artifactId: platform-jar
version: 1.0-SNAPSHOT
package: org.alfresco.test
Y: : <hit enter>
Here we choose the first archetype (4) called alfresco-platform-jar-archetype. Then we specify Maven groupId and artifactId for the new project, this can be whatever you like. We use the same Java package path as groupId.
This generates a project structure as follows:
.
├── debug.bat
├── debug.sh
├── pom.xml
├── README.md
├── run.bat
├── run.sh
└── src
├── main
│ ├── assembly
│ │ ├── amp.xml
│ │ ├── file-mapping.properties
│ │ ├── lib
│ │ │ └── README.md
│ │ └── web
│ │ └── README.md
│ ├── java
│ │ └── org
│ │ └── alfresco
│ │ └── test
│ │ └── platformsample
│ │ ├── DemoComponent.java
│ │ ├── Demo.java
│ │ └── HelloWorldWebScript.java
│ └── resources
│ ├── alfresco
│ │ ├── extension
│ │ │ └── templates
│ │ │ └── webscripts
│ │ │ └── alfresco
│ │ │ └── tutorials
│ │ │ ├── helloworld.get.desc.xml
│ │ │ ├── helloworld.get.html.ftl
│ │ │ └── helloworld.get.js
│ │ └── module
│ │ └── platform-jar
│ │ ├── alfresco-global.properties
│ │ ├── context
│ │ │ ├── bootstrap-context.xml
│ │ │ ├── service-context.xml
│ │ │ └── webscript-context.xml
│ │ ├── messages
│ │ │ └── content-model.properties
│ │ ├── model
│ │ │ ├── content-model.xml
│ │ │ └── workflow-model.xml
│ │ ├── module-context.xml
│ │ ├── module.properties
│ │ └── workflow
│ │ └── sample-process.bpmn20.xml
│ └── META-INF
│ └── resources
│ └── test.html
└── test
├── java
│ └── org
│ └── alfresco
│ └── test
├── license
│ └── README.md
├── properties
│ └── local
│ ├── alfresco-global-enterprise.properties
│ ├── alfresco-global-h2.properties
│ ├── alfresco-global-mysql.properties
│ └── alfresco-global-postgresql.properties
└── resources
├── alfresco
│ └── extension
│ ├── dev-log4j.properties
│ └── disable-webscript-caching-context.xml
└── tomcat
└── context-solr.xml
The alfresco/extension and alfresco/module directories are probably familiar to most people, but the location of them is a bit different from when the SDK used AMPs. All the webapp assembly and runner logic is now also handled by the Alfresco Maven Plugin. So you are probably thinking, if there are no WAR projects and no amp-to-war profile (the project does not extend an SDK parent POM with profiles), how do I configure what JARs and AMPs that should be applied to the standard alfresco.war?
The Alfresco Maven Plugin now provides an extra configuration section <platformModules> where you can specify what modules should be applied to the Alfresco.WAR file:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition, change to
'enterprise' if using Enterprise edition -->
<alfrescoEdition>community</alfrescoEdition>
<!-- We need the flat file H2 database to run the Repo -->
<enableH2>true</enableH2>
<!-- This is a platform extension JAR, so we need the platform
webapp (alfresco.war) -->
<enablePlatform>true</enablePlatform>
<!-- Enable Solr so we can use search, our Repo extension probably need search -->
<enableSolr>true</enableSolr>
<!-- We don't need the share.war if we don't have any UI extensions -->
<enableShare>false</enableShare>
<!--
JARs and AMPs that should be overlayed/applied to the Platform/Repository WAR
(i.e. alfresco.war)
No need to include our self...
-->
<platformModules>
<!-- This AMP is needed if we are going to access the platform webapp
from a Share webapp -->
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share-services</artifactId>
<version>${alfresco.share.version}</version>
<type>amp</type>
</moduleDependency>
</platformModules>
</configuration>
</plugin>
To run the new Platform JAR project, step into the directory and execute the following command:
$ cd platform-jar/
platform-jar$ mvn clean install alfresco:run
Note the new way of running the project via the alfresco plugin instead of via a Maven profile.
Access the webapp as usual, although there is not much webapp going on for the Alfresco.war:
http://localhost:8080/alfresco:
The generated Platform JAR project comes with sample code for a Web Script.
Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
If you would like to work with the Alfresco Enterprise Edition, then this requires just a few property changes and a license installation. You also need to have access to the private Alfresco Nexus repos. To configure access to private repos see these docs.
Install an enterprise license, otherwise the server will be in read-only mode. It goes into the following location in main resources (you will have to create the license directory):
└── src
└── main
└── resources
├── alfresco
│ └── extension
│ └── license
│ └── Ent5.1-AllEnabled-Exp01012017.lic
The license will be injected into the platform war before it is deployed to Tomcat.
Configure Enterprise version in pom.xml, let’s use Platform version 5.1.1. The platform artifactId changes for Enterprise edition:
<alfresco.platform.war.artifactId>alfresco-enterprise</alfresco.platform.war.artifactId>
<alfresco.platform.version>5.1.1</alfresco.platform.version>
<alfresco.share.version>5.1.1</alfresco.share.version>
Note that we are setting the share version too, this is so we can apply the correct version of the alfresco-share-services AMP.
Change the Alfresco Edition property in the Alfresco Maven plugin configuration to enterprise, this is also done in pom.xml:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition,
change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>enterprise</alfrescoEdition>
. . .
Changing this to enterprise helps the Alfresco Maven plugin to pick up the correct database H2 scripts.
Note. there is no longer a need to update any of the run.* scripts to use an Enterprise edition. This was previously necessary when the Enterprise edition was enabled via a profile.
Now delete the alf_data_dev directory and restart:
platform-jar$ rm -rf alf_data_dev/
platform-jar$ mvn clean install -DskipTests=true alfresco:run
You should see evidence in the logs that your are running Enterprise edition and that license is found:
2016-08-18 18:41:33,583 INFO [service.descriptor.DescriptorService] [localhost-startStop-1] Alfresco license: Mode ENTERPRISE, cluster:enabled granted to ness51team limited to 486 days expiring Sun Jan 01 00:00:00 GMT 2017 (136 days remaining).
2016-08-18 18:41:33,583 INFO [service.descriptor.DescriptorService] [localhost-startStop-1] Server Mode :UNKNOWN
2016-08-18 18:41:33,591 INFO [service.descriptor.DescriptorService] [localhost-startStop-1] Alfresco started (Enterprise). Current version: 5.1.1 (r125847-b80) schema 9,029. Originally installed version: 5.1.1 (r125847-b80) schema 9,029.
Access the webapp as usual (username: admin, pwd: admin).
http://localhost:8080/alfresco:
The generated Platform JAR project comes with a sample Web Script.
Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
Changing to Alfresco Enterprise version and running was very easy, basically just updating a few properties.
When you enabled the Enterprise edition via a profile in previous versions of the SDK some extra Enterprise libraries were brought in. Such as the following in the platform AMP:
<profile>
<id>enterprise</id>
<dependencies>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-enterprise-repository</artifactId>
<version>${alfresco.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
You will now have to add these manually to the Platform Jar Module pom.xml:
<dependencies>
<!-- The main Alfresco Repo dependency for compiling Java code in src/main/java -->
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-repository</artifactId>
</dependency>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-enterprise-repository</artifactId>
<version>${alfresco.platform.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
This is described in this section.
See the platform logging section in the AIO docs.
Hot reloading for platform extensions are described in detail in this section.
This is described in detail in this section.
This is described in detail in this section.
This is described in detail in this section.
TODO
This is described in detail in this section.
As the project does not have any WAR POM you are probably wondering if the customized WAR that we are running with is available somewhere. It is, in the /target directory you will find the customized WAR:
platform-jar/target$ ls -l
total 157848
drwxrwxr-x 4 martin martin 4096 Aug 19 15:13 Alfresco
drwxrwxr-x 2 martin martin 4096 Aug 19 15:08 Alfresco-WebScripts
drwxrwxr-x 2 martin martin 4096 Aug 19 15:05 apache-tomcat-maven-plugin
drwxrwxr-x 2 martin martin 4096 Aug 19 15:04 archive-tmp
drwxrwxr-x 5 martin martin 4096 Aug 19 15:04 classes
drwxrwxr-x 2 martin martin 4096 Aug 19 15:05 dependency-maven-plugin-markers
drwxrwxr-x 2 martin martin 4096 Aug 19 15:04 maven-archiver
drwxrwxr-x 3 martin martin 4096 Aug 19 15:04 maven-status
drwxrwxr-x 3 martin martin 4096 Aug 19 15:04 modules
-rw-rw-r-- 1 martin martin 15619 Aug 19 15:04 platform-jar-1.0-SNAPSHOT.amp
-rw-rw-r-- 1 martin martin 19446 Aug 19 15:04 platform-jar-1.0-SNAPSHOT.jar
drwxrwxr-x 11 martin martin 4096 Aug 19 15:04 platform-war
-rw-rw-r-- 1 martin martin 161544116 Aug 19 15:05 platform.war
drwxrwxr-x 4 martin martin 4096 Aug 19 15:04 test-classes
drwxrwxr-x 6 martin martin 4096 Aug 19 15:05 tomcat
It is possible to use this Platform JAR project with older Alfresco versions, such as 4.2, 5.0, and 5.1.
By default the SDK 3 Platform JAR project is configured to use Alfresco Platform (alfresco.war) version 5.2.a-EA and Share Services 5.1.g.
Important! Start from a newly generated SDK 3 Platform JAR project.
Now, let’s try with version 5.1. From this version the Platform webapp and the Share user interface webapp have different version numbering, and the artifactId for the Platform changes. It is not until version 5.2.a-EA of the platform that the version numbers deviate though. Let’s use version 5.1.e. To use this version open up the pom.xml file and update the following properties:
<alfresco.platform.version>5.1.e</alfresco.platform.version>
<alfresco.share.version>5.1.e</alfresco.share.version>
Note that the Platform and Share UI versions are the same for this release.
Now delete the alf_data_dev directory and restart:
platform-jar$ rm -rf alf_data_dev/
platform-jar$ mvn clean install -DskipTests=true alfresco:run
Access the webapps as usual:
http://localhost:8080/alfresco
The generated Platform JAR project comes with sample Web Script.
Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
So, changing Alfresco version and running was very easy, basically just updating a few properties.
Important! Start from newly generated SDK 3 Platform JAR project.
For Alfresco version 5.0 the alfresco.war and share.war have the same version number, such as 5.0.d. To use this version open up the pom.xml file and update the following properties:
<alfresco.platform.war.artifactId>alfresco</alfresco.platform.war.artifactId>
<alfresco.platform.version>5.0.d</alfresco.platform.version>
<alfresco.share.version>5.0.d</alfresco.share.version>
Note that the platform war artifactId is different in older versions (Alfresco Maven plugin will handle this, but for consistency it is good to update it).
Also, the Alfresco Share Services AMP that is applied to the platform war (i.e. alfresco.war) was introduced in version 5.1, so we need to remove it/comment it out from the Alfresco Maven Plugin configuration:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition, change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>community</alfrescoEdition>
<!-- We need the flat file H2 database to run the Repo -->
<enableH2>true</enableH2>
<!-- This is a platform extension JAR, so we need the platform webapp (alfresco.war) -->
<enablePlatform>true</enablePlatform>
<!-- Enable Solr so we can use search, our Repo extension probably need search -->
<enableSolr>true</enableSolr>
<!-- We don't need the share.war if we don't have any UI extensions -->
<enableShare>false</enableShare>
<!--
JARs and AMPs that should be overlayed/applied to the Platform/Repository WAR
(i.e. alfresco.war)
No need to include our self...
-->
<platformModules>
<!-- This AMP is needed if we are going to access the platform webapp from a Share webapp
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share-services</artifactId>
<version>${alfresco.share.version}</version>
<type>amp</type>
</moduleDependency>
-->
</platformModules>
</configuration>
</plugin>
Note. the Alfresco Maven Plugin is actually smart enough to know that you are not running a 5.1 version or newer, and will not apply the alfresco-share-services AMP from the above configuration even if you leave it in. It is just more clear when you comment it out. But if you are going to switch back and forth between versions you can leave the AMP config in, the plugin knows when to apply it and when not to.
Now delete the alf_data_dev directory and restart:
platform-jar$ rm -rf alf_data_dev/
platform-jar$ mvn clean install -DskipTests=true alfresco:run
Access the webapp as usual:
http://localhost:8080/alfresco
The generated Platform JAR project comes with a sample Web Script.
Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
So again, changing Alfresco version and running was very easy, basically just updating a few properties and changing some other XML configuration.
Important! Start from newly generated SDK 3 Platform JAR project.
So how about going all the way back to 4.2? Is that possible? Yes it is, it is going to require a bit more work but it is possible!
For Alfresco version 4.2 the alfresco.war and share.war artifacts have the same version number, such as 4.2.f. To use this version open up the pom.xml file and update the following properties:
<alfresco.platform.war.artifactId>alfresco</alfresco.platform.war.artifactId>
<alfresco.platform.version>4.2.f</alfresco.platform.version>
<alfresco.share.version>4.2.f</alfresco.share.version>
Note that the platform war artifactId is different in older versions.
Also, the Alfresco Share Services AMP that is applied to the platform war (i.e. alfresco.war) was introduced in version 5.1, so we need to remove it/comment it out from the Alfresco Maven Plugin configuration:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition, change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>community</alfrescoEdition>
<!-- We need the flat file H2 database to run the Repo -->
<enableH2>true</enableH2>
<!-- This is a platform extension JAR, so we need the platform webapp (alfresco.war) -->
<enablePlatform>true</enablePlatform>
<!-- Enable Solr so we can use search, our Repo extension probably need search -->
<enableSolr>true</enableSolr>
<!-- We don't need the share.war if we don't have any UI extensions -->
<enableShare>false</enableShare>
<!--
JARs and AMPs that should be overlayed/applied to the Platform/Repository WAR
(i.e. alfresco.war)
No need to include our self...
-->
<platformModules>
<!-- This AMP is needed if we are going to access the platform webapp from a Share webapp
<moduleDependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share-services</artifactId>
<version>${alfresco.share.version}</version>
<type>amp</type>
</moduleDependency>
-->
</platformModules>
</configuration>
</plugin>
Note. the Alfresco Maven Plugin is actually smart enough to know that you are not running a 5.1 version or newer, and will not apply the alfresco-share-services AMP from the above configuration even if you leave it in. It is just more clear when you comment it out. But if you are going to switch back and forth between versions you can leave the AMP config in, the plugin knows when to apply it and when not to.
Update indexing subsystem to Solr 1, in src/test/properties/local/alfresco-global.properties update the following property:
index.subsystem.name=solr
Set database configuration parameters, need to emulate PostgreSQL, in pom.xml:
<alfresco.db.params>MODE=PostgreSQL;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;MVCC=TRUE</alfresco.db.params>
Finally, change Alfresco module versions to not use SNAPSHOT versions as these are not supported in 4.2, update the src/main/resources/alfresco/module/platform-jar/module.properties file:
module.version=1.0
Now delete the alf_data_dev directory and restart:
platform-jar$ rm -rf alf_data_dev/
platform-jar$ mvn clean install -DskipTests=true alfresco:run
Access the webapp as usual:
http://localhost:8080/alfresco (Alfresco Explorer is available in 4.2):
The generated Platform JAR project comes with a sample Web Script.
Try out the Web Script as follows (http://localhost:8080/alfresco/service/sample/helloworld😞
It uses both a Java and JavaScript controller.
So again, changing Alfresco version and running was not that complicated, it’s a bit more work for 4.2 but doable.
This section covers how to use the new SDK 3 Share Jar project.
To generate a project based on the Share JAR Maven archetype do the following (make sure Maven environment is setup properly😞
martin@gravitonian:~$ mvn archetype:generate -DarchetypeCatalog=https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -Dfilter=org.alfresco.maven.archetype:
...
Choose archetype:
1: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-amp-archetype (Sample project with full support for lifecycle and rapid development of AMPs (Alfresco Module Packages))
2: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-allinone-archetype (Sample multi-module project for All-in-One development on the Alfresco plaftorm. Includes modules for: Repository WAR overlay, Repository AMP, Share WAR overlay, Solr configuration, and embedded Tomcat runner)
3: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:share-amp-archetype (Share project with full support for lifecycle and rapid development of AMPs (Alfresco Module
Packages))
4: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-platform-jar-archetype (Sample project with full support for lifecycle and rapid development of Platform/Repository JARs and AMPs (Alfresco Module Packages))
5: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-share-jar-archetype (Share project with full support for lifecycle and rapid development of JARs and AMPs (Alfresco Module
Packages))
6: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:activiti-jar-archetype (Sample project with full support for lifecycle and rapid development of Activiti JARs)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 5
Define value for property 'groupId': : org.alfresco.test
Define value for property 'artifactId': : share-jar
[INFO] Using property: version = 1.0-SNAPSHOT
Define value for property 'package': org.alfresco.test: : <hit enter>
Confirm properties configuration:
groupId: org.alfresco.test
artifactId: share-jar
version: 1.0-SNAPSHOT
package: org.alfresco.test
Y: : <hit enter>
Here we choose the first archetype (5) called alfresco-share-jar-archetype. Then we specify Maven groupId and artifactId for the new project, this can be whatever you like. We use the same Java package path as groupId.
This generates a project structure as follows:
.
├── debug.bat
├── debug.sh
├── pom.xml
├── README.md
├── run.bat
├── run.sh
└── src
├── main
│ ├── assembly
│ │ ├── amp.xml
│ │ ├── file-mapping.properties
│ │ ├── lib
│ │ │ └── README.md
│ │ └── web
│ │ └── README.md
│ ├── java
│ │ └── org
│ │ └── alfresco
│ │ └── test
│ └── resources
│ ├── alfresco
│ │ ├── module
│ │ │ └── share-jar
│ │ │ └── module.properties
│ │ └── web-extension
│ │ ├── messages
│ │ │ └── share-jar.properties
│ │ ├── share-jar-slingshot-application-context.xml
│ │ ├── site-data
│ │ │ └── extensions
│ │ │ └── share-jar-example-widgets.xml
│ │ └── site-webscripts
│ │ ├── com
│ │ │ └── example
│ │ │ └── pages
│ │ │ ├── simple-page.get.desc.xml
│ │ │ ├── simple-page.get.html.ftl
│ │ │ └── simple-page.get.js
│ │ └── org
│ │ └── alfresco
│ │ └── README.md
│ └── META-INF
│ ├── resources
│ │ └── share-jar
│ │ └── js
│ │ └── tutorials
│ │ └── widgets
│ │ ├── css
│ │ │ └── TemplateWidget.css
│ │ ├── i18n
│ │ │ └── TemplateWidget.properties
│ │ ├── templates
│ │ │ └── TemplateWidget.html
│ │ └── TemplateWidget.js
│ └── share-config-custom.xml
└── test
├── java
│ └── org
│ └── alfresco
│ └── test
└── resources
The alfresco/web-extension and alfresco/module directories are probably familiar to most people, but the location of them is a bit different from when the SDK used AMPs. Also, best practice now also says that web resources should go in under META-INF/resources/<module-id>. All the webapp assembly and runner logic is now also handled by the Alfresco Maven Plugin. So you are probably thinking, if there are no WAR projects and no amp-to-war profile (the project does not extend an SDK parent POM with profiles), how do I configure what JARs and AMPs that should be applied to the standard share.war?
The Alfresco Maven Plugin now provides an extra configuration section <shareModules> where you can specify what modules should be applied to the Share.WAR file:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition, change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>community</alfrescoEdition>
<!-- We assume that the platform/repository is already running on localhost:8080 -->
<enableH2>false</enableH2>
<enablePlatform>false</enablePlatform>
<enableSolr>false</enableSolr>
<!-- Enable the Share webapp, which is what we customize with Share JAR modules -->
<enableShare>true</enableShare>
<!--
JARs and AMPs that should be overlayed/applied to the Share WAR
(i.e. share.war)
No need to include our self...
-->
<shareModules>
<moduleDependency>
<!-- Bring in a newer version, can coexist with older versions in the WAR disttribution,
newest version is picked. -->
<groupId>${alfresco.groupId}</groupId>
<artifactId>aikau</artifactId>
<version>${aikau.version}</version>
</moduleDependency>
</shareModules>
</configuration>
</plugin>
Before you can run the Share JAR project you need to have an Alfresco Platform server running that it can talk to. The easiest way to do that is probably to generate and run a Platform JAR project.
To run the new Share JAR project step into the directory and execute the following command:
$ cd share-jar/
share-jar$ mvn clean install alfresco:run
Note the new way of running the project via the alfresco plugin instead of via a Maven profile.
Access the webapp as usual, note the port 8081:
The generated Share JAR project comes with a sample code Aikau page.
The Aikau page can be accessed as follows (http://localhost:8081/share/page/user/admin/dashboard😞
The Aikau page also includes a sample Aikau widget.
If you would like to work with the Alfresco Enterprise Edition, then this requires just a few property changes. You also need to have access to the private Alfresco Nexus repos. To configure access to private repos see these docs.
Configure Enterprise version in pom.xml, let’s use Share version 5.1.1 (the surf version is slightly older than the default one in SDK 3):
<alfresco.share.version>5.1.1</alfresco.share.version>
<alfresco.surf.version>6.3</alfresco.surf.version>
If you are unclear of what Surf version that is used, then install the Alfresco version you will be using and do a search in WEB-INF/lib as follows:
martin@gravitonian:/opt/alfresco511/tomcat/webapps/share/WEB-INF/lib$ ls -l *surf*
-rw-rw-r-- 1 martin martin 870024 Jul 13 10:49 spring-surf-6.3.jar
-rw-rw-r-- 1 martin martin 38968 Jul 13 10:51 spring-surf-api-6.3.jar
Change the Alfresco Edition property in the Alfresco Maven plugin configuration to enterprise, this is also done in pom.xml:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- Default is to run with a Community edition,
change to 'enterprise' if using Enterprise edition -->
<alfrescoEdition>enterprise</alfrescoEdition>
. . .
Note. there is no longer a need to update any of the run.* scripts to use an Enterprise edition. This was previously necessary when the Enterprise edition was enabled via a profile.
Now restart:
share-jar$ mvn clean install alfresco:run
Access the webapp as usual (username: admin, pwd: admin):
The generated Share JAR project comes with a sample Aikau page.
The Aikau page can be accessed as follows (http://localhost:8081/share/page/hdp/ws/simple-page😞
It shows how to create an Aikau page with a custom Aikau widget on it.
So, changing Alfresco version and running was very easy, basically just updating a few properties.
See the share logging section in the AIO docs
Hot reloading for share extensions are described in detail in this section.
This is described in detail in this section.
This is described in this section.
This is described in detail in this section.
This is described in detail in this section.
TODO
As the project does not have any WAR POMs you are probably wondering if the customized WAR that we are running with is available somewhere. It is, in the /target directory you will find the customized WAR:
share-jar/target$ ls -l
total 87744
drwxrwxr-x 2 martin martin 4096 Aug 19 16:09 apache-tomcat-maven-plugin
drwxrwxr-x 2 martin martin 4096 Aug 19 16:08 archive-tmp
drwxrwxr-x 4 martin martin 4096 Aug 19 16:07 classes
drwxrwxr-x 2 martin martin 4096 Aug 19 16:08 dependency-maven-plugin-markers
drwxrwxr-x 2 martin martin 4096 Aug 19 16:08 maven-archiver
drwxrwxr-x 3 martin martin 4096 Aug 19 16:07 maven-status
-rw-rw-r-- 1 martin martin 8902 Aug 19 16:08 share-jar-1.0-SNAPSHOT.amp
-rw-rw-r-- 1 martin martin 13203 Aug 19 16:08 share-jar-1.0-SNAPSHOT.jar
drwxrwxr-x 14 martin martin 4096 Aug 19 16:08 share-war
-rw-rw-r-- 1 martin martin 89783248 Aug 19 16:09 share.war
drwxrwxr-x 2 martin martin 4096 Aug 19 16:07 test-classes
drwxrwxr-x 6 martin martin 4096 Aug 19 16:09 tomcat
It is possible to use this Share JAR project with older Alfresco versions, such as 4.2, 5.0, and 5.1.
By default the SDK 3 Share JAR project is configured to use Share (share.war) version 5.1.g.
Important! Start from a newly generated SDK 3 Share JAR project.
Now, let’s try with version 5.1. Let’s use version 5.1.e:
<alfresco.share.version>5.1.e</alfresco.share.version>
<alfresco.surf.version>6.3</alfresco.surf.version>
The Surf version is different from what we have for 5.1.g (share.war), it is 6.3 for 5.1.e instead of 6.5. If you are unclear of what Surf version that is used, then install the Alfresco version you will be using and do a search in WEB-INF/lib as follows:
martin@gravitonian:/opt/alfresco51f/tomcat/webapps/share/WEB-INF/lib$ ls -l *surf*
-rw-rw-r-- 1 martin martin 870024 Apr 22 23:33 spring-surf-6.3.jar
-rw-rw-r-- 1 martin martin 38968 Apr 22 23:34 spring-surf-api-6.3.jar
Now restart:
share-jar$ mvn clean install -DskipTests=true alfresco:run
Access the webapp as usual:
The Aikau page can be accessed as follows (http://localhost:8081/share/page/hdp/ws/simple-page😞
It includes a sample Aikau widget.
So, changing Alfresco version and running was very easy, basically just updating a few properties.
Important! Start from newly generated SDK 3 Share JAR project.
For Alfresco version 5.0 the share.war and surf artifacts have the same version number, such as 5.0.d. To use this version open up the pom.xml file and update the following properties:
<alfresco.share.version>5.0.d</alfresco.share.version>
<alfresco.surf.version>5.0.d</alfresco.surf.version>
If you are unclear of what Surf version that is used, then install the Alfresco version you will be using and do a search in WEB-INF/lib as follows:
martin@gravitonian:/opt/alfresco50d/tomcat/webapps/share/WEB-INF/lib$ ls -l *surf*
-rw-rw-r-- 1 martin martin 831228 Mar 19 2015 spring-surf-5.0.d.jar
-rw-rw-r-- 1 martin martin 38980 Mar 19 2015 spring-surf-api-5.0.d.jar
The Spring Surf project at this time was part of the Spring Framework extensions (now it is an Alfresco project). Update the Spring Surf API dependency with the Spring Framework group ID, in the file pom.xml:
<dependencies>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>${alfresco.share.war.artifactId}</artifactId>
<classifier>classes</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.extensions.surf</groupId>
<artifactId>spring-surf-api</artifactId>
<version>${alfresco.surf.version}</version>
<scope>provided</scope>
</dependency>
Now restart:
share-jar$ mvn clean install -DskipTests=true alfresco:run
Access the webapp as usual:
The Aikau page can be accessed as follows (http://localhost:8081/share/page/hdp/ws/simple-page😞
It includes a sample Aikau widget.
So again, changing Alfresco version and running was very easy, basically just updating a few properties and changing some other XML configuration.
Important! Start from newly generated SDK 3 Share JAR project.
So how about going all the way back to 4.2? Is that possible? Yes it is, it is going to require a bit more work but it is possible!
For Alfresco version 4.2 we will try version 4.2.f. To use this version open up the pom.xml file and update the following properties:
<alfresco.share.version>4.2.f</alfresco.share.version>
The way we depend on Share classes and files from the Share JAR is different in version 4.2.f. In the Share JAR project update the dependencies completely, so they look like this instead, in the file pom.xml:
<!--
Include libs that the Share JAR extension will use.
They are mostly provided by Alfresco during runtime so scope should be set as provided
(if in doubt then check for the lib in tomcat/webapps/share/WEB-INF/lib,
if it's there then it's provided).
-->
<dependencies>
<!-- Include JAR that has classes such as BaseEvaluator -->
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco-share</artifactId>
<version>${alfresco.share.version}</version>
<scope>provided</scope>
<exclusions>
<!-- Exclude org.alfresco:alfresco-web-framework-commons:jar:classes:4.2.f
dependency -->
<exclusion>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-web-framework-commons</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Bring in the correct version of alfresco-web-framework-commons -->
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-web-framework-commons</artifactId>
<version>${alfresco.share.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
Finally, change Alfresco module versions to not use SNAPSHOT versions as these are not supported in 4.2, update src/main/resources/alfresco/module/share-jar/module.properties file:
module.version=1.0
Now restart:
share-jar$ mvn clean install -DskipTests=true alfresco:run
Access the webapp as usual:
The Aikau page can be accessed as follows (http://localhost:8081/share/page/hdp/ws/simple-page😞
It includes a sample Aikau widget.
So again, changing Alfresco version and running was not that complicated, it’s a bit more work for 4.2 but doable.
This section covers how to use the new SDK 3 Activiti Enterprise JAR Module project. Note. It has not yet been tested with the Activiti Open Source version.
Make sure the Maven environment is setup properly. And that you have the Alfresco Activiti private Nexus repo login in your settings.xml:
<server>
<id>activiti-private-repository</id>
<username>****</username>
<password>****</password>
</server>
<server>
<id>pentaho-private-repository</id>
<username>****</username>
<password>****</password>
</server>
The username and password can be requested via Activiti Enterprise Support.
To generate a project based on the Activiti JAR Maven archetype do the following:
$ mvn archetype:generate -DarchetypeCatalog=https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -Dfilter=org.alfresco.maven.archetype:
…
Choose archetype:
1: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-amp-archetype (Sample project with full support for lifecycle and rapid development of AMPs (Alfresco Module Packages))
2: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-allinone-archetype (Sample multi-module project for All-in-One development on the Alfresco plaftorm. Includes modules for: Repository WAR overlay, Repository AMP, Share WAR overlay, Solr configuration, and embedded Tomcat runner)
3: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:share-amp-archetype (Share project with full support for lifecycle and rapid development of AMPs (Alfresco Module
Packages))
4: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-platform-jar-archetype (Sample project with full support for lifecycle and rapid development of Platform/Repository JARs and AMPs (Alfresco Module Packages))
5: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:alfresco-share-jar-archetype (Share project with full support for lifecycle and rapid development of JARs and AMPs (Alfresco Module
Packages))
6: https://artifacts.alfresco.com/nexus/content/groups/public/archetype-catalog.xml -> org.alfresco.maven.archetype:activiti-jar-archetype (Sample project with full support for lifecycle and rapid development of Activiti JARs)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 6
Define value for property 'groupId': : org.alfresco.test
Define value for property 'artifactId': : activiti-jar
[INFO] Using property: version = 1.0-SNAPSHOT
Define value for property 'package': org.alfresco.test: : <hit enter>
Confirm properties configuration:
groupId: org.alfresco.test
artifactId: activiti-jar
version: 1.0-SNAPSHOT
package: org.alfresco.test
Y: : <hit enter>
Here we choose the first archetype (6) called activiti-jar-archetype. Then we specify Maven groupId and artifactId for the new project, this can be whatever you like. We use the same Java package path as groupId.
This generates a project structure as follows:
.
├── debug.bat
├── debug.sh
├── pom.xml
├── README.md
├── run.bat
├── run.sh
└── src
├── main
│ ├── java
│ │ └── org
│ │ └── alfresco
│ │ └── test
│ │ └── tasks
│ │ └── service
│ │ └── HelloWorldServiceTask.java
│ └── resources
│ └── apps
│ └── helloworld
│ ├── bpmn-models
│ │ ├── Hello World-2005.bpmn20.xml
│ │ ├── Hello World-2005.json
│ │ └── Hello World-2005.png
│ ├── decision-table-models
│ │ ├── Decide What Greeting-2007.json
│ │ └── Decide What Greeting-2007.png
│ ├── form-models
│ │ ├── Hello World Start-2006.json
│ │ └── Hello World Start-2006.png
│ └── Hello World.json
└── test
├── java
│ └── org
│ └── alfresco
│ └── test
├── license
│ └── README.md
└── resources
├── activiti-app.properties
├── activiti-ldap.properties
├── log4j-dev.properties
└── log4j-test.properties
The project contains a sample Hello World Activiti application. The application contains a business process definition, a form, and a decision table. The structure matches what you get in an application ZIP exported from the Activiti user interface. There is also a Service Task Java delegate implementation included.
The test files contains configuration for running Activiti Enterprise locally. All the webapp assembly and runner logic is handled by the Alfresco Maven Plugin. So you are probably thinking, if there is no WAR project, how do I configure what JARs that should be applied to the standard activiti-app.war (i.e. with classes for service task delegates, task listeners etc)?
The Alfresco Maven Plugin provides a configuration section <activitiModules> where you can specify what modules should be applied to the Activiti-app.WAR file:
<plugin>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
<configuration>
<!-- We need the flat file H2 database to run Activiti -->
<enableH2>true</enableH2>
<!-- Bring in the Activiti Workflow Engine and Management webapp
(i.e. activiti-app.war) -->
<enableActivitiApp>true</enableActivitiApp>
<!-- Optionally bring in the Activiti Admin App (i.e. activiti-admin.war) -->
<enableActivitiAdmin>false</enableActivitiAdmin>
<!-- Disable all Alfresco ECM apps by default -->
<alfrescoEdition>community</alfrescoEdition>
<enablePlatform>false</enablePlatform>
<enableSolr>false</enableSolr>
<enableShare>false</enableShare>
<!--
JARs that should be overlayed/applied to the Activiti App WAR
(i.e. activiti-app.war)
-->
<activitiModules>
<!-- Bring in this JAR project -->
<moduleDependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</moduleDependency>
</activitiModules>
</configuration>
</plugin>
It is possible to also deploy the activiti-admin.war webapp when running, just set the <enableActivitiAdmin> property to true.
This project is configured to run with an Alfresco Activiti Enterprise edition. So it will not work to start it up without a proper Enterprise license applied. Add the license to the following directory in the Maven project structure:
└── src
└── test
├── license
│ ├── activiti.lic
│ └── README.md
To run the new Activiti JAR project, step into the directory and execute the following command:
$ cd activiti-jar/
activiti-jar$ mvn clean install alfresco:run
This will build the following two artefacts in the /target directory:
The Alfresco Maven plugin will assemble the activiti-app.war with the activiti-jar-1.0-SNAPSHOT.jar applied. Note. the Activiti application is not automatically deployed, it needs to be done manually via the UI, see later on.
Access the Activiti webapp with the following URL:
http://localhost:8080/activiti-app:
Login with admin@app.activiti.com/koala. The password can be changed via the activiti-jar/src/test/resources/activiti-app.properties configuration file. After a successful login the following Activiti home page is shown:
The page shows a number of tiles/portlets/dashlets, or whatever you want to call them. Each one represents an Activiti application. We can deploy our HelloWorld application, which was assembled as a zip during the build, by clicking on the Kickstart App:
And then on the Apps menu item, which will show us all installed process applications:
Click on the Import App button in the upper right corner to import our HelloWorld app:
Select the ZIP project artifact.
If all goes well we should now see the Hello World application imported. We cannot however use it yet. It needs to be published as a certain version before we can try out the Hello World process that it represent. Click the Publish button and answer yes to publish the application. If we now navigate to the Activiti home page again we should see our new application:
Click on the Hello World application:
From this page we can start new HelloWorld workflow instances, we can see any tasks assigned to logged in user related to any HelloWorld workflow instance (note. The HelloWorld workflow does not have any user tasks…), inspect completed HelloWorld workflow instances etc.
To start a new HelloWorld workflow instance click on the START menu item:
The Workflow start form is very simple and just asks for two values, a greeting string and a time of day value from a dropdown. Ones we have filled them out we can click on the START PROCESS button to kick things off:
This workflow only have a start task and then a service task and a script task. So it completes without further interaction. And we can inspect the decision table result and other variables.
Looking at the logs should reveal printouts from both the Service Task and the Script task:
02:03:58,175 [http-bio-8080-exec-5] INFO com.activiti.dmn.engine.impl.deployer.DmnDeployer - Processing resource decidewhatgreeting.dmn
02:03:58,208 [http-bio-8080-exec-5] INFO org.activiti.engine.impl.bpmn.deployer.BpmnDeployer - Processing resource helloworld.bpmn
02:10:49,496 [http-bio-8080-exec-5] DEBUG org.alfresco.test.tasks.service.HelloWorldServiceTask - Hello World from the Java Service Task!
Hello World from JavaScript task:
Good Day! Administrator
You entered 'Hello World!' as a greeting text.
Any updates to the HelloWorld application, whether it be the process defintion, form definition, decision table etc. should be done from the Activiti App UI. Then export the application files from the UI and update your build project. This is specifically important if you change the process definition (BPMN 2) as it will be present in both a JSON file and in a .bpmn20.xml file in an Activiti application.
After some part of an application has been updated it need to be published again for it to take effect.
Set logging levels in the activiti-jar/src/test/resources/log4j-dev.properties file. The log file can be found here: activiti-jar/target/activiti.log
TODO
TODO
TODO
As the project does not have any WAR POM you are probably wondering if the customized WAR that we are running with is available somewhere. It is, in the /target directory you will find the customized WAR:
activiti-jar/target$ ls -l
total 170432
drwxrwxr-x 16 martin martin 4096 Sep 30 13:49 activitiApp-war
-rw-rw-r-- 1 martin martin 174437488 Sep 30 13:49 activitiApp.war
-rw-rw-r-- 1 martin martin 5959 Sep 30 13:49 activiti-jar-1.0-SNAPSHOT.jar
-rw-rw-r-- 1 martin martin 13024 Sep 30 13:49 activiti-jar-app-1.0-SNAPSHOT.zip
-rw-rw-r-- 1 martin martin 16287 Sep 30 14:19 activiti.log
drwxrwxr-x 2 martin martin 4096 Sep 30 13:49 apache-tomcat-maven-plugin
drwxrwxr-x 3 martin martin 4096 Sep 30 13:49 classes
drwxrwxr-x 2 martin martin 4096 Sep 30 13:49 dependency-maven-plugin-markers
drwxrwxr-x 3 martin martin 4096 Sep 30 13:49 generated-sources
drwxrwxr-x 2 martin martin 4096 Sep 30 13:49 maven-archiver
drwxrwxr-x 3 martin martin 4096 Sep 30 13:49 maven-status
drwxrwxr-x 2 martin martin 4096 Sep 30 13:49 test-classes
drwxrwxr-x 6 martin martin 4096 Sep 30 13:50 tomcat
This sections covers upgrading SDK 2.2 projects to SDK 3.0
/home/martin/src/alfresco-sdk-samples/all-in-one/add-metadata-template-doclib-share/src/main/resources/META-INF/resources/add-metadata-template-doclib-share/components
<config evaluator="string-compare" condition="DocLibCustom">
<dependencies>
<js src="resources/add-metadata-template-doclib-share/components/documentlibrary/custom-metadata-template-renderer.js"/>
</dependencies>
</config>
/home/martin/src/alfresco-sdk-samples/all-in-one/add-aikau-dashlet-share/src/main/resources/META-INF/resources/add-aikau-dashlet-share/js
<dojo-pages>
<packages>
<package name="acmedashlets" location="resources/add-aikau-dashlet-share/js/tutorials/dashlets"/>
<package name="acmewidgets" location="resources/add-aikau-dashlet-share/js/tutorials/dashlets/widgets"/>
</packages>
</dojo-pages>