Saturday, February 4, 2012

Browser cache, Flex and Maven

A current issue with web application, is the browser cache.

For usual HTML based application, add some meta data is enough:

<meta equiv="CACHE-CONTROL" content="NO-CACHE">
<meta http-equiv="EXPIRES" content="Mon, 01 Jan 1970 00:00:01 GMT">

But with Flex application, it is not so simple.

Flex application are usually wrapped in HTML that allows to detect with the right Flash Player is installed. And if it is not the case, downloading and installing it.

The issue is the Flex SWF name that is specified in the HTML wrapper, makes that browsers put Flex application in cache and don’t reload it.

In the following explanations, the example is a Maven project with a module for the Flex application (using FlexMojos), and a module for the web application.

In the Flex module, the produced SWF file name must be variable, for example, by adding the current version. It is done by giving the final name of the SWF.

In build section, provide the finalName:

<project >
<groupId>my.app</groupId>
<artifactId>myapp-flex-client</artifactId>
<packaging>swf</packaging>
<build>
<finalName>MyFlexApp-${parent.version}</finalName>
<sourceDirectory>src/main/flex</sourceDirectory>
<testSourceDirectory>src/test/flex</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<configuration>
<sourceFile>MyApplication.mxml</sourceFile>
</configuration>
</plugin>
</plugins>
</build>

In the web application, we have to inject the SWF name in the HTML wrapper.

It is done by adding the wrapper goal to Flexmojos plugin.

<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>${flex.mojos.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>wrapper</goal>
<goal>copy-flex-resources</goal>
</goals>
</execution>
</executions>

Adding it, implies to configure it directly in the plugin. The configuration must contains the artefact to wrap (the Flex application) and the name of the wrapper.

<configuration>
<wrapperArtifact>
<groupId>my.app</groupId>
<artifactId>myapp-flex-client</artifactId>
</wrapperArtifact>
<swf>{build.finalName}</swf>
<htmlName>flashClientWrapper.html</htmlName>
</configuration>

The element defines a variable that is injected in the HTML file. Now, it only remains replace the SWF file name in the wrapper by: ${swf}