Packaging And Deploying Extensions

cancel
Showing results for 
Search instead for 
Did you mean: 

Packaging And Deploying Extensions

resplin
Intermediate
0 0 6,762

Page Needs Work {{Page Needs Work}}




Background


There are several ways of deploying extensions. The best method for your project will depend on how complex your extension is, how many extensions you will be deploying, your environment (such as which app server you are using), which version of Alfresco you are on, and your development culture.

Whatever approach you use, make sure you:


  • Track the history of your code using source control,
  • Track your static assets,
  • Keep your code separate from Alfresco code,
  • Use the extension and web-extension folders,
  • Isolate multiple customizations,
  • Be consistent,
  • Test all extensions in a non-production environment.

These habits will pay dividends such as:


  • Allow you to remove your customizations when troubleshooting an issue,
  • Ask for help from an Alfresco expert without confusing your code and Alfresco code,
  • Identify what needs to be audited during an Alfresco upgrade.

Packaging Approaches


AMP Files


Alfresco Module Packages are the recommended way of packaging Alfreco customizations and extensions. AMPs are zip files that follow a specific layout and can be merged with the alfresco.war and/or share.war using the Alfresco Module Management Tool (alfresco-mmt.jar).

Since July 2008 a Sourcesense contribution is available for building and packaging extensions into AMPs using Apache Maven (see Managing Alfresco Lifecyle with Maven).


Unpackaged Files or ZIP


Many development environments employ a build process that can execute a script to move unpackaged modified files from source control into the web application's exploded WAR file. Ant, bash, or some scripting language can all be good ways to do this.

Moving unpackaged files has the advantage of being quick and easy to understand, but it may be better to package the files into a zip artifact that will then be unzipped over the exploded WAR.

Note that this approach is not recommended for QA or production environments, as Tomcat (and potentially other app servers) may re-explode WAR files at unpredictable times, thereby overwriting any changes that have been installed on top.  This is one of the reasons that AMP files (see previous section) were created.


JAR


As of v3.4, the Share web application supports overrides that are packaged as JAR files. This allows multiple customizations to be isolated from each other, and order of selection can be predicted.  Static files such as JavaScript, CSS, or image files that would normally be placed in the web root of the Share application can also be packaged into these JARs.

To deploy these JARs, it is recommended to place them inside one or more AMPs (see previous section), and deploy them into the share.war file.  As mentioned above, installing these JARs directly into the exploded webapp is not recommended as Tomcat (and potentially other app servers) can (and will) overwrite your changes at unpredictable times.

While it's possible to avoid the overwriting problem (at least in Tomcat) by placing these JAR files in tomcat/shared/lib, this is also not recommended as this causes the JARs to be included on the classpath of every webapp installed in that Tomcat server (typically this means at least the Share webapp and the Alfresco repository webapp).  In fact since v6.0 Tomcat no longer provides a shared/lib directory by default, specifically because it is so problematic from a webapp isolation perspective.


Deployment Locations


Background


Any specific change can be deployed to various locations so as to override an Alfresco file.

All locations depend on the application server you are using.


Tomcat


Once the Tomcat server has been started, the application is exploded into   $TOMCAT_HOME/webapps/alfresco. Stop the server if it is running, copy the file to $TOMCAT_HOME/webapps/alfresco/WEB-INF/ and re-start Tomcat.

Beware that any time your app server re-deploys the alfresco.war file, your extension will be deleted and you will have to re-deploy it.

One solution is to use a permanently exploded deployment (instead of deploying an Alfresco  WAR file under /webapps). Create a directory called alfresco under the webapps directory and extract the contents of  alfresco.war into it.  Then copy your files to ../webapps/alfresco/WEB-INF/ and restart Tomcat. It is then recommended to remove the war file so that Tomcat can't redeploy and overwrite your changes.

Useful background information on how Tomcat resolves classpaths is here.


JBoss


In  JBoss, if you  deploy a  web application as a WAR file the application  gets exploded to  a  temporary directory each time the app server  starts. Thus there is   nowhere to copy the JAR file to. One solution is  to use an exploded   deployment. Create a directory called  alfresco.war under the   deploy directory and extract the contents  of   alfresco.war (the file) into it. Then  copy your   JAR file to   ...deploy/alfresco.war/WEB-INF/lib and restart  JBoss.


Shared Classpath Folder


Many  customizations can be placed on your application server's classpath,  such as Alfresco configuration files or properties files i.e.  web-client-config-custom.xml, and Spring  context files or webclient.properties.


  • For Tomcat, the shared classloader folder is $TOMCAT_HOME/shared/classes/alfresco/.
  • For JBoss, the shared classloader folder is $JBOSS_HOME/server/default/conf/alfresco/.

In this folder there are standard sub-directories:


  • extension: for changes to the repository or Alfresco Explorer UI,
  • web-extension: for changes to the Share UI,
  • messages: for localization strings.

Files which are packaged as a JAR would be placed in the appropriate lib such as $TOMCAT_HOME/shared/lib.

Files placed in these folders will overlay the relevant file in the appropriate WAR.


Caution


Be aware that files on the application server classpath will overlay all WARs in the application server. It is more predictable to put your files into the classpath for a specific WAR.

Because of web application sandboxing, Java classes which extend Alfresco's Java classes cannot be placed in the shared class loader. They must be in the class loader for the web application to which they apply.

Also note that in Tomcat 7 $TOMCAT_HOME/shared/lib is no longer on the default classpath as it is recommended to put your library in a context specific to your WAR.


WAR Specific Classpath


A better location for your changes would be in one of:


  • $TOMCAT_HOME/webapps/alfresco/WEB-INF/classes
  • $TOMCAT_HOME/webapps/alfresco/WEB-INF/lib (for JARs)
  • $TOMCAT_HOME/webapps/share/WEB-INF/classes
  • $TOMCAT_HOME/webapps/share/WEB-INF/lib (for JARs)

It is most common to patch the Alfresco and Share WAR files in order to put your code in the correct location in a way that is preserved through redeployments. This is what the apply_amps script accomplishes.


Considerations


Classes which are intended to be extended


Should you be building an Alfresco extension that you plan to redistribute, and you want to allow the consumers to modify your extension, it will need to be placed in the extension folder and not the web-extension folder. If customers want to extend your extension, their customizations will go in web-extension folder which will load after the customization you placed in the extension folder.


Alfresco configuration files


You can only have one identically named file on the classpath as only the last one will be used. For example, if you have multiple JARs with a web-client-config-custom.xml file in the alfresco/extension package the ClassLoader will load the last one it finds, which in turn, will result in unpredictable behavior. Furthermore, you can not guarantee the order in which files will be found.

In versions newer than 2.0, you can have multiple web-client-config-custom.xml files present in the system by placing them in the JAR file's META-INF folder. This change is part of the module management improvements made in 2.0


JSF configuration files


Unfortunately, to override JSF configuration differs depending on what you want to override. For whatever reason, JSF has a first one wins policy for navigation rules and a last one wins policy for managed beans.

We therefore provide hooks for JSF configuration at the start and the end of JSF initialisation. To hook in at the beginning (i.e. to override a navigation rule,) create a faces-config.xml and package the file within a JAR within the META-INF folder. To hook in at the end, create a faces-config-custom.xml file and copy it to the WEB-INF folder of the Alfresco web application (this should replace our empty placeholder file).

As a guide the table below shows which file JSF config should go to:












Override File and Location
Overriding navigation rules faces-config.xml in META-INF
Overriding managed beans faces-config-custom.xml in WEB-INF
New navigation rules Either
New managed beans Either

Packaging
Deployment
AMP