Pages

Wednesday, December 24, 2008

Flex : Solution to Error: unable to resolve '/assets/icons/icon.png' for transcoding using Embed tag

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>

Sunday, December 07, 2008

Tutorial to use Eclipse with JAX-WS for contract-first Webservice

I assume that the wsdl is already present and this tutorial is to show, how to use eclipse to generate the java code.

Configuration:
Eclipse 3.3
JAX-WS RI 2.1.5
JDK 6

Step 1: Download the JAX-WS RI jar(JAXWS2.1.5-20081030.jar) from https://jax-ws.dev.java.net/2.1.5/

Step 2: Run the command java -jar JAXWS2.1.5-20081030.jar, Accept the license and allow it to be installed. I will call this $JAXWS_HOME

Step 3: Open eclipse, and Run->External Tools->Open External Tools Dialogue..

Step 4: Give name as GenerateJavaFromWSDL, Location as $JAXWS_HOME\bin\wsimport.bat, Working Directory(path to directory containing wsdl) as ${project_loc}/WEB-INF/wsdl where ${project_loc} [Eclipse variable already defined in eclipse, no need to create this ]is the project location in eclipse, arguments as "myWSDL.wsdl -keep -d ${project_loc}/WEB-INF/src" [without quotes] where myWSDL.wsdl is the wsdl to generate java code, keep is to keep the generated java files and d is the output directory. You can also provide p as argument to specify the package for the java files being generated.

Step 5: Click the Run button. The java files are generated.

Wednesday, December 03, 2008

Filtering in Java

I find the below piece of code pretty useful for filtering purposes in java. I use the apache Commons collection library for this purpose. In the below code snippet, I am filtering on id in the model Data present in the List. After running this code snippet, the 'list' will contain only those Data Objects that satisfy the filter criteria, in this case that will be 'userId = Id'. Predicate defines the filter criteria in the snippet below.

public void filterOnId(String Id,List<Data> list){ 
final StringBuilder string = new StringBuilder(Id);
Predicate predicate = new Predicate(){
public boolean evaluate(Object object) {
boolean returnValue = false;
if(object instanceof Data){
Data vo = (Data)object;
returnValue = vo.getUserId().compareTo(string.toString())==0?true:false;
}
return returnValue;
}
};
CollectionUtils.filter(list, predicate);
}