Developer tips for Alfresco Share 3.3

With Alfresco 3.3, the Share content collaboration platform has never been easier to develop for! With the integration of SpringSurf in Alfresco 3.3, plus a number of improved debugging features, the edit->test->debug development cycle for Share pages and components is more rapid than ever. Once set-up, it can take literally seconds to see the results of changes to any WebScripts, templates, JavaScript or CSS files. This post is a collection of tips direct from Alfresco Engineering on how to set-up your environment, tweak the default Share configuration, debug scripts and enable the fastest possible development cycle.

Get the Tools You Need

Your favorite developers text editor. Obviously. But that’s pretty much all you need to work with Alfresco WebScripts, FreeMarker templates and JavaScript text files – you don’t need anything heavier, but something like Eclipse or IntelliJ will do nicely if you prefer.

Firefox plus the Firebug extension or Google Chrome – because of the nifty HTML, CSS inspection and JavaScript debugging features. Most Alfresco devs prefer the Firefox+Firebug combination as the features are currently stronger than the dev tools built into Chrome, and it gives more accurate and descriptive JavaScript errors – but Chrome is catching up with every release and it’s certainly noticably faster at processing JavaScript and general rendering.

Setting up a Folder Structure

See this previous post on how to set-up your folder structure for creating Share pages, components and WebScripts. It also discusses using the SpringSurf resource servlet to easily access web assets such as images, CSS and client-side JavaScript in your templates and components from within the same folder structure.

During Development Deploy Files and Folders – not a JAR!

Create a quick shell or ant script to copy your working files and folder structure to your tomcat Share classes folder. You can then work on your assets easily and quickly deploy them all to a running Alfresco server. The previous post describes how to package them up for run-time deployment as a single JAR – but that isn’t needed during development, and in fact isn’t really desirable – having the files and folders expanded out ensures quicker deployment and ensures the various config options discussed below will work correctly.

share-config-custom.xml

Share is configured by various Spring config files and Alfresco format config files. These are easy enough to override. There’s really only one file you need to worry about for most situations. The default config override file that Share is already set-up to look for is called share-config-custom.xml and should be placed in your $TOMCAT_HOME$/shared/classes/alfresco/web-extension folder. Here you can override various configuration settings and several of the most useful ones for development and debugging will be discussed here. If you do want to override Spring beans, then Share will look for a file called custom-slingshot-application-context.xml and it should be placed in the same folder. Generally unless you are modifying Surf internals you won’t need to override the Spring beans.

A default installation of Alfresco will include a .sample version of these files in the above location, they can also be found in the source tree: HEAD/root/projects/slingshot/config/alfresco/web-extension

Debugging client-side JavaScript

Here’s an example of a share-config-custom.xml file with the correct config to turn on client-side JavaScript debugging. You may be wondering why you need to do this, after all surely it’s just a matter of turning on FireBug and getting on with it? But for performance reasons, Share will include minimized versions of its client-side JavaScript files during page rendering – it will even combine some of the files – which don’t make for useful debugging. Turning on the client-debug flag forces Share to load the original uncompressed source with all comments and formatting intact, perfect for debugging into. It also ensures the various YUI library files are uncompressed – if you are feeling brave enough to poke around in them.

   <alfresco-config>

      <!-- Global config section -->
      <config replace="true">
         <flags>
            <!-- Developer debugging setting - DEBUG mode for client scripts in the browser -->
            <client-debug>true</client-debug>

            <!-- LOGGING can be toggled at runtime when in DEBUG mode (Ctrl, Ctrl, Shift, Shift).
                 This flag automatically activates logging on page load. -->
            <client-debug-autologging>false</client-debug-autologging>
         </flags>
      </config>

   </alfresco-config>

Restarting the server is required if you make changes to this file. Force a refresh of Share in your browser and you will then be able to use FireBug or the Chrome debugger tool to set breakpoints and debug the client-side JavaScript of Share components.

You’ll notice the client-debug-autologging flag in the example above. There is a logging feature in Share that allows a developer to make use of log4j style debugging methods in client-side JavaScript. It’s not a commonly used feature as it’s pretty low-level, but if you can’t solve your issue with breakpoint style debugging then logging may be useful. The flag is used to automatically active the logging output window in Share rather than having to toggle it with a funky key combination.

To log from within your client-side JavaScript:

if (Alfresco.logger.isDebugEnabled())
   Alfresco.logger.debug("some string value");

The log4j info, warn, error and fatal levels can be used if required.

SpringSurf Development Mode

SpringSurf has a number of autowire configuration modes. By default Share is configured in the “production” mode – this ensures that web-tier JavaScript and FreeMarker templates are compiled and cached for maximum performance. For development, it is much more useful to have JavaScript and templates not cached. As mentioned above this allows simple scripts to quickly copy over new versions of files and see the results immediately in the application – no restarts required.

This is an example of the config required for share-config-custom.xml:

   <alfresco-config>

       <config evaluator="string-compare" condition="WebFramework">
           <web-framework>
               <!-- Autowire Runtime Settings -->
               <autowire>
                   <!-- Pick the mode: development, preview, production -->
                   <mode>development</mode>
               </autowire>
           </web-framework>
       </config>

   </alfresco-config>

Web-Tier JavaScript debugging

Share SpringSurf components are simply a special case of an Alfresco WebScript – with a few additional rules and restrictions on what objects are available and what presentation templates can output. The web-tier JavaScript controller associated with a WebScript can be debugged via the Rhino debugger window. Once “development” mode is activated as mentioned above, the script debugger will be able to break on JavaScript functions and breakpoints. To turn on the debugger, use the browser to navigate to /<yourserver>/share/service/index – this will display the WebScripts index page. Click the Alfresco JavaScript Debugger link and then Enable. A Java GUI window will appear, this is the Rhino debugger interface. The easiest way to get into the web-tier JavaScript is to select Debug->Break On Function Enter from the menus. The next WebScript that is executed in the app will break in the debugger. Once the appropriate source files are loaded breakpoints can be added and the Break On Function Enter can be disabled to reduce the noise during debugging.

Web-Tier Javascript Logging

Logging from within WebScript code can be another useful debugging aid. On both the Repository and Web-Tier, the “logger” root scoped JavaScript object is available for simple logging tasks. The output is directed to the App-Server console window.

logger object API:

boolean logger.isDebugEnabled() - returns true/false to indicate if debug logging output via log4j is active,
this can be used to ensure performance isn't degraded when console logging is inactive.
void logger.log(string message) - output a log message to the console

To turn on logging for your application, modify the log4j.properties file and set the following class to debug:

log4j.logger.org.alfresco.repo.jscript.ScriptLogger=debug

Note that the same logging class name is used by the Alfresco repository and SpringSurf – it is maintained for backward compatibility.

Refreshing WebScripts

On a production deployed instance of Share or any instance where all the various debug settings noted above are not applied, most caching and refresh issues can be quickly resolved without restarting the app-server. The Refresh WebScripts option in the Share WebScript index page can be used to clear the caches for all components and compiled scripts. It also means that additional WebScripts can be deployed or removed at runtime without restart. Use the browser to navigate to /<yourserver>/share/service/index – this will display the WebScripts index page. Click the Refresh Webscripts button to clear the caches and refresh the list of available WebScripts.

Separate Alfresco and Share Server Instances

Since Alfresco 3.0, the Share client is a stand-alone web-application and the share.war can be deployed on a separate TomCat instance to the Alfresco repository, on another server entirely if required. This is recommended for development and production. For development, it enables the Share application to be restarted quickly (a few seconds on a modern laptop or server) without interfering with the main Alfresco repository instance. For production, it allows proxies and clustering to be implemented.

The configuration to do this is simple, but first it requires the set-up of a new TomCat instance, with appropriate tweaks as recommended for an Alfresco server such as; JVM memory settings, server URIEncoding set to UTF-8, web-extension folder etc. The easiest way to do this is to take a copy of the Alfresco installed TomCat instance and remove the alfresco.war. If you are running the new TomCat instance on the same machine as the Alfresco repository instance then modify the port settings in tomcat/conf/server.xml to ensure Share can be started at the same time as Alfresco. Developers at Alfresco generally use port 8080 for Alfresco and port 8081 for Share.

By default the Share web-application will attempt to communicate with the Alfresco server via HTTP on port 8080. There should be no additional configuration required if you use those settings. However if your Alfresco instance is not running on this port then the following example of configuration for share-config-custom.xml can be used to modify the endpoint settings, change the endpoint-url values as appropriate:

   <!-- Overriding endpoints to reference a remote Alfresco server -->
   <config evaluator="string-compare" condition="Remote">
      <remote>
         <endpoint>
            <id>alfresco-noauth</id>
            <name>Alfresco - unauthenticated access</name>
            <description>Access to Alfresco Repository WebScripts that do not require authentication</description>
            <connector-id>alfresco</connector-id>
            <endpoint-url>http://localhost:8080/alfresco/s</endpoint-url>
            <identity>none</identity>
         </endpoint>

         <endpoint>
            <id>alfresco</id>
            <name>Alfresco - user access</name>
            <description>Access to Alfresco Repository WebScripts that require user authentication</description>
            <connector-id>alfresco</connector-id>
            <endpoint-url>http://localhost:8080/alfresco/s</endpoint-url>
            <identity>user</identity>
         </endpoint>

         <endpoint>
            <id>alfresco-feed</id>
            <name>Alfresco Feed</name>
            <description>Alfresco Feed - supports basic HTTP authentication via the EndPointProxyServlet</description>
            <connector-id>http</connector-id>
            <endpoint-url>http://localhost:8080/alfresco/s</endpoint-url>
            <basic-auth>true</basic-auth>
            <identity>user</identity>
         </endpoint>
      </remote>
   </config>

Conclusion

Hopefully this list of tips should help speed up development and improve your experience when customising and working with Alfresco Share components. In the next post we will explore the architecture of SpringSurf components, templates and page rendering.

11 thoughts on “Developer tips for Alfresco Share 3.3

  1. Pingback: uberVU - social comments

  2. Ken Barber

    Nice walk-through Kev. I’m a big fan of the Chrome javascript performance profiling, for the most part so I can blame the client side code when things go slowly :-).

    Reply
  3. Pingback: Most Tweeted Articles by CMS Experts: MrTweet

  4. Erik Winlöf

    When installing this on Alfresco Community 3.4a I needed to also do the following changes to run my servers separately:
    Changes assume you named your copy of tomcat to: “tomcat-app”.

    1. Change all ports in tomcat-app/conf/server.xml (i.e. adding +1 on each one works)

    2. Remove tomcat-app/conf/Catalina/localhost/alfresco.xml (to get rid of the warnings when Tomcat thinks that an “alfresco” webapp shall be found under webapps.

    3. Change the following line in tomcat-app/conf/catalina.properties from:
    shared.loader=/Applications/alfresco-3.4.a/tomcat/shared/classes
    to:
    shared.loader=${catalina.home}/shared/classes,${catalina.home}/shared/lib,${catalina.home}/shared/lib/*.jar
    …otherwise your own share-config-custom.xml in tomcat-app will be ignored.

    Note! If you have the records-management module installed it will have placed its own custom-slingshot-application-context.xml in tomcat-app/webapps/share/WEB-INF/classes/alfresco/web-extension where it overrides the “webscripts.resources” bean to add the dod5105.properties file. This means that even if you change thje name of your custom-slingshot-application-context.xml to my-custom-slingshot-application-context.xml that bean will still be overriden by records-management.

    Cheers,

    :: Erik

    Reply
  5. Kevin Roast Post author

    Thanks for that info Erik. Also you could extract the various WAR files from the installer, and replace ones in an existing 3.3 installation without any further changes.

    Reply
  6. Chris Clearfield

    Hi,
    I realized that this post is a bit late, but I just wanted to make sure it was safe to run a dev AND a production instance of share against the same version. I’m looking to develop some simple dashboard add ins and just getting into the process, and was a little uncertain of the above.

    i.e., can I have my local machine localhost:8080/share/ point to our production alfreso servier: alfresco:8080/.

    I’ve stood it up and it seems to work, but I’m worried that I’ll accidentally corrupt something.

    Regards,
    Chris

    Reply
  7. Kevin Roast Post author

    You should only really run versions of Share that match the version of Alfresco server – so if you Alfresco production server is the same code revision as your dev Share that is ok – otherwise then it is possible something unexpected might happen – the further the version differences between the two servers the more likely you will get a problem…

    Reply
  8. Jon Morgan

    I had a hard time getting the javascript debugger to load as you detailed above, was getting “Caused by: java.awt.HeadlessException”
    in the log when I tried to enable. Found this JIRA with the fix:

    https://issues.alfresco.com/jira/browse/ALF-14184

    had to remove “-Djava.awt.headless=true” from “tomcat/scripts/ctl.sh

    Just wanted to note this somewhere as I had a hard time to find the solution.

    -jon

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>