# James Ward — Full Content
> James Ward — Developer Advocate, Co-Author of Effect Oriented Programming, and podcaster of Happy Path Programming. Writing about software development since 2003.
This file contains the full Markdown content of every page on this site, concatenated,
for use as LLM context. See also `/llms.txt` for a lighter-weight index with links to
each page's individual Markdown version.
---
## About James Ward
Bio:
Professional software developer since 1997, with much of that time spent helping developers build software that doesn't suck. A Typed Pure Functional Programming zealot who often compromises on his ideals to just get stuff done. Currently a Developer Advocate for AWS and AAIF Technical Committee member.
Check out My YouTube Channel
GPG Key Fingerprint:
0xE0130A3ED5A2079E
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFlMSXMBCADcgN0/57D/gU5cDobPiRuDT6qAxb/NWhQiqwAocKd274r4gPJm
RbffUEZEgKhjH6l0CQfilC4R4x2QtU9sNC9kB/D6zumoS1uI0Hmx1pC4UseUy55r
20WDxujUQ7OcJbpe2cDcQVKmMok2top7ZJqt4KVosQEeT9jjsgBBbEtg4cWb5ddR
5rf+aJw0v/6dMLef1r9YAo0ZtLc+g2dyacqw73tcWEd3oCH++SgE26NntN+GibZu
VXSE5u6xI4KwfT2vUT3jt5Fb29myX4sxsfB7n/xageuJYy5ms1ABS+WDO5ssEZC4
eQEVL7eyIb9YhNAW/WtjeAuOfOKNonoqKFGXABEBAAG0IEphbWVzIFdhcmQgPGph
bWVzQGphbWVzd2FyZC5jb20+iQE3BBMBCAAhBQJZTElzAhsDBQsJCAcCBhUICQoL
AgQWAgMBAh4BAheAAAoJEOATCj7VogeecsoH/AthoNYkuhDO0sSQsMWYHY5WBYl5
IklRRgeCvDGb9R+Sp/u3basG6FoJHUnZVW0RuQqmk/MEkFRcH5l9uTO4oe7N3BXx
sCD1DI/YKkPel4y/AffidNumTXpvIqrHbIIUXlKUw1YO1jHyZqBE1ItXDF7rt0h5
WCzh5x3fVtOwNItEpkwqD13I4SjRaIdbjr8AurXLiro5+BwPPC02Hi9iUCRzfkfx
82e3jdlGTxUQKku+YLP80/x9TwBe5ULo9wWbcuzbAmBwqYk7FtGNjSqZHyYcP5Zx
2ZTB462dllY63zMOnWnjX27NJkv7gdSfsN6emsg0foTiaPAWQWHW7pQhdh65AQ0E
WUxJcwEIAMgrP3U+7YCibxSQKOZrp63RaSUkv7mCvQ3Lx4P4ZD/sDEsLOiKkAc+Z
U7ETTIQkEpHaibvCZNrA+R0pfAj0LYBLstEIkUxtAaVM4DBQGN13Zdup46fI8rPZ
EyZVb2XpZ/qS4RYiStFyJzUdazBJs/IB7CT0xp4DUFUOrsykVy0aWzWt4z0QBe1x
3AmpAO/DdrDN5gvtmWzWbV3f783PuK3g41ju7F9XX5nuuatNSNHOHt65XL4vmhmS
fXuP6UFjK6MKzq9zpbZD4ipUPoKEId5ONDSucX4C8OydpC8+rFWJCDDDvocox3/l
6TzihQXf8MDDcB0u1TgDPz4M/S2vBh8AEQEAAYkBHwQYAQgACQUCWUxJcwIbDAAK
CRDgEwo+1aIHntk2B/42pBknUQB2YjkPryJ1B1ArcxaLO7gVo/lgT/rLGL7BuTYs
FIl9kJUD156EfkmSAkfsxPzwUNh/GyfVQt09F6wheprx1fLNJCFIYA9ZA0WVZGSw
bE3NdiuwEaJ3/HZ77IteQh5LKllqFuSlZ3u0xdtGJjnAUU9wHxWH+0W3RPm62piS
JcWUw7CSqEyuX+8Z+eq4HY0v74znfy6GyCiil7S1T9fdan22hP3xiJHgVKtyFmhh
rz6YxcZLa0fYl+R3mCQvt2FuiaLL3d/uH0z6EzWs+XZNbjRBTGI9VmO7siIy6rja
tdult3Sx1quBCixC4Ms2AWEA7bMqvUmCoB2M/0x8
=3ou5
-----END PGP PUBLIC KEY BLOCK-----
GPG Key Fingerprint:
82F94BBDF95C247BBD21396B9A0B94DEC0FFA7EE
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
dascGcm+EFTofUs37bZj2nBwer0P
=i0t2
-----END PGP PUBLIC KEY BLOCK-----
Contact Me:
Work: jwdev <at> amazon <dot> com
Personal: james <at> jamesward <dot> com
|
Id
|
Name
|
Industry
|
Rating
|
|---|
In total there were only five pretty small files needed to have an end-to-end Salesforce REST API integration with a web application. Hopefully that gets you started! For full instructions on Heroku deployment of this application or to get the app running locally, check out the [complete project on GitHub][7].
Let me know how it goes!
[1]: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/
[2]: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_understanding_web_server_oauth_flow.htm
[3]: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_understanding_user_agent_oauth_flow.htm
[4]: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_understanding_username_password_oauth_flow.htm
[5]: https://projects.spring.io/spring-security-oauth/
[6]: https://projects.spring.io/spring-boot/
[7]: https://github.com/jamesward/hello-spring-salesforce
---
## Quick & Easy ETL from Salesforce to MySQL with Workflow & Heroku (2016-08-10)
While sometimes unfortunate it is often necessary to have data silos that share data. The _Extract, Transform, and Load_ (ETL) pattern has been around for a long time to address this need and there are tons of solutions out there. If you just need a quick and easy way to copy new & updated records in Salesforce to an external data source, a simple Heroku app and Salesforce Workflow might be the quickest and easiest solution. I've put together a sample Node.js application for this: https://github.com/jamesward/salesforce-etl-mysql
Check out a demo:
This sample app uses a Salesforce Workflow that sends created and updated Contact records to an app on Heroku, which inserts or updates those records in a MySQL database. A simple [transform][1] JavaScript function makes it easy to customize this app for your own use case. To setup this app for your own uses, check out the instructions in the GitHub repo: https://github.com/jamesward/salesforce-etl-mysql
Let me know how it goes!
[1]: https://github.com/jamesward/salesforce-etl-mysql/blob/master/server.js#L7-L13
---
## Add NPM Packages to Salesforce with a Few Clicks (2016-08-02)
I've built a little web-based tool called [ForceNPM][1] that makes it super easy to add NPM packages to Salesforce. Check it out:
[
][1]
[Give ForceNPM a try!][1]
The code is [on GitHub][2] so if you'd like to deploy this on your own Heroku app or other infrastructure, you can do that. Let me know how it goes!
[1]: https://forcenpm.herokuapp.com
[2]: https://github.com/jamesward/forcenpm
---
## Scalable Continuous Delivery Pipelines (2016-07-18)
Back when I first started building web apps we'd just "do it in production" by vi'ing Perl & PHP files on the server. This was fine because the risks and expectations were low. No big deal if I broke the app for a few hours. Good thing I made an _app.php-bak_ copy!
As software became more critical to businesses, the risks of making changes to production systems increased. To cope with these risks we slowed down delivery through processes. Today many enterprises are so bogged down by risk aversion that they may only deploy to production once a year or less. The rate of change in businesses and software continues to increase and the expectations are even higher. Downtime is not an option but that change also needs to go out now!
We need a way to reduce risk and increase the rate of delivery. The two seem to be opposing but [Continuous Delivery][1] provides a way to deliver more often AND reduce risk.
As the name implies, the idea of Continuous Delivery is to continuously deliver changes. There are many ways to do that but the process should be scalable depending on the acceptable amount of risk. For some apps a little potential downtime is worth the tradeoff of essentially being able to "do it in production" for some changes.
Continuous Delivery can be thought of as a pipeline... There is an input / source that needs to be moved and transformed in a variety of ways until it reaches it's output, the production system. By adding or removing the steps in between we can adjust the risk profile.
In order to have a Continuous Delivery Pipeline there are a few things necessary to facilitate any size process:
* A Source Control System (SCM) that enables developers to collaborate but also enables a direct correlation between a point-in-time in the source and a deployment of that source.
* Single directional flow from source to deployment. No more "do it in production" because that breaks the source to deployment correlation.
* A repeatable and pure method of transforming source into something that can run. Repeatability is usually accomplished by using a build tool. However, often builds specify dependencies with version ranges, sacrificing the pureness. Don't do that.
With that infrastructure the simplest form of Continuous Delivery can be achieved. Systems like Heroku provide automated tooling for this kind of pipeline. On Heroku you can either kick off deployment by pushing a git repo directly to Heroku, which then runs the build, then stores and deploys the generated artifacts. This is the infamous `git push heroku master`. A newer method (which I prefer) is instead to push the changes to GitHub and have Heroku then auto-deploy those changes. Here is a demo of that:
For apps that can tolerate more risk this simple pipeline is great! But many apps need a process that better supports collaboration and risk mitigation. The next layer that may be added to the pipeline is a Continuous Integration system that runs the build and tests. If there is a failure then the changes should not be deployed. Here is an demo of doing CI-verified auto-deployment on Heroku:
Reducing risk further we could add a staging system that auto-deploys the changes (with or without CI validation depending on your needs). After manual validation the changes could then be manually promoted to production.
Taking things a step further we can hook into GitHub's Pull Request process to deploy and validate changes before they are merged into a production branch (e.g. master). In Heroku this is called "Review Apps" in which Heroku automatically creates a fresh environment with the changes for every Pull Request. This enables actual app testing as part of the review cycle.
This full pipeline with Pull Request apps / Review Apps, CI validation, staging auto-deployment, and manual production promotion significantly reduces the risk of doing frequent deployments. Many organizations that use this kind of process are able to do hundreds of deployments every day! This also helps disperse risk over many deployments instead of accumulating risk for those big once-a-year deploys. Check out a demo of this entire flow on Heroku:
Sometimes a feature may not be ready for end user testing or launch but that shouldn't prevent you from actually deploying the feature! For this you can use "Feature Flags" a.k.a. [Feature Toggles][2].
Another technique that can be useful to reduce risk with Continuous Delivery is "Canary Deploys" where only a portion of users run on a new version of the app. Once a period of time validates the new version is "safe" for everyone, it can be rolled out to the rest of the users.
Of course Continuous Delivery isn't a silver bullet as there are always tradeoffs. One of the challenges with Continuous Delivery is with database schemas. For instance, what if you were to do a schema migration as part of a Canary Deploy? With two versions of the app running simultaneously you may break one version with the schema changes from another. NoSQL / Schema-less databases are one way to address the issue. Another option is to decouple code deployments from schema migrations, utilizing testing / staging environments to validate the schema changes.
Implementing Continuous Delivery with large and complex systems can be pretty tough. But this is one of those things that if you don't figure out how do, it won't matter cause your business will likely fade as it is overtaken by startups that deliver software as the business needs it. If you need some more practical advice on how to get there check out my [Comparing Application Deployment: 2005 vs. 2015][3] blog post. Let me know how it goes.
[1]: http://martinfowler.com/bliki/ContinuousDelivery.html
[2]: http://martinfowler.com/articles/feature-toggles.html
[3]: https://www.jamesward.com/2015/06/08/comparing-application-deployment-2005-vs-2015
---
## Reactive Web Request Batching with Scala and Play Framework (2016-06-16)
At first glance it seems silly to do batching in the reactive world. When I first started with reactive programming I thought I wouldn't have to worry about things like resource starvation. After all, the reactive magic bullet was \*magical\*! But my magic bullet fizzled when it hit downstream resource constraints causing me to need batching.
With a reactive web client library like Play Framework's, I can easily spin up tens of thousands of web requests, in parallel, using very little resources. But what if that saturates the server I'm making requests to? In an ideal world I could get backpressure but most web endpoints don't provide a way to do that. So we just have to be nicer to the server and batch the requests. (Sidenote: How do you know how nice you should be to the service, e.g. batch size?)
So in some scenarios you might just need to batch a bunch of web requests. Let's say you need to make 100 requests and you've figured out that you should only do 10 at a time. Then once all 100 have completed you need to do some aggregation of the results. Of course you could block until each batch is complete and mutate a shared value that accumulates the results. But we can do better than that! You can still use immutable data and non-blocking requests with batching.
In Play I have a `/echo?num=1` request handler that just returns the number passed into it:
```scala
def echo(num: Int) = Action {
Logger.info(s"num=$num")
Ok(num.toString)
}
```
Now in another async controller I want to send 10,000 requests to the `echo` controller but batched 256 at a time, then return the aggregated results. First I need a function that will handle the batching:
```scala
private def processBatch(results: Future[Seq[String]], batch: Seq[String]): Future[Seq[String]] = {
// when the results for the previous batches have been completed, start a new batch
results.flatMap { responses =>
// create the web requests for this batch
val batchFutures: Seq[Future[String]] = batch.map(ws.url(_).get().map(_.body))
// sequence the futures for this batch into a singe future
val batchFuture: Future[Seq[String]] = Future.sequence(batchFutures)
// when this batch is complete, append the responses to the existing responses
batchFuture.map { batchResponses =>
Logger.info("Finished a batch")
responses ++ batchResponses
}
}
}
```
This `processBatch` function takes a `Future` that holds the previously accumulated results which are a sequence of Strings. It also takes a batch of urls and returns a `Future` that holds the previously accumulated results and the results from the batch. When the `results` that were passed in have all been completed, the batch is processed by creating a web request for each URL. Each request is transformed to just the `String` from the response body. All of the requests in the batch are then transformed into a single `Future` that completes when all of the requests in the batch have been completed. Once that future completes the results of the batch are combined with the previously completed results.
This could also be written using Scala's fancy for comprehension:
```scala
for {
responses <- results
batchFuture = Future.sequence(batch.map(ws.url(_).get().map(_.body)))
batchResponses <- batchFuture
} yield {
Logger.info("Finished a batch")
responses ++ batchResponses
}
```
Here is an async controller that uses the `processBatch` function:
```scala
def index = Action.async { implicit request =>
// ints 1 to 10000
val numbers: Seq[Int] = 1 to 10000
// turn each number into a url
val urls: Seq[String] = numbers.map(routes.Application.echo(_).absoluteURL())
// split into groups of 256
val batches: Iterator[Seq[String]] = urls.grouped(256)
// futures for all of the response strings
val futureResponses = batches.foldLeft(Future.successful(Seq.empty[String]))(processBatch)
// render the list of responses when they are all complete
futureResponses.map { responses =>
Ok(responses.toString)
}
}
```
A sequence of 10,000 URLs `/echo?num=1` to `/echo?num=10000` are assembled. That sequence is then partitioned into groups of 256. Then the reactive batching magic... Take the batches and do a `foldLeft` starting with an empty sequence of String, calling the `processBatch` function for each batch, accumulating the results. Once the future returned from the `foldLeft` completes the results are turned into a String and returned in an the `Ok` response.
There you have reactive batching of web requests! [Check out the full source][1].
[1]: https://github.com/jamesward/play-batch-requests
---
## Machine Learning on Heroku with PredictionIO (2016-06-14)
Last week at the [TrailheaDX Salesforce Dev Conference][1] we launched the [DreamHouse sample application][2] to showcase the Salesforce App Cloud and numerous possible integrations. I built an integration with the open source [PredictionIO][3] Machine Learning framework. The use case for ML in DreamHouse is a real estate recommendation engine that learns based on users with similar favorites. [Check out a demo and get the source][4].
For the DreamHouse PredictionIO integration to work I needed to get the PredictionIO service running on Heroku. Since it is a Scala app everything worked great! Here are the steps to get PredictionIO up and running on Heroku.
First you will need a PredictionIO event server and app defined in the event server:
1. Deploy: [![][5]][6]
2. Create an app:
```bash
heroku run -a
Check out the [full source for instructions on how to get this example setup on your machine and on Heroku][8]. Let me know how it goes!
[1]: https://blog.heroku.com/archives/2016/4/26/announcing-heroku-kafka-early-access
[2]: http://playframework.com
[3]: http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/scala.html
[4]: http://www.reactive-streams.org/
[5]: https://github.com/jamesward/hello-play-kafka/blob/master/app/workers/RandomNumbers.scala
[6]: https://github.com/akka/reactive-kafka
[7]: https://github.com/jamesward/hello-play-kafka/blob/master/app/controllers/HomeController.scala
[8]: https://github.com/jamesward/hello-play-kafka
---
## Building a Mock HVAC for Smart Thermostat Demos (2016-05-17)
*Update: I've added instructions for a cooling system at the bottom of this post.*
Recently I needed to create a mock HVAC system so that I could have a portable smart thermostat for various demos. I searched around but couldn't find any such thing. So with some sleuthing and the help of my friend [Bruce Eckel][1] I was able to build a simple system that powers a smart thermostat and simulates a heating system. This post will document how to do this in case anyone else ever needs such a thing.
Here is a quick demo:
{{< youtube EB2hbKzr7NM >}}
Modern HVAC systems typically provide 24 volt AC power to thermostats so the first thing you will need is a 120 VAC (wall power) to 24 VAC transformer. I used this one:
Then you'll need something that can simulate a single stage heating system. A smart thermostat uses 24 volt AC to flip on and off a relay (electronic component that uses one power current to toggle another, usually stronger, current). I could have used an actual relay for this but decided to go with something easier, a red LED light that runs on 24 volt AC:
For my smart thermostat I used an [ecobee3][2] (due to their REST APIs) but a Nest should work as well:
Now to wire it together pick a terminal on the transformer to be the "common" and run two wires, one to the LED and one to the "C" terminal on the smart thermostat. Then run a wire from the other side of the LED to the "W1" terminal on the smart thermostat. And finally connect the other terminal on the transformer to the "Rh" terminal on the smart thermostat. Like this:
Here is what it looks like wired together:
Once the smart thermostat is powered on and setup, the LED should turn on when the "heater" is on:
And turn off when the heater is off:
## Cooling System
The wiring for a cooling system is pretty similar to heating (and can be combined with the heating LED):

I grabbed these 24v LEDs so that I'd have a blue one to represent the cooling system:
I also grabbed a 24v fan to represent the fan:
Since the fan is DC and the power is AC, you will also need a converter, like:
That is it for wiring in a mock cooling system!
I hope that helps someone out. Let me know if you have any questions!
[1]: https://bruceeckel.github.io/
[2]: https://www.ecobee.com/
---
## The 6 Minute Cloud/Local Dev Roundtrip with Spring Boot (2016-04-04)
Great developer experiences allow you go from nothing to something amazing in under ten minutes. So I'm always trying to see how much I can minimize getting started experiences. My latest attempt is to deploy a [Spring Boot][1] app on [Heroku][2], download the source to a developer's machine, setup & run the app locally, make & test changes, and then redeploy those changes — all in under ten minutes (assuming a fast internet connection). Here is that experience in about six minutes:
To try it yourself, start at the [hello-springboot GitHub repo][3]. Let me know how it goes!
[1]: http://projects.spring.io/spring-boot/
[2]: https://heroku.com
[3]: https://github.com/jamesward/hello-springboot
---
## Pulling Go Code Colorado Data into Salesforce (2016-04-02)
This weekend I'm at the [Go Code Colorado][1] Challenge Weekend event in Durango. The purpose of Go Code Colorado 2016 is for teams to build something useful for businesses using one or more of the [Colorado Public Datasets][2]. Some teams are using Salesforce for the back-office / business process side of the app they are building. So I decided to see if I could pull a Colorado Public Dataset into Salesforce. Turns out it's super easy! Just follow these steps:
1. [Sign up for a Salesforce Developer Edition][3]
2. [Create a new External Data Source][4] with the following field values:
> External Data Source = Colorado Public Data
> Name = Colorado\_Public\_Data
> Type = Lightning Connect: OData 2.0
> URL = https://data.colorado.gov/OData.svc
> Special Compatibility = Socrata
3. Save the new External Data Source and then hit "Validate and Sync" to fetch the metadata for the services.
4. Select one or more tables from the list. A good table to test with is the "Occupational Employment Statistics" dataset.
5. Sync the table and you should see a new "External Object" in the [list of External Objects][5].
6. The data is now available in Salesforce. An easy way to see the dataset is to create a tab in the Salesforce UI. On the [Custom Tabs Setup page][6] create a new Custom Object Tab for the "Occupational Employment Statistics" object and select a Tab Style:
7. Complete the creation of the tab (select Next, Next, Save).
8. Select the "Occupational Employment Statistics" tab (which might be in a drop-down menu depending on the width of your browser:
9. Next to the View - All selector, hit "Go!" to fetch the data from the Colorado Public Data source. You'll now see the records:
Note: The columns displayed in this view can be customized in the External Object's Search Layout.
10. Selecting a record's ID will display the record details:
That's it! Now you can build all sorts of business processes and other employee-facing interactions around the public data.
Good luck to all of the Go Code Colorado teams!
[1]: http://gocode.colorado.gov/
[2]: https://data.colorado.gov
[3]: https://developer.salesforce.com/signup
[4]: https://login.salesforce.com/0XC?setupid=ExternalDataSource
[5]: https://login.salesforce.com/p/setup/custent/ExternalObjectsPage?setupid=ExternalObjects
[6]: https://login.salesforce.com/setup/ui/customtabs.jsp?setupid=CustomTabs
---
## Quick Force Java – Getting Started with Salesforce REST in Java (2016-01-26)
Recently I [blogged about a toolchain][1] that quickly gets you going with the Salesforce REST APIs. I believe developers should be able to get started with new technologies without having to install tons of stuff and struggle for days. That blog used [Quick Force Node][2] for those who want to use JavaScript / Node.js. I've had a number of requests for a Java version of this toolchain so I created [Quick Force Java][3].
Check out a screencast that shows how to start with nothing, deploy a Salesforce REST app on Heroku, setup OAuth, setup a local dev environment, make & test changes to the app, and then deploy those changes back to the cloud (all in under 12 minutes):
[Try out Quick Force Java][3] and let me know how it goes!
[1]: http://www.jamesward.com/2016/01/13/salesforce-rest-apis-from-zero-to-cloud-to-local-dev-in-minutes
[2]: https://github.com/jamesward/quick-force-node
[3]: https://github.com/jamesward/quick-force-java
---
## Salesforce REST APIs – From Zero to Cloud to Local Dev in Minutes (2016-01-13)
When getting acquainted with new technologies I believe that users shouldn't have to spend more than 15 minutes getting something simple up and running. I wanted to apply this idea to building an app on the [Salesforce REST APIs][1] so I built [Quick Force (Node)][2]. In about 12 minutes you can deploy a Node.js app on Heroku that uses the Salesforce REST APIs, setup OAuth, then pull the app down to your local machine, make and test changes, and then redeploy those changes. Check out a video walkthrough:
Ok, now give it a try yourself by following the instructions in [Quick Force (Node)][2]!
I hope this will be the quickest and easiest way you've gotten started with the Salesforce REST APIs. Let me know how it goes!
FYI: This \*should\* work on Windows but I haven't tested it there yet. So if you have any problems please let me know.
[1]: https://www.salesforce.com/us/developer/docs/api_rest/
[2]: https://github.com/jamesward/quick-force-node
---
## Winter Tech Forum 2016 – My Favorite Developer Conference! (2016-01-11)
I've been to a TON of developer conferences and by a landslide my favorite is the [Winter Tech Forum][1] (which used to be the Java Posse Roundup). Here is why... Learning for me is experiential.
Typical eyes-forward conferences are like being a passenger on a sail boat. I can watch what is happening but I could definitely not become the captain based on my experience as a passenger. This is what makes WTF different; every attendee is a captain (or maybe a skipper if you are new). The whole conference is the experiences that the attendees want to have. Sometimes that means we write code together, explore new technologies, or discuss ideas. Those experiences have made a significant impact on my technical skills. We also eat together and play together which has helped me build some amazing relationships.
This might sound a little crazy until you actually experience it. Which I highly encourage you to do! This year's [WTF is Feb 29 - March 4 in Crested Butte, CO][1] and will be followed by a new [Developer Retreat][2] event that also looks to be awesome. I hope to see you there!
[1]: http://www.mindviewinc.com/Conferences/JavaPosseRoundup/
[2]: http://mindviewinc.com/cbDeveloperRetreat/
---
## Dreamforce 2015 Video: Tour of Heroku + Salesforce Integration Methods (2015-09-29)
This year at Dreamforce I presented a session that walked through a few of the ways to integrate Heroku apps with Salesforce. Here is the session description:
> Combining customer-facing apps on Heroku with employee-facing apps on Salesforce enables a whole new generation of connected and intelligent experiences. There are four primary ways to do this integration: Heroku Connect, Canvas, Apex / Process Callouts, and the Salesforce REST APIs. Using code and architectural examples, we'll walk through these different methods. You will walk away knowing when you should use each and how to use them.
Check out [the video recording of the session][1].
To dive into these methods here are the "Further Learning" resources for each method:
* [Heroku Connect Trailhead][2]
* [Lightning Connect - GitHub Example][3]
* [REST API Example with Node and NForce][4]
* [Salesforce Webhook Creator][5]
I hope this is helpful. Let me know if you have any questions.
[1]: http://salesforce.vidyard.com/watch/1OCODEdjjZkoIUmVe3kdnA
[2]: https://developer.salesforce.com/trailhead/project/quickstart-heroku-connect
[3]: https://developer.salesforce.com/blogs/developer-relations/2015/08/rendering-github-json-data-salesforce.html
[4]: https://github.com/jamesward/hello-nforce
[5]: http://www.jamesward.com/2014/06/30/create-webhooks-on-salesforce-com
---
## Smoothing the Cloud & Local Roundtrip Developer Experience (2015-07-08)
Getting started with new technologies is usually a huge pain. Often I stumble around for hours trying to get an app's toolchain setup correctly. Instructions are usually like:
![][1]
Things get worse when I lead workshops for hundreds of enterprise developers where many are on Windows machines and not very comfortable with `cmd.exe`.
Experiencing this pain over-and-over is what led me to create [Typesafe Activator][2] as a smooth way to get started with Play Framework, Akka, and Scala. Developers have been thrilled with how easy taking their first step with Activator is but I never finished polishing the experience of the second step: App Deployment.
Over the past few months I've been working on a set of tools that make the roundtrip between deployment and local development super smooth with zero-CLI and zero-install. Check out a demo:
Here is a summary of the "from scratch" experience:
1. [Deploy the Click, Deploy, Develop][3] app on the cloud
2. [Download the app's source][4]
3. Run gulp from a file explorer to download Node, the app's dependencies, and Atom and then launch the Node / Express server and the Atom code editor
4. Open the local app in a browser: ```
UPDATE: There is a new and better way to get started with Java on Heroku using Eclipse. For details check out:
Screencast: Java Template Apps on Heroku
The rest of this post is now legacy stuff.
I recorded a screencast and put together some instructions on how to try out Java on Heroku using just a web browser and Eclipse. First, check out the screencast: Here are steps you can follow to get started running Java on Heroku with Eclipse and your browser: **Prerequisites)** Install the EGit and Maven (m2e) Eclipse plugins into your Eclipse. In Eclipse select the "Help" menu, select "Install new Software", from the "Work With" drop-down menu select "All Available Sites", and enter "EGit" in the filter box. After the plugin list has loaded (could take a minute) then select the "Eclipse EGit" plugin, select "Next", and finish walking through the wizard to the plugin. Then do the same for the Maven Plugin "m2e". **Step 1)** Go to [java.herokuapp.com][1] and select an application template. In the screencast I used the "Simple Java Web App with Maven and Tomcat" option since it uses the familiar WAR packaging and Tomcat. Enter your email address and click the "Go!" button. This will create a copy of the template, upload it to Heroku, and assign you as the owner of the app. When the app is created you will see some instructions and a link to the application running on Heroku. **Step 2)** You should have received an email from Heroku indicating that an application has been shared with you. If this is your first time using Heroku you will need to click the account setup link in the email in order to set your password on Heroku. **Step 3)** If this is the first time you have used Heroku then you will need to create and associate a SSH key with your Heroku account. This will be used to authenticate you for git file transfers (to copy the application to/from Heroku). The standard way to do this is with the Heroku CLI. But I've created a little web app using the [heroku.jar][2] library (which wraps the Heroku RESTish APIs) that provides a web-based way to associate a SSH key to your Heroku account. If you don't have an SSH key already then in Eclipse go to "Window" menu -> "Preferences" -> search for "SSH", select the "SSH2" preferences, select the "Key Management" tab, select "Generate RSA Key..." to create a new SSH key, select "Save Private Key...", and then select and copy the public key (starts with ssh-rsa). If you already have an SSH key then in the "Kay Management" tab select "Load Existing Key..." and copy the public key.
Now in your browser go to [key.herokuapp.com][3], enter your Heroku username (email) & password, paste the key into the Public Key field, and click the "Add Key" button.
**Step 4)** Now you are ready to import the created project into Eclipse. Select the "File" menu -> "Import", select "Project from Git", select "Clone...", paste the git URL into the "URI" box (you will find the git URL in the java.herokuapp.com instructions or in the email from Heroku), and select "Next".
Eclipse will fetch the branches of the remote git repository and should display just a master branch. Select "Next" and then "Finish". A local copy of the project will now be on your computer. Now select "Next", select "Import as general project, select "Next", and then select "Finish" to complete the import. From here you can take a few other steps to setup the project for local development. First, [install the m2e-wtp connector][4], create a new Tomcat server in Eclipse, change the web module context root to "/", and then you can just right-click on the project and select "Run As" -> "Run on Server".
**Step 5)** Make a change to the app that you will be able to see when the new version is pushed to Heroku. For instance, add something to the index.jsp file. If you have setup your Eclipse for local development then you should be able to test this change locally before pushing it to Heroku.
**Step 6)** To commit the changes to the local git repository, right-click on the project, select "Team" -> "Commit...", enter a commit message, and select "Commit".
Now that the changes are in the local git repository they can be pushed to Heroku. Right-click on the project, select "Team" -> "Push to Upstream". This will send your change to Heroku and then Heroku will run the project's Maven build and redeploy the changes. When the process has completed you will see the details of the push and the Maven build.
Now refresh (or load) the app in your browser and you should see the changes.
That should be enough to get you started. As you dive in further check out the [Heroku Dev Center][5] for a lot more details on using Java on Heroku. Let me know if you have any questions.
[1]: http://java.herokuapp.com
[2]: https://github.com/heroku/heroku.jar
[3]: https://key.herokuapp.com
[4]: http://stackoverflow.com/questions/6356421/maven-tomcat-projects-in-eclipse-indigo-3-7
[5]: http://devcenter.heroku.com/categories/java
---
## Just Released the S3Blobs Play Framework Module for Amazon S3 (2012-01-23)
I've just posted the first release of the [S3Blobs Play Framework Module][1]. This module makes it easy to upload and download files from [Amazon S3][2] from a JPA entity in a Play Framework Java application. This module is based on [a POC that I did a few months ago][3], the JPA stuff from [Tim Kral][4], and the modularization done by [Roderik van der Veer][5]. For more details on how to use the module check out [the documentation][6], [my tutorial][7] (slightly out of date now), and [the source code][8]. This makes it really easy to save file uploads to an external system when [running Play! apps on Heroku][9]. Let me know if you have any questions. Thanks!
[1]: http://www.playframework.org/modules/s3blobs
[2]: http://aws.amazon.com/s3/
[3]: http://www.jamesward.com/2011/09/13/sending-play-framework-file-uploads-to-amazon-s3
[4]: https://github.com/tkral
[5]: http://vanderveer.be/
[6]: http://www.playframework.org/modules/s3blobs-0.1/home
[7]: /2011/09/13/sending-play-framework-file-uploads-to-amazon-s3
[8]: https://github.com/jamesward/S3-Blobs-module-for-Play
[9]: /2011/08/29/getting-started-with-play-framework-on-heroku
---
## Java, Play! & Scala on Heroku – This Week in San Diego, Mountain View, and Albany (2012-01-16)
This week I'll presenting at three Java User Groups about **Running Java, Play! and Scala Apps on the Cloud**:
* [San Diego Java User's Group on Tuesday, January 17th][1]
* [Silicon Valley Web JUG on Wednesday, January 18th][2]
* [The Capital District Java Developers Network on Thursday January 19th][3]
Hope to see you there!
[1]: http://www.sdjug.org/
[2]: http://www.meetup.com/sv-web-jug/events/45516292/
[3]: http://www.cdjdn.com/content/running-java-play-and-scala-apps-cloud
---
## Heroku JUG Tour: Boulder, Phoenix, & Portland (2011-12-12)
For the next wave of the Heroku Java User Group Tour I will be speaking about running Java, Play Framework, and Scala apps on the cloud in these three wonderful places:
* [Boulder, Colorado - December 13][1]
* [Phoenix, Arizona - December 14][2]
* [Portland, Oregon - December 20][3]
I hope to see you there!
[1]: http://www.boulderjug.org/
[2]: http://www.phxjug.org/meetings.html#next
[3]: http://www.pjug.org/
---
## Tutorial: Play Framework, JPA, JSON, jQuery, & Heroku (2011-12-12)
UPDATE: This tutorial is for Play 1.x (an old version). Check out my Play 2 Tutorial if you want to get started with the latest stuff. (Thanks to John Borys for pointing this out.)
If you are a Java developer then you really need to give [Play Framework][1] a try. It is really refreshing to take a few minutes, step out of the legacy-feeling world of traditional Java web app development and into something modern and fun. I want to walk you through a very simple tutorial where we will build a web application with Play Framework. The application will use JPA for persistence and expose access to the data through a JSON over HTTP interface. The client-side of the application will be built with [jQuery][2]. Lets get started.
**Step 1)** Download and install [Play Framework 1.2.3][3]
**Step 2)** Create a new Play app from the command line and then move to the new directory:
```bash
play new playbars
cd playbars
```
**Optional Step 3)** If you want to work in an IDE then you can run one of the following commands and then open the generated project in your IDE:
```bash
play idealize
```
```bash
play eclipsify
```
I won't walk though the IDE specific steps here, but you can refer to the [Play documentation on IDE integration][4] if you want to get that setup. Note that IntelliJ IDEA has great support for Play Framework with a console right in the IDE.
**Step 4)** Start the Play server from the new project's directory :
```bash
play run --%test
```
This starts Play in test mode which will automatically recompile any changes we make to the application. No packaging, redeploying, or restarting servers will be needed.
**Step 5)** Open the application in your browser:
9. In the Project Structure window, with "Modules" selected, click the "+" button to add a new module to the project.
10. Select the "Import existing module" option and then point it to the generated .iml file.
11. With the module now selected, select the content root block for the module (mine is /home/jamesw/projects/foo). Then select the "tmp/generated" directory in the tree on the right and press the "Sources" button. The HTML template pages are converted to .scala source files by Play and we need these source files to be included in the project along with the regular source files in the app directory.
12. Select "Global Libraries" in the Platform Settings on the left and add a new Java Library named "scala-compiler-2.8.1". Then press the "Attach Classes..." button and navigate to the "lib" directory in your Scala 2.8.1 directory. Then select the "scala-compiler.jar" and "scala-library.jar" files.
13. Add another Global Library named "scala-library-2.8.1" containing the "scala-dbc.jar", "scala-library.jar", and "scala-swing.jar" files.
14. Press the "Apply" button to save the Global Libraries configuration.
15. Select "Modules" and then the "Dependencies" tab. Press the "Add..." button and select "Library" to add a new library to the module. Select "scala-library-2.8.1" and then press the "Add Selected" button to add it to the Dependencies.
16. Select the "Scala" Facet in the module and set the Compiler library to the "scala-compiler-2.8.1" option.
17. Save the Project Structure by pressing the "Ok" button. Make sure the project now builds without any errors.
18. To run the Play server from IntelliJ a new Run Configuration must be configured. To create a new Run Configuration select "Run" from the main IntelliJ menu and then select "Edit Configurations".
19. Press the "+" button and select "Application" from the list of Run Configuration types.
20. Set the name to "Play Server".
21. Set the Main class to "play.server.Server".
22. Set the VM Parameters to: ```bash
-Dapplication.path="."
```
23. De-select the "Make" option in the "Before Launch" section.
24. Press the "Ok" button to save the configuration.
25. Run the Play Server by selecting "Run" from the "Run" IntelliJ menu and verify that the application still works by opening the application in a browser.
It is so much easier to figure this stuff out with a group of people. That is just one of the many reasons why the Programming Summer Camp is a great event!
Let me know if you have any questions or problems.
[1]: https://sites.google.com/site/programmingsummercamp/
[2]: http://www.playframework.org/
[3]: http://www.jetbrains.com/idea/
[4]: http://www.scala-lang.org/node/165
---
## Architectural Evolution: From Middleware to The Cloud (2011-07-12)
You've heard it said that "all things old are new again." That statement can certainly be applied to the current Cloud hype. But each time the old becomes new it gets a bit better because of what was learned the last time around. If we look back ten years at enterprise application development in Java things were quite different than they are today. EJB was "the way" to build scalable systems from a vast abundance of components. But things didn't work out as well as the vendors planned.
**EJB Component Architecture**
I remember back in the early days of enterprise Java everyone was talking about "Components." Application complexity would be greatly reduced because there would be components for everything! Need to connect your app to Exchange? Well, there's a component for that. Does your app need to send email? No problem, there are twenty components for that! Component marketplaces flourished with VC funding galore.
The official way to build reusable Java components became standardized as _Enterprise Java Beans_ (EJB). These "beans" could be accessed either locally or remotely! Vendors led us to believe this was the panacea of Lego-style application development. Just grab pieces from every-which place and hook them together. Hooking the components together required a heavyweight "Middleware" server. Here is what Monolithic Middleware with EJBs looks like:
But the EJB Component Architecture didn't work. Billions of dollars were spent on components and the middleware to tie them all together. And now I bet you can't find a single person that doesn't regret going that route. Why? Three primary reasons...
1. The programming model was too hard. The EJB programming model consisted of too much boilerplate code ("solved" through code-gen tools like xdoclet). EJB's also required configuration which was often middleware server-specific. The EJB Component Architecture creates too many layers of indirection ([Core J2EE Patterns][1] anyone?).
2. Scalability was too hard. EJBs can either run inside your container (using what is called a "Local Interface") or somewhere else (a "Remote Interface"). Using Local Interfaces is fast but causes middleware to run into memory limits and scaling bloated app servers is challenging. Using Remote Interfaces leads to massive serialization and routing overhead and whatever is on the remote end of the wire is still a pain to scale.
3. Deployment was too hard. Remember the days when starting up an app server / middleware container took minutes not seconds?
If you need further proof that the middleware model didn't work then just try to name one place you can still go to buy an EJB component today. Obviously we needed another way to compose the parts of an application.
**POJO Component Architecture**
SpringSource deserves a lot of credit for pulling us out of the EJB muck. They created a model where the application pieces are _Plain Old Java Objects_ (POJOs) injected into an application. This led to better testability, much easier deployment, and a much better programming model. Essentially the revolution of Spring was to make all those app pieces injectable dependencies. This was a huge step forward. But there are still some limitations with this model that are currently being addressed by the next revolution. The three primary challenges with the POJO Component Architecture are:
1. Isolation is too hard. It is now very easy to throw a bunch of components together into a single Web application ARchive (WAR). But at some point all of these pieces being stacked on top of each other make our application brittle and difficult to piece together. What do you do when the version of Hibernate you want to use requires a different version of an Apache Commons library than the version of XFire that you want to use? Or when two libraries that your app needs actually require conflicting dependencies. Sometimes isolating the pieces of an application is actually simpler than injecting them. And unfortunately with POJOs you may not be able to easily switch from using a "Local Interface" to an external "Remote Interface" like you can with EJBs.
2. Polyglot is too hard. The POJO components we use today in our systems are not inherently supportive of a Polyglot world where different parts of a system may be built using different technologies. Suppose your system has a rules engine and you want to access it from a Java-based application and a Ruby-based application. Today the only way to do that is to proxy that component and expose it through an easily serialization protocol (likely XML or JSON over HTTP). This will likely add unnecessary complexity to your system. When the high-level functional pieces of a system are technology-specific the entire system may be forced to use that technology or those pieces may exist multiple times to support the Polyglot nature of today's systems.
3. Scaling is still too hard. As we continue to stack more pieces on top of each other it becomes harder to stick with simple, lightweight share-nothing architectures where each piece is individually horizontally scalable.
**Cloud Component Architecture**
The emerging solution to the challenges we have faced with the EJB and POJO Component Architectures is the Cloud Component Architecture. Instead of bundling components for things like search indexing, distributed caching, SMTP, and NoSQL data storage into your application those high level functions can instead be used as Cloud Components. There are already numerous vendors providing "Component as a Service" products like MongoDB, Redis, CouchDB, Lucene Search, SMTP, and Memcache.
SMTP / outbound email is a simple example where the Cloud Component Architecture makes a lot of sense. With the EJB and POJO Component Architectures I'd find a SMTP component that simply sends email. Then configure my server to be able to send emails that aren't considered spam. I'd also need to deal with constant blacklisting challenges and a larger management surface. Or in a Cloud Component Architecture I could simply sign-up with one of the SMTP as a Service providers like [AuthSMTP][2] or [SendGrid][3] and then just use the Component as a Service.
Here is what the new Cloud Component Architecture for application composition looks like:
The top six benefits of the Cloud Component Architecture are:
1. Simple scalability. By making each functional piece of an application an independent and lightweight service they can each be horizontally scaled without impacting the overall application architecture or configuration. If you chose to use a vendor's Component as a Service then they will handle the scalability of those pieces. Then you only need to scale a very thin web layer. Composing Cloud Components also makes it easier to stick with a share-nothing architecture that is much easier to scale than the traditional architectures.
2. Rapid composition. Cloud Components are flourishing! Most of the basic building blocks that applications need are now provided "as a Service" by vendors who maintain and enhance them. This is a much more erosion-resistant way to assemble applications when compared to the typical abandon-ware which is prevalent with many Java components. Many of the emerging Cloud Components also provide client libraries for multiple platforms and RESTful APIs to support easy composition in Polyglot systems.
3. Reduced management surface. With Cloud Components you can reduce the number of pieces you must manage down to only the stuff that is unique to your app. Each Cloud Component you add doesn't enlarge the management surface like it does in typical component models where you own the implementation of the component.
4. Simple Deployment. One of the biggest benefits of using the Cloud is the ease of deployment. Partitioning the functional pieces of an application makes it thinner and easier to deploy. With Cloud Components you can also setup development and staging instances that make it easy to simulate the production environment. Then moving from one environment to another is simply a matter of configuration.
5. Better Security. In most application architectures today there is one layer of security. This would be like a bank without a vault. There are a few ways into the bank that are wrapped with security (doors with locks) but as soon as someone has found a way in, they have access to everything. With Cloud Components security can be more easily distributed to provide multiple layers of security.
6. Manageable costs. With Cloud Components your costs can scale with your usage. This means it's easy to get started and grow rather than make large up-front investments.
The Cloud Component Architecture may seem similar in ways to the old EJB and POJO Component Architectures because it is similar! The wheel has not been reinvented, just improved. The dream of Lego-style application assembly is now being realized because we've come full circle on some old ideas from twenty years ago ([CORBA][4] anyone?). This time around those ideas are reality thanks to the evolution of many independent pieces like REST, Polyglot, and the Share-Nothing pattern. Cloud Components are the foundation of a new era of application development. My only question is... How long before we see the [UDDI][5] idea again? ;)
[1]: http://java.sun.com/blueprints/corej2eepatterns/
[2]: http://www.authsmtp.com/
[3]: http://sendgrid.com/
[4]: http://en.wikipedia.org/wiki/Corba
[5]: http://en.wikipedia.org/wiki/UDDI
---
## Programming Summer Camp 2011 (2011-06-29)
Over the past few years I've attended a bunch of geek/coder events in the Colorado Mountains. It always surprises me how much I can learn by getting away, being around some really smart people, and writing code with them. So I'm incredibly excited to be attending [The Programming Summer Camp 2011][1] this summer in Crested Butte, Colorado!
At the summer camp you can choose which campsite to hangout in. Or if you want, you can create your own campsite! I'll probably spend most of my time in the Scala campsite. But I look forward to mingling in some of the other campsites as well.
It's like I'm a kid again - getting all excited about going to camp! But I really hope you all can join me July 25 - 29 in Crested Butte, Colorado for [The Programming Summer Camp 2011][1]!
[1]: https://sites.google.com/site/programmingsummercamp/
---
## Getting Started with Node.js on The Cloud (2011-06-21)
In my new job at salesforce.com I'm incredibly exited about getting into [Heroku][1], a Platform as a Service provider / Cloud Application Platform. In a future blog post I'll provide more details on what Heroku is and how it works. But if you are like me the first thing you want to do when learning a new technology is to take it for a test drive. I decided to take my Heroku test drive using the [recently announced Node.js support][2]. I'm new to Node.js, but at least I know JavaScript. Heroku also offers Ruby / Rails support but I don't know Ruby - yet. So let me walk you through the steps I took (and that you can follow) to get started with Node.js on the Heroku Cloud.
_**Step 1)**_ [Sign up for Heroku][3]
_**Step 2)**_ [Install the Heroku command line client][4]
_**Step 3)**_ Login to Heroku via the command line:
```bash
heroku auth:login
```
_**Step 4)**_ [Install git][5]
_**Step 5)**_ [Install Node.js][6]
_**Step 6)**_ Create a Node.js app
I started by building a very simple "hello, world" Node.js app. In a new project directory I created two new files. First is the **package.json** file which specifies the app metadata and dependencies:
```javascript
{
"name": "hellonode",
"version": "0.0.1",
"dependencies": {
"express": "2.5.11"
},
"engines": {
"node": "0.8.4",
"npm": "1.1.45"
}
}
```
Then the actual app itself contained in a file named **web.js**:
```javascript
var express = require('express');
var app = express.createServer(express.logger());
app.get('/', function(request, response) {
response.send('hello, world');
});
var port = process.env.PORT || 3000;
console.log("Listening on " + port);
app.listen(port);
```
This app simply maps requests to "/" to a function that sends a simple string back in the response. You will notice that the port to listen on will first try to see if it has been specified through an environment variable and then fallback to port 3000. This is important because Heroku can tell our app to run on a different port just by giving it an environment variable.
_**Step 7)**_ Install the app dependencies with npm:
```bash
npm install .
```
This uses the **package.json** file to figure out what dependencies the app needs and then copies them into a "node_modules" directory.
_**Step 8)**_ Try to run the app locally:
```bash
node web.js
```
You should see "Listening on 3000" to indicate that the Node.js app is running! Try to open it in your browser:
3. Copy all of the files from the zip file you downloaded into the root directory of the newly created Android project. You will need to overwrite the existing files and update the launch configuration (if Eclipse asks you to).
4. Delete the “res/layout” directory.
5. Add the airbootstrap.jar file to the project’s build path. You can do that by right-clicking on the file, then select Build Path and then Add to Build Path.
6. Verify that the project runs. You should see “hello, world” on your Android device. If so, then the AIR application is properly being bootstrapped and the Flex application in assets/app.swf is correctly being run.
At this point if you do not need any custom startup hooks then you can simply replace the assets/app.swf file with your own SWF file (but it must be named app.swf). If you do need a custom startup hook then simply create a new Java class named “MainApp” that extends the air.app.AppEntry class.
* Override the onCreate() method and add your own startup logic before super.onCreate() is called (which loads the AIR app). Here is an example: ```actionscript
package com.jamesward;
import air.app.AppEntry;
import android.os.Bundle;
public class MainApp extends AppEntry {
@Override
public void onCreate(Bundle arg0) {
System.out.println("test test");
super.onCreate(arg0);
}
}
```
* Open the AndroidManifest.xml descriptor file and tell it to use the new MainApp class instead of the original AppEntry class. First change the package to be the same as your MainApp’s package: ```xml
Next I had a look around the _WebService_ source code (available in
[Tour de Flex][1] was launched at Adobe MAX two years ago. In that time Tour de Flex has become an essential resource for learning Flex. Now that you can build Flex apps for mobile devices with the [Flex Hero prerelease][2] we thought we should build a version of Tour de Flex for mobile devices. Using Flex Hero and [AIR for Android][3] we've created [Tour de Mobile Flex][4]! This is a great way to explore the capabilities of Adobe AIR and Flex on mobile devices. Get it from the Android Market by searching for "Tour de Mobile Flex"!
Download the [Tour de Mobile Flex Flash Builder Project (FXP)][5] or [get the code from github][6]. And let me know what you think!
UPDATE: To compile the latest code on github you will need the latest private prerelease of Flash Builder. You can get more information about the private prerelease on the Flex Team Blog.
[1]: http://flex.org/tour
[2]: http://labs.adobe.com/technologies/flexsdk_hero/
[3]: http://www.adobe.com/products/air/
[4]: http://flex.org/tourmobile
[5]: http://flex.org/TourDeMobileFlex.fxp
[6]: http://github.com/jamesward/TourDeMobileFlex
---
## Install Adobe AIR on 64-bit Ubuntu 10.10 (2010-10-14)
Right now Adobe AIR is only officially available for 32-bit Linux. But it does work on 64-bit Linux with the 32-bit compatibility libraries. There are several ways to install Adobe AIR on Linux. My preferred way on Ubuntu is to use the .deb package. However the .deb package distributed by Adobe can only be installed on 32-bit systems. Good news is that this can be easily fixed! To install the Adobe AIR .deb package on a 64-bit system just follow these steps:
1. [Download the Adobe AIR .deb file][1]
* In a terminal window go to the directory containing the adobeair.deb file
* Create a tmp dir: ```bash
mkdir tmp
```
* Extract the deb file to the tmp dir: ```bash
dpkg-deb -x adobeair.deb tmp
```
* Extract the control files: ```bash
dpkg-deb --control adobeair.deb tmp/DEBIAN
```
* Change the Architecture parameter from "i386" to "all": ```bash
sed -i "s/i386/all/" tmp/DEBIAN/control
```
* Repackage the deb file: ```bash
dpkg -b tmp adobeair_64.deb
```
Now you can install Adobe AIR on a 64-bit system! From the command line just do:
```bash
sudo dpkg -i adobeair_64.deb
```
That's it! Let me know if you have any questions.
[1]: http://get.adobe.com/air/
---
## Data Paging in Flex 4 (2010-10-11)
I know — you've heard it from me before — [AMF rocks!][1] With AMF you can load massive amounts of data into your Flex ([or JavaScript][2]) apps very quickly. This can often obviate the need for paging data. But what if you have lots, and lots, and lots of data? Well then you should use data paging. And here is how...
There is a new collection wrapper class in Flex 4 called "[AsyncListView][3]". The UI data controls in Flex 4 know how to handle an AsyncListView as a dataProvider. The purpose of the AsyncListView is to give you a callback when the underlying list throws an [ItemPendingError][4]. The ItemPendingError indicates that an item that the list thinks it has isn't really there yet. This allows you to then load the data and update the list. In order to throw an ItemPendingError you need to keep track of which items haven't been loaded and then, when an item is requested that isn't really there, throw the ItemPendingError. Here is some code from my [PagedList][5] implementation:
```actionscript
public function getItemAt(index:int, prefetch:int = 0):Object
{
if (fetchedItems[index] == undefined)
{
throw new ItemPendingError("itemPending");
}
return _list.getItemAt(index, prefetch);
}
```
In my main application I just create a PagedList, set its length (which should really be done by a remote call instead of manually), and then assign the instance of PagedList to the list property on my instance of AsyncListView. With MXML this looks like:
```xml
Strange! The width and height are larger than the screen resolution. You can fix this by adding the following to the HTML page:
```xml
```
And now it will look like:
Now that looks right! This also turns off the two-finger / pinch zooming feature for the page (which is more important for content that hasn't been optimized for a mobile profile).
I hope this is useful for those of you embarking on new adventures with Flash / Flex on mobile devices!
[1]: http://www.jamesward.com/demos/MobileSizeTest/MobileSizeTest.html
---
## amf.js – A Pure JavaScript AMF Implementation (2010-07-07)
I just finished the first version of a new pure [JavaScript library for AMF][1]. I've wanted to do this for a while but didn't think it was possible since JavaScript doesn't have a ByteArray. But then I came across this: "[High Performance JavaScript Port of ActionScript's ByteArray][2]". That became the basis for [amf.js][1]. Before I get into the gory details of how this works, check out some developer eye candy:
http://www.jamesward.com/demos/JSAMF/censusTest.html
Ok, hopefully that worked for you. I've tested this in the latest Chrome, Firefox, Safari, and IE and they all seem to work. It should also work on your iPad, iPhone, or Android device.
Now for those gory details... AMF is a protocol initially created in Flash Player as a way to serialize data for storage on disk or transfer over a network. Typically in web apps we use text-based serialization protocols (like JSON or RESTful XML) for data transfer. But there are some advantages to using binary protocols - primarily [much better performance][3]. There are two versions of the AMF protocol, [AMF0][4] and [AMF3][5]. Both are publicly documented by Adobe and numerous server-side implementations of AMF exist. AMF is just a serialization technology, not a transport. So you can put AMF encoded data into any transport (like HTTP / HTTPS). Typically Flash Player is the client that reads / writes AMF data.
I recently had a conversation with [Stephan Janssen][6] who runs [Parleys.com][7] (an amazing Flex app), which started me on this fun project. The Parleys.com PC-profile web client and the Adobe AIR desktop client both use BlazeDS and AMF as the primary serialization protocol for moving data between client and server. This is a great choice for those clients because it makes the apps snappy. But for the HTML5 client Stephan wants to reuse his AMF endpoints. This is where amf.js comes in.
Flash Player has a ByteArray API that can be used for a lot of amazing things. One of those things is to read and write AMF. If you have an object in Flash Player and you create a new ByteArray and then call "byteArray.writeObject(myObject)" you will get a ByteArray with the AMF representation of that object. Likewise if you get some AMF and you call "byteArray.readObject()" you get the object(s) from the AMF. In Flex there are high level APIs (like RemoteObject, Consumer, etc.) that use this native AMF support in Flash Player.
To create a pure JavaScript AMF library the first thing that is needed is a pure JavaScript ByteArray library since JavaScript doesn't natively have one. I used one from [adamia.com][2] since it was similar to the ByteArray in Flash Player, seemed fast, and seemed to parse floats correctly. This ByteArray has some of the basic functions like readByte, readFloat, etc. But what about that cool readObject function? Well, that has to be built from scratch. And it should support both AMF0 and AMF3.
Using the AMF specs and code from BlazeDS & pyamf as a reference I was able to add the other functions to the ByteArray. But there was a problem. Using XMLHttpRequest as the method of getting the AMF was not working right. Some bytes were incorrect. It turns out XMLHttpRequest uses UTF-8 and that screws up some of the bytes above 128. I tried other charsets and each one would change some range of bytes. That is not good because I need the bytes to be exactly what the server sent. Then I came across [this gem][8]:
```javascript
//XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
req.overrideMimeType('text/plain; charset=x-user-defined');
```
Using the "x-user-defined" charset left the bytes alone. Perfect! Except that IE doesn't support the req.overrideMimeType function. But IE does actually have a real ByteArray available in req.responseBody via VBScript. For now in IE I just change the ByteArray into a string (like req.responseText in the other browsers) although a lot of optimization could be done to just use the VBScript ByteArray directly.
Right now amf.js is just a basic JavaScript library for reading AMF data. It doesn't support using a BlazeDS MessageBrokerServlet yet because I need to be able to assemble a AMF object in JavaScript and send that in the HTTP request to the servlet. But it works fine with a custom servlet that uses BlazeDS's AMF library to just write AMF into the HTTP response. It should also work with pyamf, AMFPHP, and other AMF server libraries.
To use amf.js start by dumping some AMF into an HTTP response. In Java with BlazeDS I did this:
```java
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setHeader("Content-Type", "application/x-amf;charset=x-user-defined");
ServletOutputStream out = response.getOutputStream();
ActionMessage requestMessage = new ActionMessage(MessageIOConstants.AMF3);
MessageBody amfMessage = new MessageBody();
amfMessage.setData(someSerializableObject);
requestMessage.addBody(amfMessage);
AmfMessageSerializer amfMessageSerializer = new AmfMessageSerializer();
amfMessageSerializer.initialize(SerializationContext.getSerializationContext(), out, new AmfTrace());
amfMessageSerializer.writeMessage(requestMessage);
out.close();
}
```
In a HTML web page add the amf.js script:
```xml
```
In JavaScript make a XHR request for some data:
```javascript
var url = "TestServlet";
var req;
function getAMF()
{
if (window.ActiveXObject)
{
req = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest)
{
req = new XMLHttpRequest();
//XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
req.overrideMimeType('text/plain; charset=x-user-defined');
}
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send(null);
}
```
And when the response comes back decode the AMF:
```javascript
function processReqChange()
{
if (req.readyState == 4)
{
if (req.status == 200)
{
var o = decodeAMF(req.responseText).messages[0].body;
}
else
{
alert("There was a problem retrieving the data:\n" + req.statusText);
}
}
}
```
For details on how to support IE, check out the source code for [censusTest.html][9].
While amf.js works in my tests there is more work to be done. I need to add the write functions so that AMF can be sent to the server. Then supporting BlazeDS's MessageBrokerServlet should be pretty straightforward. I'd also like to create pure JavaScript implementations of Flex's RemoteObject, Consumer, and Producer APIs. Also, I need people to test amf.js with their AMF to make sure that I've implemented things correctly. All of the [code is on github.com][1] so go ahead and fork it! Let me know what you think.
[1]: http://github.com/jamesward/JSAMF
[2]: http://www.adamia.com/blog/high-performance-javascript-port-of-actionscript-byteArray
[3]: http://www.jamesward.com/2009/06/17/blazing-fast-data-transfer-in-flex/
[4]: http://download.macromedia.com/pub/labs/amf/amf0_spec_121207.pdf
[5]: http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_05_05_08.pdf
[6]: http://twitter.com/Stephan007
[7]: http://parleys.com
[8]: http://web.archive.org/web/20061114143134/http://mgran.blogspot.com/2006/08/downloading-binary-streams-with.html
[9]: http://www.jamesward.com/demos/JSAMF/censusTest.html
---
## Tour de Flex 2.0 – Nearly 500 Flex Examples! (2010-06-21)
Adobe has just launched the new AIR 2 based [Tour de Flex version 2.0][1] which now contains almost 500 Flex examples! The new version has new AIR 2 examples (only available in the AIR version of Tour de Flex) including:
* File Promises
* Mass Storage Detection
* Native Process
* Open with default app
* Socket Server
Also there are some great examples of the new Flash Player 10.1 and AIR 2 APIs including:
* Gestures
* Global Error Handler
* Globalization / Internationalization
* Microphone access
Those are some great examples but my favorite is still [Doug McCune's][2] [Physics Form][3] followed closely by the [real-time Tour de Flex Dashboard][4]. :)
If you already have Tour de Flex installed then it should auto update to the latest version when you launch it. Otherwise install it now using the badge installer below.
[1]: http://flex.org/tour
[2]: http://dougmccune.com/blog/
[3]: http://www.adobe.com/devnet/flex/tourdeflex/web/#docIndex=0;illustIndex=0;sampleId=16300
[4]: http://www.adobe.com/devnet/flex/tourdeflex/web/#docIndex=-1;illustIndex=0;sampleId=14050
---
## Top 10 StackOverflow.com Flex Contributors (2010-06-18)
Back in the day the [FlexCoders Yahoo! Group][1] was all the rage. It was the place where Flex rock stars like [Alex Harui][2] and [Doug McCune][3] hung out and helped the community learn Flex. But these days a lot of developers have turned to [StackOverflow.com][4] as their primary resource for getting answers to their technical questions. I started using Stack Overflow over a year ago primarily because it makes it easy to follow the conversation around a specific question and quickly identify the right answer. Stack Overflow totally nails what I need as a developer when I have problems and questions. Many Flex rock stars have stepped up and frequently answered questions on Stack Overflow and I wanted to highlight the top 10 contributors to [the "Flex" tag][5].
As of June 18, 2010 the top 10 Flex contributors on Stack Overflow ([based on "All Time" total score][6]) are:
| #1 |
Blog: http://amarghosh.blogspot.com/ Twitter: @amrghosh |
#2 |
Blog: http://histos.net/ Twitter: @cliffmeyers |
| #3 | Blog: http://blog.iconara.net/ | #4 |
Whoot! That's me! Blog: http://www.jamesward.com/ Twitter: @riacowboy |
| #5 | Blog: http://turbonerd.com/ | #6 |
Blog: http://joshblog.net/ Twitter: @joshtynjala |
| #7 |
Blog: http://www.herrodius.com/ Twitter: @herrodius |
#8 | Blog: http://blog.richardszalay.com/ |
| #9 | #10 |