Eron Hennessey from Amazon has responded below with a new updated Java SDK that’s much easier to grok. The title of this article has since been changed accordingly.
We recently had a use case that was a perfect for the Amazon Simple Workflow Service (SWF).
In the end it was quite simple to implement. I simply read the C# SWF Hello World example and implemented that in Java.
The actual Java example is a nightmare. The following is not a rant about Java, Design Patterns or Aspect Oriented programming. I actually don’t mind any of those. It’s a rant about a Hello World example that requires hours to even setup and comprehend and in the end abstracts the whole point of the exercise away.
The fucking ridiculous HelloWorld example
Let me show you why i do not like to use the Java examples and why in general the AWS documentation is complete shit.
Let me introduce you to the SWF Hello World Java example. It has a few prerequisites.
Setting up the Framework with the Toolkit for Eclipse
I’m in a huge project that uses IntelliJ and this example is for Eclipse specifically. Oh well I’ll install Eclipse just for this example.
Couple of plug ins. No problem.
Now we need to enable annotation processing. Hmmm i wonder if that’s really required for a simple HelloWorld example. Oh well lets go ahead and do that.
Enabling and Configuring AspectJ
Wait a minute. Is this really required for a HelloWorld example?
Oh well lets go through that subsection and get this done.
First it says to download AspectJ for your Java version here. Ok done.
Now it says we need to enable AspectJ by setting our preferences to use AspectWeaver.jar
Now it says to create a META-INF folder in your project and place an aop.xml file with the following contents in it…
XML file editing… In a HelloWorld example application… Hmmm
In the Available Software dialog box, enter http://download.eclipse.org/tools/ajdt/
version/update, whereversion represents your Eclipse version number. For example, if you are using Eclipse 4.3 (Kepler), you would enter: http://download.eclipse.org/tools/ajdt/43/update
And we install 3 more Eclipse plugins. I wonder how well i’ll go when i implement this in our actual IntelliJ project since it uses a lot of Eclipse specific plug-ins?
Add some more AspectJ JARs to your classpath.
Editing of that aop.xml to specifically include components from this HelloWorld example.
Wait a minute did i just complete a tutorial on setting up Aspect Oriented Programming?
Well it seems i now know how to setup an Aspect Oriented Programming (AOP) project along with all the various plugins and helpers. That’s a strange thing when all i wanted was a HelloWorld tutorial for Amazon SWF. Alright well it’s now done, back to it i guess…
Create GreeterActivities interface. Hmm i actually have no problem with using various design patterns. But this is a HelloWorld sample. Can’t we just get to the meat of it?
Create the sole implementation of the above interface. If it’s only ever implemented once perhaps the interface wasn’t required?
A workflow interface. I’m wonder how long it’ll be till i get to the meat of the application.
The workflow implementation of the above interface.
The HelloWorld workflow starter.
No actual meat here. This code doesn’t directly call the AWS SDK. This whole exercise was just a confusing introduction for workflows and a prerequisite for what comes next.
The HelloWorldWorkflow. It now builds on the above to actually talk to AWS. Here’s a handy diagram Amazon has provided to help us understand our code. Most HelloWorld examples don’t require diagrams explaining how the interfaces and implementations of various classes interact but this one sure as hell does.
Got all that? OK lets continue.
Personal preference here – I believe in a HelloWorld tutorial hiding things behind annotations isn’t such a good idea. Sure annotations are great once you understand what they’re doing to the code behind but for now in a tutorial where i want to learn they’re not so great.
Hmm more unexplained annotations. Remember i want to learn how AWS SWF works behind the scenes. Annotations might be a nice shortcut but i really need to see the meat of the application. How exactly is anything pushed to or pulled from the SWF queue? This tutorial skips that part.
The implementation of the above interface.
So far all I’ve ever seen is variables passed around. Where’s the goddamn meat of the application?
A few more paragraphs to read about the program structure so far.
HelloWorldWorkflow Workflow and Activities Implementation. Yes that’s the title of this section. Man i have a headache right now…
Ok this apparently processes our workflow. You’ll note this is the first time we’ve directly used the AWS SDK stuff in code. Although even here it’s just to setup our login details. So far any actual SWF functionality has been hidden behind layers of annotations. Even now it’s not clear how everything is taking items off the workflow queue and processing them.
Similar to the above. Still not sure of the exact call made behind the scenes in the AWS SDK.
AmazonSimpleWorkflowClientobject by using the same code as
GreeterWorker. It then creates a
GreeterWorkflowClientExternalobject, which acts as a proxy for the workflow in much the same way that the activities client created in
GreeterWorkflowClientImplacts as a proxy for the activity methods. Rather than create a workflow client object by using
new, you must:
- Create an external client factory object and pass the
AmazonSimpleWorkflowClientobject and Amazon SWF domain name to the constructor. The client factory object is created by the framework’s annotation processor, which creates the object name by simply appending “ClientExternalFactoryImpl” to the workflow interface name.
- Create an external client object by calling the factory object’s
getClientmethod, which creates the object name by appending “ClientExternal” to the workflow interface name. You can optionally pass
getClienta string which Amazon SWF will use to identify this instance of the workflow. Otherwise, Amazon SWF represents a workflow instance by using a generated GUID.
The client returned from the factory will only create workflows that are named with the string passed into the getClient method, (the client returned from the factory already has state in Amazon SWF). To run a workflow with a different id, you need to go back to the factory and create a new client with the different id specified.
Are you fucking serious?
I really don’t have anything against design patterns but i do think there’s a time and a place. What should be a fairly simple HelloWorld example is not the right place to go off the deep end like this.
And We’re Done… Apparantly
Wait a minute. At no point in that massive and confusing HelloWorld tutorial was there ever any actual code that pushes or pulls items off the workflow queue. The tutorial got so far up its ass that it actually forgot to teach us anything about the AWS SWF service.
Well at least i learnt a lot about AspectJ and aspect weaving
Namely that it’s tied down pretty hard to the Eclipse ecosystem (note the Eclipse only plug-ins above) and my current project is using IntelliJ. Also why the hell did i get taken down this path? I get that some people at Amazon might love Aspect Oriented Programming but there’s a time and a place to force your methodologies on others and go through the many steps to use those methodologies. HelloWorld examples that are meant to teach AWS usage are not the place for this crap.
The C# example is a better Java example than the Java example.
Amazon provides some straightforward C# sample applications. I’m not a C# developer but I’ve found them to be the best resource for how to do things in AWS using Java. Simply install the AWS SDK for .Net and create the sample application.
In that sample you’ll see pushing work to the SWF workflow queue is as simple as setting up a StartWorkflowExecutionRequest object with any data you want and call
Pulling work from the workflow queue involves a decider which determines how the workflow is to be processed. You pull workflow items requiring a decision with the following
response = swfClient.PollForDecisionTask(request);
You can that take that decider object and check it’s history to determine if the activity has finished (so you can go ahead and mark it done in the database) or you can schedule an activity to be run for it.
On your workers you’ll be pulling activities off the queue with
PollForActivityTaskResponse response = swfClient.PollForActivityTask(request);
The PollForActivityTaskResponse will contain the data you passed in above and you can go ahead and do the task you wanted.
It’s a straightforward example with a lot of meaty parts that actually accomplish tasks. Those above lines are just as valid in Java as they are in C#. In fact the whole C# project only requires some trivial (if admittedly verbose) syntax changes if you want to use it in Java. It’s a pretty good example and i was able to grok it in minutes. The AWS Java SDK has all the same class and member names and works in exactly the same way as the AWS .Net SDK.
Seriously Amazon. Look at the C# example. Convert that to Java syntax. It’s quite clear. It doesn’t take any Eclipse only plug-ins. No Aspect Oriented Programming tutorials required. No XML editing. No factory methods or implementations in sight. It’s a straightforward meaty application. And it pretty much works as-is in Java.
13 thoughts on “AWS Java documentation is now much better”
Your mileage may vary I guess. Never had to deal with this in the rest of the SDK. And we’re using SQS, DyanmoDB, MySQL on RDS, etc. The rest of the SDK is beautiful and simple.
You’re looking at the SWF Flow DSL documentation, which is much different than the C# “here’s how to make an API call” example.
The SWF service by itself doesn’t give you a full workflow system; it’s basically a bunch of event queues with consistent event history bolted on. It takes extra framework work to build a typical workflow state machine. Flow is one way to do it: you describe your decider state machine in DSL-conforming Java code, and lots of AoP magic glues your high-level decider logic to the low-level API calls that interact with the service.
There are other ways to use SWF than Flow. If Flow is too grody for you (which is totally understandable, it’s exotic for both better and worse), you can hard code your own state machine and service calls– the route you ended up taking it sounds like– or use some other framework.
Here is one entry point into the Java docs: http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html
Here’s another into generic API docs: http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-using-swf-api.html
It’s rather unfortunate that the Flow Framework examples are the only concrete Java examples provided.
Going into the SWF tutorial listing for some concrete examples and getting this Java monstrosity is going to scare people off. The simple C# example linked below the Java example changes everything. It’s instantly understandable and easily usable for simple use cases. It’s a great starting point to learning and using SWF. The Java example not so much.
LikeLiked by 1 person
Has any one tried SWF with gradle, we are trying to setup Helloworld Flow with gradle. Not able to get AspectJ working with gradle to generate *Client classes for swf annotations. Hash anyone done this before
Reblogged this on russomi.
I think your title should have been:
AWS Java Documentation
Reblogged this on Oligofren and commented:
This is why I don’t work with Java anymore
Hello–I’m the doc writer for both the AWS Java SDK and for Amazon SWF, so I take these words to heart.
In answer to you, I’ve added a few new SWF topics to the AWS Java Developer Guide:
Please let me know if these are more to your liking. I’m tryin’, here. Next up, I’ll tackle those nasty Java Flow Framework topics…
Thanks much for the healthy criticism. It actually does help. 🙂
You might be interested to know that we’ve recently followed the path of the AWS Java SDK, and open-sourced the Java Developer Guide on GitHub:
Please feel welcome to log issues about the content–direct feedback would definitely help in understanding what sucks about the docs, and what I can do to help make them better.
Thanks Eron. Looks good. I’ve updated the article with a note up top to acknowledge this good work and edited the post with the correct URLs for the new Java SDK.
Those examples are a big improvement, but as far as I’m aware they’re not linked from the main SWF developer guide, so I would never have seen them if it wasn’t for the comment here.
Like a lot of other people, I’d really like some documentation on how to build the Flow framework outside of Eclipse, particularly with Gradle.
Hi, I’ve updated the SWF Developer Guide, as well, linking directly to the SWF section in the Java Developer Guide from the SWF “welcome” page. It’s the first link you’ll encounter in the SDK development options section:
I realize that the SWF developer guide could benefit from reorganization and rewriting. I’m working to make that experience better, as well.
Since I have been hearing from customers recently that the Eclipse-centered approach we used in the early content doesn’t suit the needs of the wider Java audience, I’ve been rewriting material using Maven as the baseline, which you can easily modify for Gradle with the Spring dependency management plugin:
Maven’s build files are also easy to parse and convert to various IDEs since they clearly list the necessary dependencies + versions.
I’ll keep looking to improve the way that we address different build tools and IDEs. I welcome further suggestions, and please remember that we have feedback buttons in the documentation itself (the “Tell us about it” link allows more than just yes/no feedback), issues management on the Java SDK docs GitHub repo (where you can be very detailed about what you want to see in the docs), *and* the AWS forums for general/programming questions about the SDKs or various services.
A list of such resources are available on the Welcome page of the AWS Java Developer Guide itself:
Disclaimer: Although I currently work for AWS, my words/opinions expressed here are my own. I can’t promise anything on behalf of the company or AWS, but I do want to let you know what I’ve been doing to address these concerns.
Could you also provide a little more realistic example? Perhaps an example with 2 activities A and B that happen in series? For example, Workflow execution starts, then an activity task is created for ActivityWorker A. Once A completes, an activity task is started for ActivityWorker B.