Developer tips for Alfresco Share 3.3

cancel
Showing results for 
Search instead for 
Did you mean: 

Developer tips for Alfresco Share 3.3

kevinr1
Established Member
0 11 4,159
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 Comments
blog_commenter
Active Member
Thanks, useful tips in your post. I think the upcoming Forms Development Kit, http://wiki.alfresco.com/wiki/Forms_Development_Kit will be handy too. Especially if it will support forms testing without restart, not sure about that yet.
blog_commenter
Active Member
Social comments and analytics for this post...

This post was mentioned on Twitter by kevinroast: New blog post on Developer Tips for Alfresco Share 3.3 http://bit.ly/kevsblog02 #alfresco #cms #ecm #springsurf #javascript...
blog_commenter
Active Member
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 :-).
blog_commenter
Active Member
Your article was most tweeted by CMS experts in the Twitterverse...

Come see other top popular articles surfaced by CMS experts!...
blog_commenter
Active Member
Good to know about the SpringSurf Development Mode, because that snipped of code was not found in the share-config-custom.xml :-)
kevinr1
Established Member
Yes you are quite right! I'll get that added to the .sample config.
blog_commenter
Active Member
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
kevinr1
Established Member
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.
blog_commenter
Active Member
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
kevinr1
Established Member
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...
blog_commenter
Active Member
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