Introducing FlowMVC
Posted by brianr in html5, javascript, sencha extjs, sencha touch on April 30th, 2013

Introducing FlowMVC: A reference architecture & MVC extensions for developers using Sencha ExtJS or Sencha Touch with DeftJS.
Take what you already know and go with it… just code with the Flow.
FlowMVC builds on the work of DeftJS, Sencha ExtJS, and Sencha Touch APIs adding extensions that enable Flex and ActionScript developers to take their expertise and apply them to the HTML5/JavaScript world. It’s a framework that users of Flex MVC-based architectures, such as Swiz or Parsley, will be familiar with. FlowMVC can help anyone, but Flex developers will find it particularly familiar.
In addition, for enterprises looking to leverage intellectual capital across platforms with Sencha Touch and Sencha ExtJS, it provides an application structure with reusability and portability in mind encouraging the re-use of application and business logic.
For enterprises struggling with the myriad of available javascript frameworks, FlowMVC and the tools used in the Cafe Townsend Demo Project, provide a level of security for enterprise architects and managers that their goals, such as well defined project structure, documentation, testability, localization, and re-use of resources, both human and IC, are met.
FlowMVC works with ExtJS version 4.1 and up, Sencha Touch version 2.0 and up, and DeftJS version 0.8.0 and up.
Highlights
- FlowMVC uses a Global Event Bus for loosely coupled object communication.
- FlowMVC separates Mediators from Service Controllers — it strictly separates Mediators (View Controllers that own views) from Service Controllers (that own services).
- FlowMVC has Service Objects separating server side logic into it’s own layer.
- FlowMVC has Mock Service Objects with delays built-in for async service stubbing.
- FlowMVC looks and feels like a robust OO client using traditional MVC architecture and IoC frameworks.
- FlowMVC has an awesome logger!
Documentation Overview
Full documentation on the features and usage of FlowMVC is available on the Wiki. Show me code.
- Consistant Project Structure
- Model-View-Controller-Service Architecture
- Dependency Injection
- Event Bus
- HTTP Data Services and Mocks
- Implementation of Passive View using Mediators
- Jasmine Unit Tests for both functional and asynchronous code blocks
- Reuse of code between ExtJS and Touch versions
- FlowMVC API Docs
- Resources
- License
Examples
- Cafe Townsend Demo Project - A HTML5 implementation using Sencha ExtJS, Sencha Touch, DeftJS, and FlowMVC.
Pending Features
This effort is still ongoing with some in-progress work that will provide the following features:
- Unit Tests with Jasmine - (In Progress @ 60%)
FlowMVC is currently considered an Alpha release, so help us make it better by adding to the Issues Page where necessary. Please free to reach out to us and lets us know what you like, love, hate, feature requests, defects, etc on the Issues Page.
Jasmine Unit Test for Sencha Custom Asynchronous Event
Posted by brianr in javascript on March 25th, 2013
We’ve created some custom framework objects to extend the Sencha MVC framework and needed to test custom events we’re dispatching from those objects. Here’s a simple example testing a custom event being fired when a store’s selected record method has been called; the method should fire off an event with type “selectedRecord” and the actual selected record being set on the store using the fireEvent() method in the base Sencha Store:
describe("CafeTownsend.store.EmployeeStore", function() {
// reusable scoped variable
var store = null;
// setup
beforeEach(function() {
store = Ext.create("CafeTownsend.store.EmployeeStore");
});
// teardown
afterEach(function() {
store = null;
});
describe("setSelectedRecord() method", function() {
it("should be a function", function() {
expect(typeof store.setSelectedRecord).toEqual("function");
});
it("should have a selected record", function() {
var model = {
id: 1,
firstName: "Rob",
lastName: "Dougan",
phoneNumber: "508-566-6666"
};
spyOn(store, "fireEvent");
store.setSelectedRecord(model);
expect(store.fireEvent).toHaveBeenCalledWith("selectedRecord", store, model);
expect(store.fireEvent).toHaveBeenCalledWith("selectedRecord", store, store.getSelectedRecord());
});
});
});
The key is using the Jasmine.spy object. The following thread shed some light on this topic for me.
P90X Primer
DISCLAIMER: This is not a tech post. Since people seem to ask me about it all the time I have this email on the ready deck.
Best thing about P90X and what sold me on it 5+ years ago and why I still do it:
- All workouts <= 60 mins. [NOTE: Except Yoga so I do the 45 min vr Tony offers.]
- All workouts can be done in a 4×4 square ft area — I used to do it in my little living room in our little condo in Boston.
- Most moves use your own body weight so less need for extra stuff (although you do need some once you really get into it, like a pull-bar and some bands and/or dumbbells).
- Can do at home and on the road (via lap/ipad/iphone) — no more driving to gym and it’s cheaper. I have it all stored on my iPad and even use that at home rather than rely on a TV.
- It’s dumb simple — old school strength and cardio moves that you can learn after 1 round if not already familiar with them. You remember pushups and pull-ups right?
Couple side notes I tell anyone getting into either P90X or Insanity:
If this is your first time doing p90x I highly recommend doing 1/2 of each workout the first wk and then starting to do the full thing the second wk, but counting your second wk as wk 1 in terms of p90x calendar.
Unless you’re in really good shape and have been doing these moves for awhile, the warmup vr of wk 1 that I recommended is more of a learning curve and gives your body a chance to slowly jump in without hurting yourself, tearing muscle, or getting frustrated b/c it’s moving too fast/hard. If you can plow through it without that break-in wk, then rock on…just my 2 cents.
One more tip — some of the moves are awkward and can lead to injury. Just listen yo your body and learn to know the diff between good pain and bad pain; good pain being you’re working hard and you can feel your muscles getting “that burn” vs bad pain where you tear things and injure yourself. Simply put, if you encounter bad pain then modify the move; eg, I have bad knees after years of volleyball so I modify on plyos where necessary but keep on pushing hard to keep the heart rate up.
If you want more details on P90X, then checkout my business partner’s blog as he tells you about his experience with it:
- Notes on Completing Round 1 of P90X
- Positive Notes on Week 3 of P90X
- Positive Life Changes & Challenges After Round 2 of P90X
Good luck and hit me with any questions.
TypeScript Quick Summary
Posted by brianr in javascript on October 16th, 2012
After watching the 53 minute video “Anders Hejlsberg: Introducing TypeScript” last week, I threw together a summary in the form of a bulleted list so my partners that didn’t have time to watch could at least get the gist; if you do have time I highly suggest watching the video and then reading my partner Jesse Warden’s detailed post “TypeScript for ActionScript Developers“. If you want the 10,000 foot view from my POV, here ya go:
In a Nutshell
TypeScript (TS) provides the following constructs to JavaScript developers at author time: Strong, static typing including packages, classes, interfaces, and other common OO constructs; ie, your IDE will perform code completion and type checking as if JavaScript were a real, strongly typed language…to me, this is the single most important thing missing from native JS.
5,000 Foot View
- Compiles down to normal JS and works with any other existing JS lib right in the same code base, even inline and mixed right in there with your existing JS; this is contrary to sayGWT or CoffeeScript which says you can only use Java and CoffeeScript respectively. With TS, it lives right inline with your JS and you can use as much/little as you want.
- Common OO constructs with expected keywords and syntax:
- class
- interface
- extends
- implements
- super
- constructor
- module
- new
- public
- private
- static
- void
- override — not used as TS compiler does for you
- overload – not used as TS compiler does for you
- ? — optional properties and method parameters
- Looks like ActionScript typing:
- var a:IFoo;
- function bar(myString:string, myNum:number):bool
- interface IFoo { var bar:string; doFoo(x:number):void; }
- class Bar implements IFoo { var bar:string; doFoo(x:number):void; }
- Private members in classes.
- NOTE: This is not enforced at runtime. This is purely a author-time thing only as they’re really no private members in JS.
- Getter/Setter methods in classes (like AS):
- function get foo():string
- function set foo(s:string):void
- Default and optional values in function methods.
- interface IFoo { var bar?:string; doFoo(x:number=0, y?:number):void; }
- Inheritance:
- Can use the keyword extend for classes, ie classes with inheritance.
- This is the only time TS injects extra code that you wouldn’t normally see in your JS.
- Provides method overloading that us Java doods are accustomed to.
- Nothing special to do here as the TS compiler picks up on multiple methods with the same name but different params and handles this behind the scenes
- Better keyword this scoping within event handler methods using fat arrow =>. This eliminates the whole creating references to the outer class’s “this” with another var and then passing it into the event handler. Can also help clean up code by eliminating the need for inline, anonymous functions.
- Support CommonJS and AMD modules
- Pretty much follows the EcmaScript 6 definitions, which is very similar to AS3
- Tooling:
- Extendable:
- You can create separate declaration/type/config files for existing libs — simply put, the TS compiler uses basic config files that suggest what the types are in the basic JS lang. You can create your own for JQuery, Angular, BackBone, whatever you want and add them to your TS setup — this will give you strong typing for any other JS framework you want.
- Online, web editor TS Playground and server playground built into the stack
- 100% Open Source
- http://www.typescriptlang.org/
Adobe AIR Won’t Package Modules & Assets From Linked Resources
Posted by brianr in air, eclipse, flash builder, flex, flex builder, modules on June 20th, 2012
If you happen to leverage a linked resources directory as your output folder or bin-debug directory for modules and other loaded assets, then you’ll run into problems when trying to export your AIR application for release.
Flash Builder will not recognize linked resource directories in the packaging contents of your AIR application: http://forums.adobe.com/thread/492841
This means modules that you might build to a linked resource directory will not be discovered by AIR when packaging the installer. In order to get around this, you must either use absolute paths (and therefore remove your linked resources) or copy the files to a physical directory in the AIR project’s source path. A simple solution is to create a modules directory in your src/main/resources directory and copy and paste the built modules there.
NOTE: This is just a quick fix and developers should consider using Ant or Maven to do the copying and pasting during the build process.
Styling MX Alert in a Spark World
If you’ve ever tried to style the MX Alert in a Spark Application (Flex 4.x), then you know it’s painful…the solution?
Save yourself some time and just create a custom Alert view and skin and use the PopupManager to show/hide the sucker. Takes about 5 mins and ensures you can style it to your hearts content.
One Java Service POJO for AMF/XML/JSON with Spring BlazeDS & Jersey JAX-RS
Posted by brianr in blazeds, flex, java, jersey jax-rs, sencha extjs on March 23rd, 2012
Introduction
I was reading Christophe Coenraets’ blog post on RESTful services with jQuery and Java using JAX-RS and Jersey and it got me thinking…in order to serve technology agnostic Java Service POJOs to HTML5/JavaScript clients as well as Flex/AIR/Flash clients without writing two service layers and a whole bunch of extra code, why not just put Jersey’s JAX-RS framework next to Spring BlazeDS framework?
Tutorial Goal: Create one Java Service POJO capable of handling RESTful services with XML/JSON over HTTP as well as AMF over HTTP (for RemoteObjects with the Flash Platform) and demonstrate this via a Sencha ExtJS (JavaScript) app and Apache Flex app.
NOTE: I could’ve used Spring’s owen REST framework, but I found Jersey easier than Spring’s 3.02 impl that I’m using and Christophe already banged this out in Jersey so I really just needed to add the Flex part with Spring BlazeDS — big thanks to @ccoenraets for kicking this post off for me! …the point is you can use either Spring or Jersey’s REST impl.
The following is a quick example of a simple Java CRUD Service for beers (because, well, I like beers — Untappd) that serves both HTML5/JavaScript clients via XML/JSON over HTTP as well as Flex clients via AMF over HTTP using Spring BlazeDS.
Download Sample Code
Assumptions
- This post assumes you know what RESTful Services are and have read RESTful services with jQuery and Java using JAX-RS and Jersey so you’re familiar with Jersey.
- This post assumes you’re familiar with Flex and using BlazeDS for RemoteObject calls with the Flash Platform.
- This post assumes you’re familiar with JavaScript and/or Sencha ExtJS (a JavaScript framework similar to Flex with a robust UI library, services, and prescribed MVC architecture).
- This example uses a Tomcat 7 server running on http://localhost:8080/SpringBlazeDSJerseyServer and will refer to that URL throughout the post.
How’s It Work At A High Level?
Both Spring BlazeDS and Jersey work off of the same simple principle of servlet filtering which is configured in web.xml and explained in detail further down in the article — in our example the following mappings take care of everything
Spring BlazeDS = http://localhost:8080/SpringBlazeDSJerseyServer/messagebroker/*
Jersey = http://localhost:8080/SpringBlazeDSJerseyServer/rest/*
Bottom line, these frameworks sit next to each other in the servlet container and do not interfere with each other or use each other in any way. These simply share the same Java Service so you’re not coding one for Flex and one for HTML/JavaScript.
One Java Service to Rule Them All
Let’s take a quick peak at the Java Service BeerService and see what’s so special about it. The key to exposing this service to both BlazeDS and Jersey is in the annotations; review the comments above the class to see what each does.
package com.webappsolution.springbdsjersey.service.impl;
/**
* <b>Spring BlazeDS Annotations</b>
* <p>
* The annotation Service is used to tell Spring this object is a service bean.
* The annotation RemotingDestination is used to expose it as a Flex Remoting destination.
* The annotation RemotingInclude above individual methods is used to expose public methods of the service to Flex
* as opposed to RemotingExclude which hides them from a Flex client.
* </p>
*
* <b>Jersey JAX-RS Annotations</b>
* <p>
* The annotation Path is used to define the base URL pattern (after the app server's context) to map to this RESTful Jersey service.
* The annotation GET above individual methods is used to define the HTTP action/verb associated with the service method.
* The annotation Produces above individual methods is used to define the request and response types for the service method.
* The annotation GET Path("{id}") above individual methods is used to add specific method parameters for the service method via REST path.
* </p>
*/
@Service("beerService")
@RemotingDestination
@Path("/beer")
public class BeerService implements IBeerService
{
private static Log logger = LogFactory.getLog(BeerService.class);
BeerDAO dao = new BeerDAO();
@Override
@RemotingInclude // BDS
@GET // JERSEY
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) // JERSEY
public List<BeerDTO> findAll()
{
logger.debug("findAll");
return dao.findAll();
}
@Override
@RemotingInclude // BDS
@GET @Path("{id}") // JERSEY
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) // JERSEY
public BeerDTO findById(@PathParam("id") String id)
{
logger.debug("findById: " + id);
return dao.findById(Integer.parseInt(id));
}
@Override
public BeerDTO create()
{
logger.debug("create");
return null;
}
@Override
public BeerDTO update()
{
logger.debug("update");
return null;
}
@Override
public void delete()
{
logger.debug("delete");
}
}
Next we’ll need to add an annotation to our simple BeerDTO so Jersey knows how to convert it to XML or JSON; take note of the annotation XMLRootElement:
@XmlRootElement
public class BeerDTO
{
private int id;
private String name;
private String brewery;
public BeerDTO()
{
// TODO Auto-generated constructor stub
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public void setBrewery(String brewery)
{
this.brewery = brewery;
}
public String getBrewery()
{
return brewery;
}
}
This has no effect on our DTO when being used by Spring BlazeDS.
After that the other big piece to getting this thing cranking is the required JARs (which I packaged up in the WAR so you can play easily) and checking out the web descriptor for the app (web.xml) as it maps incoming servlet requests for Jersey and BlazeDS appropriately.
web.xml - Spring BlazeDS config
<!-- ================================================= -->
<!-- SPRING BLAZEDS PROJECT SETUP -->
<!-- ================================================= -->
<!-- This will configure the BlazeDS message broker as a Spring-managed bean using the simple message-broker tag.
This will bootstrap the BlazeDS message broker. When you use the message-broker tag without mapping child elements,
all incoming DispatcherServlet requests are mapped to the MessageBroker.
You can add mapping child elements if you need more control.
Any requests hitting the URL http://SpringBlazeDSJerseyServer/messagebroker/* will get mapped to Spring BlazeDS.
The component scanning for Spring BlazeDS services is done in app-context-flex.xml.
-->
<!-- ================================================= -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/config/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>flex.messaging.HttpFlexSession</listener-class>
</listener>
<servlet>
<servlet-name>flexspring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flexspring</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
web.xml - Jersey config
<!-- ================================================= --> <!-- JERSEY --> <!-- ================================================= --> <!-- Configure Jersey JAX-RS to handle RESTful services Any requests hitting the URL http://SpringBlazeDSJerseyServer/rest/* will get mapped to Jersey. The param "com.sun.jersey.config.property.packages" with a value of "com.webappsolution.springbdsjersey.service" tells Jersey the package to scan for Jersey enabled services. You can add more than 1. --> <!-- ================================================= --> <servlet> <servlet-name>Jersey</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>com.webappsolution.springbdsjersey.service</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>
Quick HTTP REST Test
Start the Server and hit the following URL: http://localhost:8080/SpringBlazeDSJerseyServer/rest/beer and you should see an XML list of Beers. This is good and means you’re ready to test the Flex side.
As Christophe points out, you can also use the cURL command in terminal to see the results:
- Get All Beers: curl -i -X GET http://localhost:8080/SpringBlazeDSJerseyServer/rest/beer
- Get Beer By ID: curl -i -X GET http://localhost:8080/SpringBlazeDSJerseyServer/rest/beer/1
- Get All Beers - XML: curl -i -X GET http://localhost:8080/SpringBlazeDSJerseyServer/rest/beer -H ‘Accept:application/xml’
- Get All Beers - JSON: curl -i -X GET http://localhost:8080/SpringBlazeDSJerseyServer/rest/beer -H ‘Accept:application/json’
Flex RemoteObject Beer Service Example
Our simple Flex example has a button that invokes the RemoteObject BeerService.findAll() method and uses the ArrayCollection response to populate a DataGrid.
protected var beerService:RemoteObject;
protected function init(event:FlexEvent):void
{
this.beerService = new RemoteObject("beerService");
this.beerService.endpoint = "http://localhost:8080/SpringBlazeDSJerseyServer/messagebroker/amf";
this.beerService.addEventListener(ResultEvent.RESULT, onBeerServiceResult);
this.beerService.addEventListener(FaultEvent.FAULT, onBeerServiceRFault);
}
protected function onBeerServiceBtnClick(event:MouseEvent):void
{
this.beerService.findAll();
}
protected function onBeerServiceResult(event:ResultEvent):void
{
this.beerDG.dataProvider = event.result as ArrayCollection;
}
protected function onBeerServiceRFault(event:FaultEvent):void
{
Alert.show("Beer Service Error = " + event.fault.faultDetail, "Error");
}
Assuming your server is still running, run the Flex app and click the “Get Beers!” button and watch the DataGrid populate with some solid brews. Your Flex app should look like:

Sencha ExtJS RESTful Beer Service Example
Similarly, our simple ExtJS example has a button that invokes the RESTful service method BeerService.findAll() via a Proxy within a store that requests JSON as the data format– the response is also mapped back to the Grid.
First, let’s define the matching Beer Model on the client — this matches our BeerDTO on the server and is similar to how we’d mapped Flex ActionScript objects to the same Java BeerDTO.
Ext.define('Beer', {
extend: 'Ext.data.Model',
fields:
[ 'id', 'name', 'brewery' ],
});
Next we’ll create a Store that uses a REST proxy to interact with the Jersey Services and is responsible for mapping the Beer Model we just created to the JOSN request and responses from Jersey. There’s some additional CRUD code that isn’t actually being used in this post but will in the future.
var store = Ext.create('Ext.data.Store', {
autoLoad: false,
autoSync: true,
model: 'Beer',
proxy: {
headers: {
'accept': 'application/json'
},
type: 'rest',
url: 'http://localhost:8080/SpringBlazeDSJerseyServer/rest/beer',
reader: {
type: 'json',
root: 'beerDTO'
},
writer: {
type: 'json'
}
},
listeners: {
write: function(store, operation){
var record = operation.getRecords()[0],
name = Ext.String.capitalize(operation.action),
verb;
if (name == 'Destroy') {
record = operation.records[0];
verb = 'Destroyed';
} else {
verb = name + 'd';
}
Ext.example.msg(name, Ext.String.format("{0} user: {1}", verb, record.getId()));
}
}
});
Finally we’ll create our Grid and Button to invoke the service:
var grid = Ext.create('Ext.grid.Panel', {
renderTo: document.body,
plugins: [rowEditing],
width: 500,
height: 300,
frame: true,
title: 'Beers',
store: store,
iconCls: 'icon-beer',
columns: [{
text: 'ID',
width: 40,
sortable: true,
dataIndex: 'id'
}, {
text: 'Name',
flex: 1,
sortable: true,
dataIndex: 'name',
field: {
xtype: 'textfield'
}
}, {
header: 'Brewery',
flex: 1,
sortable: true,
dataIndex: 'brewery',
field: {
xtype: 'textfield'
}
}]
});
Ext.create('Ext.Button', {
text: 'Get Beers!',
renderTo: Ext.getBody(),
handler: function() {
store.load();
}
});
Assuming you’re server is still running, run the ExtJS app by hitting the URL http://localhost:8080/SpringBlazeDSJerseyServer/extjs/springblazedsjersey/restful.html and click the “Get Beers!” button and watch the DataGrid populate with some solid brews. Your ExtJS app should look like:

Any questions?
Flex 4 ModuleManager & CSS Inheriting Styles
A client I’m working with has a Flex 3.5 app that’s being migrated to 4.5 and one of the immediate issues we ran into (after we got it compiling successfully) was that the modules didn’t inherit the styles from the main app…worked fine in 3.5, but not in 4.5, so what gives?
So I created a simple PoC with a ModuleLoader and it did indeed pick up on the main apps styles as expected. Next I changed my PoC to resemble the client’s architecture a bit more and used a ModuleManager to load the module — low and behold, the module didn’t inherit the main app’s styles.
After some reading on Adobe’s docs I found the following as the key fix:
Using the ModuleManager class to load modules
You can use the ModuleManager class to load the module. This technique is less abstract than using the tag, but it does provide you with greater control over how and when the module is loaded.
To use the ModuleManager to load a module in ActionScript:
- Get a reference to the module’s IModuleInfo interface by using the ModuleManager getModule() method.
- Call the interface’s load() method.
The application that loads the module should pass in its moduleFactory property. This lets the module know who its parent style manager is. When using the load() method, you can specify the application’s moduleFactory with the fourth parameter, as the following example shows:
info.load(null, null, null, moduleFactory);- Use the factory property of the interface to call the create() method and cast the return value as the module’s class. If you are adding the module to a container, you can cast the return value as an IVisualElement (for Spark containers) or a DisplayObject (for MX containers) so that they can be added to the display list.
So the key is passing in a reference to the moduleFactory when calling the ModuleManager.load() method. The 4th parameter is the moduleManager. If you don’t have a reference the main app lying around, just use:
info.load(null, null, null, FlexGlobals.topLevelApplication.moduleFactory);
Great Ant Build Series for Flex
Many people have asked if we use Maven or Ant for Flex builds…while we like Maven for Java, we don’t like Maven for Flex. It’s not that we don’t like Maven in general (obviously since we’re cool with it for Java), we just found it’s almost too much trouble with Flex. It never fails to make us want to pull our hair out and say “Why bother?” — Yes, we have used FlexMojos and we’re still not convinced. So we use Ant for Flex builds.
Instead of writing our own Ant build tutorial series for Flex, we’d like to push you to Jon Campos’s tutorials:
January 7th, 2010 - Using ANT to build an Application
January 14th, 2010 - Building a Library with ANT
January 19th, 2010 - Building the HTML Wrapper with ANT
January 20th, 2010 - Building a Custom HTML Wrapper with ANT
January 21st, 2010 - Including Assets Files with ANT
January 26th, 2010 - Building a Library and Application with ANT
January 28th, 2010 - Building ASDocs with ANT
February 2nd, 2010 - Run Flex Unit Tests from ANT
February 4th, 2010 - Run FlexMonkey Tests from ANT
February 9th, 2010 - The Master Flex ANT File
Thanks for an awesome series Jon.
As a side note, if someone can convince me that mvn + flex is better/easier than ant by all means ping me. brianr@webappsolution.com
Some Helpful Settings For Maven Builds
Posted by admin in actionscript, air, eclipse, flash builder, flex, flex builder, maven on December 20th, 2010
When running Maven builds, there are typically a few settings that are useful to have in your ~/.bash_profile (for Mac or similar, depending on your shell) to help get things off on the right foot.
Set memory usage to 1024M minimum.
export MAVEN_OPTS=-Xmx1024m
Set the path to the appropriate SDK for Flash Builder
FLASH4_SDK=’/Applications/Adobe Flash Builder 4 Plug-in/sdks/3.5.0′
Set the path for ADL if building AIR applications
ADL_PATH=${FLASH4_SDK}/bin
Set the path to the Flash Player for launching FlexUnit tests
FLASH_PLAYER_PATH=’/Applications/Adobe Flash Builder 4 Plug-in/Player/mac/Flash Player.app/Contents/MacOS’
Append these to the current path
export PATH=${PATH}:${ADL_PATH}
export PATH=${PATH}:${FLASH_PLAYER_PATH}
This seems to make embedded fonts play nice in both MX and Spark components in almost every situation. The one I couldn’t seem to get around was mx:Legend.