It so happens that when we work on IDE like flex builder, every thing seems to be working fine but the same would not work other wise.
Problem:
We use maven as build tool, and my mxml and css has tags like:
[Embed(source='/assets/icons/icon.png')]
We get the error
Error: unable to resolve '/assets/icons/icon.png' for transcoding
You have tried to put assets folder in line with the main application file, in common and any other place you can think of, and still this problem is not resolved.
You have also tried with or with out '/' in front of 'assets' in your Embed tag as given by many people around the Internet.
Solution:
With all the assets that will be used in the Embed tag, create a 'swc' library and put it in the mxmlc class path. And use with out a forward slash in the beginning,as in, assets/icons/icon.png.
Next Problem:
How do you create a swc file?
Solution:
The method I adopted in the beginning to just to get my app up as I had a release next day was, if you own Flexbuilder, then create a Flex Library project, and include all these resources in the library. Use this generated library in the mxmlc build path to build the project.
Next Problem:
I can not always keep adding a resource as and when included into my Flex builder library project to generate the swc. So, I will have to automate this. Before, I build the mxmlc, I have to create the swc, and add it in the build path of mxmlc so that the compilation is successful.
Solution:
This is done using the compc compiler. So, I will have to use this compiler to generate the swc of the resources being embedded in the Flex project, then run the mxmlc.
Next Problem:
Running compc directly from command line, to include files, takes the form:
compc -output assets.swc -include-file <file_alias_1> <real file path 1> .. -include-file <file_alias_n> <real file path n>
or
We can use the compc task in the maven ant run plugin. But, this compc task, can include only classes, and could not include all the resources.
Solution:
I assume that the folder structure is like below:
flex
|- libs
|- mainapp
|--src
|
|-- index.mxml
|-- assets
| |-- icons
| |-- images
|-- css
|-- pom.xml
The packages that Flex app uses can be any where, either in mainapp/src or out side it, but its configured in the class path of the mxmlc task in pom.xml.
Step 1: Add the following dependencies with in the maven-antrun-plugin.
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b2</version>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-jakarta-regexp</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.6.5</version>
</dependency>
</dependencies>
Step 2: Define ant-contrib task as below:
<taskdef
resource="net/sf/antcontrib/antlib.xml" classpathref="maven.plugin.classpath">
</taskdef>
Step 3: Before invoking the mxmlc task, add the below ant script. If you are not using maven, then directly use the below ant script in the ant build.xml, making sure the dependent jars are present in the ant/lib directory.
<fileset id="assets.flex" dir="src" includes="**/*.jpg,**/*.png,**/*.css,**/*.swf,**/*.TTF,**/*.jpeg,**/*.xml" />
<pathconvert pathsep=" " property="assets.flex.output" refid="assets.flex" dirsep="/">
<map from="${basedir}/src/" to=""/>
</pathconvert>
<echo message="...Resources being considered..."/>
<var name="filelist" value=""/>
<var name="prefixfilelist" value="-include-file"/>
<for list="${assets.flex.output}" delimiter=" " param="asset">
<sequential>
<echo>Asset: @{asset}</echo>
<propertyregex property="prop"
input="@{asset}"
regexp="(.*)mainapp/src/(.*)"
select="\2"
casesensitive="false" />
<var name="filelist_tmp" value="${filelist}"/>
<var name="filelist" unset="true"/>
<var name="filelist" value="${filelist_tmp} ${prefixfilelist} ${prop} @{asset}"/>
<var name="prop" unset="true"/>
</sequential>
</for>
<echo message="-output assets.swc ${filelist}"/>
<exec executable="${FLEX_HOME}/bin/compc.exe" failonerror="true">
<arg line="-output ../libs/assets.swc ${filelist}"/>
</exec>
Its just a simple program that generates the required argument for compc compiler and invokes it, any developer should be able to read and understand this script. Hence, I will leave out the explanations part of it.
Step 4: Proceed with the mxmlc task with libs in the class path, sample is given below:
<mxmlc file="src/index.mxml"
output="../target/App.swf"
link-report="../target/report.xml"
warnings="false"
services="${CONFIG}/services-config.xml"
context-root = "/App"
>
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
<include name="libs" />
</compiler.library-path>
<compiler.library-path dir="../." append="true">
<include name="libs" />
</compiler.library-path>
<compiler.source-path path-element="../mainapp/src"/>
</mxmlc>
This will make sure all your assets is present in the mxmlc build path, and the Embed transcode error does not occur.
I will put the entire ant run plugin in the pom file here for reference:
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b2</version>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-jakarta-regexp</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.6.5</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<tasks>
<taskdef
resource="net/sf/antcontrib/antlib.xml" classpathref="maven.plugin.classpath">
</taskdef>
<taskdef resource="flexTasks.tasks" />
<fileset id="assets.flex" dir="src" includes="**/*.jpg,**/*.png,**/*.css,**/*.swf,**/*.TTF,**/*.jpeg,**/*.xml" />
<pathconvert pathsep=" " property="assets.flex.output" refid="assets.flex" dirsep="/">
<map from="${basedir}/src/" to=""/>
</pathconvert>
<echo message="...Resources being considered..."/>
<var name="filelist" value=""/>
<var name="prefixfilelist" value="-include-file"/>
<for list="${assets.flex.output}" delimiter=" " param="asset">
<sequential>
<echo>Asset: @{asset}</echo>
<propertyregex property="prop"
input="@{asset}"
regexp="(.*)mainapp/src/(.*)"
select="\2"
casesensitive="false" />
<var name="filelist_tmp" value="${filelist}"/>
<var name="filelist" unset="true"/>
<var name="filelist" value="${filelist_tmp} ${prefixfilelist} ${prop} @{asset}"/>
<var name="prop" unset="true"/>
</sequential>
</for>
<echo message="-output assets.swc ${filelist}"/>
<exec executable="${FLEX_HOME}/bin/compc.exe" failonerror="true">
<arg line="-output ../libs/assets.swc ${filelist}"/>
</exec>
<mxmlc file="src/index.mxml"
output="../target/App.swf"
link-report="../target/report.xml"
warnings="false"
services="${CONFIG}/services-config.xml"
context-root = "/App"
>
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
<include name="libs" />
</compiler.library-path>
<compiler.library-path dir="../." append="true">
<include name="libs" />
</compiler.library-path>
<compiler.source-path path-element="../mainapp/src"/>
</mxmlc>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>