Faking Transaction in LCDS 3

Posted in Justin Shacklette on February 19th, 2010 by admin

admin originally posted this on Saturnboy.

Alas, LCDS 3 doesn’t support the notion of transaction (in the sense of a Database Transaction). I assume that somewhere deep within the system transactions are used to ensure correctness of data in the db, but none of this is exposed to the user. Fortunately, it is possible to bundle up a bunch of updates on the client and push them all at once to the server. Fake transactions, as I like to call them, are quite useful. But they can also be dangerous because they are not really transactions (hence the fake part), and don’t always work as you would hope.

Fake It

Faking a tranaction is done using the autoCommit property on a generated service. According to the docs, setting autoCommit to false blocks Data Management from pushing any changes to the server until commit() is called manually.

Here’s a direct quote:

“…set a DataService component autoCommit property to false to allow only manual calls to the commit() method. It is important to set autoCommit to false when you are going to make more than one change…so that the DataService component can batch those changes and send them in one batch to the destination.”

So to make life easy, I made a simple static function that does the autoCommit gymnastics:

public static function fakeIt(service:DataService, func:Function):AsyncToken {
    if (!service.autoCommit) {
        throw new Error("ERROR: autoCommit is already off.");
    }
    if (service.commitRequired) {
        throw new Error("ERROR: another transaction is already open.");
    }
 
    service.autoCommit = false;
    func();
    var token:AsyncToken = service.commit();
    service.autoCommit = true;
    return token;
}

After some error handling, we toggle autoCommit to false, call our function, then commit any updates, toggle autoCommit back on, and return the token.

Usage

Using our fake transaction function is straight forward, and typically involves passing in and inline anonymous function.

Imagine our favorite example of teams and players, where each team has one-to-many players. We might choose to perform a sequence of operations to add a new player to an existing team, like this:

var token:AsyncToken = FakeTransaction.fakeIt(
    teamService.serviceControl,
    function ():void {
        //rename the team
        team.name = 'Denver Nuggetz';
 
        //create player
        var p:Player = new Player();
        p.name = 'Carmelo Anthony';
 
        //wire both side of relationship
        p.team = team;
        team.players.addItem(p);
 
        playerService.createPlayer(p);
    });
 
token.addResponder(new AsyncResponder(successHandler, faultHandler));

In this case, the fake transaction is used to ensure the team is renamed and the player is added. Both operations occur together, so it should not be possible to have the new player on the old team, or have the renamed team without the new player.

Warning! Danger!

Experience has shown me that fake transactions don’t always work as one would expect if they were real transactions. Sometimes, particularly when you are manipulating entities already under Data Management, it seems like operations are not really batched but instead executed one at a time. Thankfully, it appears that LCDS is order preserving, and by that I mean it doesn’t magically re-order things. LCDS always executes operations in the order they come in. I can only recommend you test your application vigorously to ensure what you expect to happen actually happens (FlexUnit4 is pretty awesome for testing async backends).

Files

Creating a TimeMachine SparseBundle on a NAS

Posted in Eric Daugherty on February 18th, 2010 by admin

admin originally posted this on EricDaugherty.com.

I use a ReadyNAS NV+ as my backup drive and bulk storage.  Although the newer firmware directly supports TimeMachine, I've never been able to get that to work.  (This probably has something to do with the fact that I was upgrading and downgrading my NV+ Firmware quite a bit to debug a separate issue).

However, I did find a great tool to create SparseBundles that you can use on a NAS (or any external disk).

BackMyFruitUp.  First, it is a great name.  Second,  it is a simple and easy tool.  The Tool I actually use is 'Create Volume Backup,' a subproject of BackMyFruitUp, which you can download from this page

You hardly need instructions.  Unzip it, run it, and type in the size you want for the sparsebundle.  Then just copy it to your destination share and point Time Machine at it.  Done.

Of course, I wouldn't need it now if my Time Machine SparseBundle hadn't become corrupted.  Luckily I didn't need it.  I also perform a seperate rsync backup on occasion to insure I have a 'basic' backup of my user directory as well.

Ignorance Spam

Posted in Eric Daugherty on February 18th, 2010 by admin

admin originally posted this on EricDaugherty.com.

I've been getting a lot of spam recenctly.  But this isn't normal spam, it is actually 'legitimate' bulk, although *I* didn't sign up for it.  What is going on?

Someone out there, apparently with the name Emily Daugherty, thinks that my gmail address is actually her gmail address.  She's been signing up for all sorts of websites using her (really my) email address  in the past few months.  That results all sorts of useless email for me that is not caught by normal spam filters.

Today she finally tried to reset my gmail password!  I'm not sure if she really doesn't know her email address, or is simply really, really, really bad at typing it in.  Either way, it needs to stop.

I need to somehow convince her to stop using my email address.  Unfortunately, I don't know her real address, since apparently she mostly doesn't either.

Any ideas?

Gorilla Logic releases the MonkeyWrench Java profiler

Posted in Wayne Adams on February 17th, 2010 by admin

admin originally posted this on Wayne Adams' Blog.

Hello, everyone:

I've posted a number of entries in the last year about profiling Java applications. Some of this effort went in to a standalone Java profiler with a Swing interface, called the MonkeyWrench. My company (Gorilla Logic) maintains and has released MonkeyWrench, and you can find it at http://www.gorillalogic.com/monkeywrench. Source code is also available, so if there's some interesting data you want from the java.lang.instrument package (or the JMX beans that I query) that you don't see, feel free to experiment to suit your needs. If you're curious but not sure if you need a profiler right now, take a look at the Getting Started Guide, which contains screenshots. Happy Profiling!

Database/Code impedance mismatch

Posted in Jerry Andrews on February 17th, 2010 by admin

I love natural keys in database design. You have to pay attention, though: the natural impedance mismatch between a programming language representation and the database representation of the key can bite you.

Consider an object whose primary key might contain a date–say, a change log record. Oracle and DB2 both store a DATE as a time containing year, month, day, hours, minutes, and seconds. No timezone. The natural mapping for a Java tool like Hibernate is to map to a java.util.Date, which stores the Date as a time in milliseconds since the epoch GMT, and then maps it to whatever timezone is set on the machine where the code is running for display and conversion.

Now consider what might happen (especially if our change log record is attached to some parent object);

  1. We create and save the object; it is persisted. The local cached copy contains a non-zero value for milliseconds, but the database has truncated the milliseconds value and saved it.
  2. Later on in the code somewhere, we have reason to save the object again, perhaps as part of some collection operation.
  3. Hibernate looks in its cache, compares it with the database, and notes that the values of the Date don’t match–so it tries to save the value again.
  4. The database dutifully tosses out the spare milliseconds, and bam! we have an attempt to re-insert an existing record, so it throws an exception.

This is all terribly confusing to the programmer, who, inspecting the objects in question, sees no difference between what’s in the database and what’s in her code, especially since the default display characteristics of her database browser and her debugger don’t show the milliseconds.

The easy fix in this case is to declare a class which matches the database representation–in this case, a good choice would be to declare a new class which truncates the milliseconds. A modest example is shown below:

/*** Public Domain; use or extend at will.*/import java.util.Date;

public class DbDate extends Date {/** increment if you change the state model     */private static final long serialVersionUID = 1L;

/** @see java.util.Date#Date() */public DbDate() {    long t = getTime();    setTime(t - t%1000);}

/** @see java.util.Date#Date(long) */public DbDate(long t) {    super(t - t%1000);}

/** @see java.util.Date#setTime(long)     */@Overridepublic void setTime(long time) {    super.setTime(time - time%1000);}}

Also note that if you declared the database column as a TIMESTAMP, the Java and database representations more-or-less match–avoiding, in this case, this kind of problem. Note that Oracle doesn’t support TIMESTAMP_WITH_TIMEZONE in a primary key, and DB2 doesn’t implement TIMESTAMP_WITH_TIMEZONE at all–as of the last time I had access to DB2.

Dealing with timezones is another topic entirely–one which I’ll take up in a future post.

Like Peas and Carrots: LCDS 3 and UTF-8

Posted in Justin Shacklette on February 17th, 2010 by admin

admin originally posted this on Saturnboy.

I just wrote about how to handle special characters in Flex 4 when written as HTML entities in MXML. Now I’ve moved my data with the special characters out of MXML and down into a MySQL database. Data access is provided by a vanilla LCDS 3 backend. I now have a very different problem than what I had before: How do I get UTF-8 data out of the database with LCDS and onto the display?

MySQL and UTF-8

In theory, LCDS is perfectly happy with special characters and foreign languages (here’s a link to supported characters sets in LiveCycle ES2). So this time around, our problem has nothing to do with Flex 4 or LCDS, instead it’s all about the database. For our example, we’ll skip the pure model driven development route and just start with a simple database with a single players table.

Create the database:

CREATE DATABASE ballerz DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'baller'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON ballerz.* TO baller@localhost;

It is possible to configure MySQL to default to UTF-8 friendly behavior but the CREATE DATABASE command guarantees that the newly created db will be happy.

Create the players table:

CREATE TABLE players (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(255),
  PRIMARY KEY (id)
);

Nothing special here, just use VARCHAR for the text fields. In this case, we only have the player’s name.

Insert some sample data:

INSERT INTO players (id,name) VALUES (1, "Carmelo Anthony");
INSERT INTO players (id,name) VALUES (2, "Chaunçey Billups");
INSERT INTO players (id,name) VALUES (3, "Nenê");
INSERT INTO players (id,name) VALUES (4, "Këñÿõn Martin");
INSERT INTO players (id,name) VALUES (5, "LeBrøn James");
INSERT INTO players (id,name) VALUES (6, "Mo Williams");
INSERT INTO players (id,name) VALUES (7, "Shaquille O†Neal");
INSERT INTO players (id,name) VALUES (8, "Ænderson Varejao");
INSERT INTO players (id,name) VALUES (9, "Zýdrunãs Ílgauskãs");

I put some extra special characters into the INSERT statements just for fun.

Digging Deeper: When connecting to MySQL from the commandline you can use the --default-character-set=utf8 option to force your terminal to show UTF-8 characters correctly.

LCDS and UTF-8

Now that the database is correctly setup to handle UTF-8, the rest of the LCDS setup is straight forward (see my getting started part 1 and part 2 posts). Create a new LCDS webapp via copy-and-paste from the template app, then fire up Flash Builder 4 and get to work. In the Modeler plugin, configure a new RDS connection and just drag-and-drop the players table into the model.

Here’s a screenshot of our LCDS model:

model

And here’s a screenshot of the running app (remember this is backed by LCDS, so no running demo):

screenshot

Lastly, the frontend code showing just the highlights:

<?xml version="1.0" encoding="utf-8"?>
<s:Application ...
        creationComplete="complete()">
 
    <fx:Script>
        <![CDATA[
           private function complete():void {
                getPlayers.token = playerService.getAll();
            }
        ]]>
    </fx:Script>
 
    <fx:Declarations>
        <s:CallResponder id="getPlayers" />
        <Ballerz:PlayerService id="playerService" />
    </fx:Declarations>
 
    <s:List 
            dataProvider="{getPlayers.lastResult}"
            labelField="name" />
</s:Application>

Again, no magic here, I use a simple getAll() query to retrieve the entire players table then feed it into a List via the CallResponder’s lastResult property.

Conclusion

So the moral of our story is: if you correctly configure your database to support UTF-8 and you correctly get UTF-8 data into your tables, then everything just works. LCDS will transparently get data out of the db and Flex will transparently get it onto the screen.

Files

Does Write Once Run Anywhere Work?

Posted in Eric Daugherty on February 16th, 2010 by admin

admin originally posted this on EricDaugherty.com.

Yes, and No.

Write Once, Run Anywhere, a slogan created by Sun to evangelize the virtues of the Java Platform, is a controversial approach to software development.

Write Once, Run Anywhere (WORA) is accomplished through an abstraction layer between the 'compiled code' and the operating system and processor.  This abstraction usually takes the form of a Virtual Machine or Runtime, such as the Java Virtual Machine (JVM), Microsoft's Common Language Runtime (CLR), Flash Player (or Air runtime), or one of the many interpreted language runtimes (Perl, PHP, Ruby, etc.).  These runtimes convert the intermediate language into device specific code that can execute on the local operating system and processor.  While this overhead introduces extra steps, which slow down execution, they also provide features not (easily) available in native code, such as garbage collection and Just In Time (JIT) compilers which can optimize the code while it executes, as opposed to at compilation time.

So does it work?  Yes, and No.

Server

WORA languages have achieved a significant level of success on the server side.  Code that runs on large servers and interacts with clients over HTTP or other protocols is almost always written in some form of WORA, whether it is Java, .Net, PHP, Ruby, Perl, or other interpreted languages.  There is no advantage to using native code in these cases.  All interactions with the user are through an intermediate protocol/interface, such as HTML over HTTP for websites, XML over HTTP for web services, or various other formats and protocols used to exchange information between servers and clients or other servers.

There are certainly some applications developed for servers in native code.  Database servers are the most common example, but LDAP servers, webservers (Apache), and others are compiled to native code.  However, there are WORA versions of each of these examples, and many of the native applications were first written before WORA languages took off.

There is no denying that WORA is a huge success on the server side.

Client

Which brings us to No.

Client application development has struggled on the client side.  The biggest challenge is User/Human Interface Guidelines (HIG).  User or Human interface guidelines are published by various Operating System vendors (Microsoft, Apple) that define a set of recommendations on how an application should look and interact with the user.  Applications that follow these look like 'Windows' or 'Mac' applications.

With WORA, application developers have two choices.  Follow the guidelines of a specific platform, and ignore the others, or compromise between the various target platforms, creating an application that doesn't match any platform. 

Early Java desktop applications looked like Java applications.  They were obviously different from the other applications that users were used to interacting with, and were often shunned.  This has led to a negative view of WORA applications in general, as John Gruber comments on a Jason Kincaid article:
Jason Kincaid nails it: “write once, run everywhere” has never worked out. It’s a pipe dream.
In the context of client applications, I have to (mostly) agree.

There are exceptions.  In the Java world, nearly every developer uses an Integrated Development Environment written in Java, whether it is Eclipse, IntelliJ IDEA, or NetBeans.  But developers are a very different target audience than general computer users.

Another example is Flash and Flex applications.  Often delivered in the web browser, there are no real Human Interface Guideline that govern their interactions, other than the expected HTML experience.  This can work, but it can also be horribly painful, as many people have discovered trying to find a menu on a Restaurant's website. 

Mobile

There is a third act to this story.  Mobile.

Apple has take the mobile market by storm with its iPhone and App Store.   With over 100,000 applications written for the iPhone, the iPhone has become THE mobile development platform.  And every one of these applications was compiled to native code.

A consistent user experience is even more important on a mobile device with a limited display and user input capability.  Apple's success is in part due to its consistent device design.  Every iPod/iPod Touch/iPad version has a single home button, and a touch screen.  There are two screen sizes, the iPod size, and the iPad size.  While individual phone capabilities do very (memory, speed, GPS, Compas, etc.) the primary interface components are all the same.   By using a software keyboard on the devices, the keyboard is the same across all devices and applications.  All of this makes developing applications for the platform much more predictable and enjoyable.

The Windows Mobile and Android platforms both share a wide variety of device form factors, screen sizes, physical buttons, and device features.  This makes it much more difficult to build an application that is easy and intuitive to use across the platform.  And I think the quality and quantity of applications on the Windows Mobile and Android platforms demonstrate this point.

Solution

There is a solution, of sorts.  HTML in the browser is the most successful WORA language and runtime for client applications since the ANSI/VT100 terminal.  By creating a common language and interface, applications could be written for all operating systems easily, without the pain of violating their human interface guidelines.  The browser itself conformed to the local guidelines, and users expected the experience in the browser to be different from a native application.

It is time to evolve this paradigm to the next level.  HTML 5 is a good first step.  It provide the ability to display video, store data locally, and draw 2D graphics in a standardized way.  But to be successful, these features and more need to be implemented consistently across browsers, enabling developers to truly develop great WORA client applications.

As an intermediate step, frameworks and libraries that abstract the browser differences away is a short term solution.  JavaScript libraries such as Prototype and jQuery abstract the browser implementation differences while frameworks like Google's Web Toolkit (GWT) provide a platform to develop client applications that just happen to run in the browser.

Realistically, I think tools like GWT are the future.  As a Flex developer, I enjoy the ability to quickly and easily create rich applications that will render the same on ever user's machine.  But I would prefer that the Flex applications would compile to HTML and JavaScript, so they could be run native in the browser.

In the future, we will be developing using various language and platforms, but they will all compile down to code that runs native in the browser.  Or so I hope.

Trust But Verify, A Consulting Love Story

Posted in Dave Rodenbaugh on February 15th, 2010 by admin

admin originally posted this on Lessons of Failure.

About 12 years ago, I was a member of the Professional Services Group for a C++ tools company.  They created a great framework for C++ classes, particularly dates and strings, that really didn’t exist in a standard format at the time.  They dominated the market because their tools were second-to-none.

One of my many gigs at the company took me to Dallas, Texas, home of great bar-b-que and technology companies.  My observation upon arrival is that the density of the two is approximately 1:1, or at least it was at the time.  Coincidentally, another colleague of mine from the same company was also on assignment during the same two-week period at a company just down the road, a major telecommunications company (let’s call them “Lint Communications”).  Not coincidentally, I think lint was all that existed between some of the managers ears at that company.

My friend was tasked with porting the C++ toolkit over to OS/390 for Lint Communications.  This sort of work was typical for our group–anyone who wanted support for our libraries that was outside the supported platform list usually hired Professional Services to come on-site and create a custom build for them.  After you did a few of those, it was mind-numbing work usually consisting of chasing down obscure compiler parameters and libraries in paper manuals at a time when Google and the Internet were not really up to the task of storing that information.

Oh, did I mention that our company charged about $500,000 for a single OS/390 license?  Yeah, so there was serious cash on the line.  That might be important later.

This gig started out innocently enough.  We had dinner about midway through the week, during which we traded war stories:

Me: How did it go today?

Friend: Uh, it was kind of weird.  They are telling me to finish the port, but they are talking to the sales guy like they’re not all that interested in it.  Something about it not working right.

Me: Did you run the standard test suite?  Did it pass?

Friend: Yeah, flying colors.  No problems.

Me: Did you offer training or help?

Friend: Yeah, they tell me they don’t have time right now.  One other thing though…

Me: What?

Friend: Every hour, on the hour, the file system slows to a crawl.  Kind of seems like they’re taking backups of it or something.

I should tell you that my friend was a junior engineer working in our group and this was one of his first gigs.  He seemed to think this felt wrong, but he just wasn’t sure.  At this point, my alarm bells were ringing.  Here we had a customer that was paying good money to have an engineer on site, but telling the sales rep that the product wasn’t working and they didn’t want help to fix it.  And taking snapshots of his work.

Our conversation continued:

Friend: What should I do?

Me: Finish the port like they asked.  However, just in case, put in a time-bomb.  Something not easy to find on quick inspection inside of our headers that will kill the library after a certain date.

He completed his work and put in the Trojan horse in the string library, something like:

#if !defined(SOME_OBSCURE_COMPILER_OPTION_THEY_WOULDNT_GUESS) {
      if (today > some_magic_date) { exit(DONT_STEAL_ME_BRO); }
}

After we returned from our jobs, we learned from the sales rep that they decided not to purchase the software license and they deleted the software from their mainframe.  We considered the matter dropped and went about our other projects.

About 45 days later, our customer support department got a call from Lint Communications.  They complained that our toolkit was crashing their application every time they launched it, based on stack dumps.  A quick search of their customer information confirmed they had no purchased licenses.

Sure enough, they had continued to use the OS/390 port without paying for it.

Our sales group negotiated a nice settlement with them to the tune of almost $3 million for a license deal after agreeing not to sue them for piracy.  After that, my friend turned over the compiler option to Lint Communications that was required to shut it off.

I learned a critically important lesson in consulting that day:  Take the customer’s word, but make sure they are telling the truth.

Trust, but verify.

No related posts.

Limiting Irreversibility

Posted in Jerry Andrews on February 14th, 2010 by admin

This afternoon I was reading Martin Fowler’s commentary on architecture: http://www.martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf, and ran across the following:

At a fascinating talk at the XP 2002 conference (http://martinfowler.com/articles/xp2002.html), Enrico Zaninotto, an economist, analyzed the underlying thinking behind agile ideas in manufacturing and software development. One aspect I found particularly interesting was his comment that irreversibility was one of the prime drivers of complexity. He saw agile methods, in manufacturing and software development, as a shift that seeks to contain complexity by reducing irreversibility—as opposed to tackling other complexitydrivers. I think that one of an architect’s most important tasks is to remove architecture by finding ways to eliminate irreversibility in software designs.
I think he’s absolutely on the mark with this–in fact, I think it illuminates one of the two or three key roles of architecture in system implementation. If the architect focuses on helping to define approaches which are hard to change once the system “complexifies”, and in helping developers write solid code that can easily be modified when needs change, (s)he goes a long, long way towards making the system flexible and maintainable.
Note that there’s two architectural roles there: (1) helping to make key decisions early, and (2) mentoring developers around those decisions.
On most of the dev teams I’ve worked with, the first set of decisions is made by proposal and refinement–one of us proposes an overall approach, and the rest of us point out tweaks or whole new approaches until the whole thing gels in everyone’s mind. It seems to work, if everyone is engaged. Some architects would prefer to “rule by fiat”, but I’ve found that generally results in systems which can’t be maintained or in far more work than is needed. It’s very hard to get key decisions right by yourself. To illustrate: I once proposed a relatively modest refactoring in a large thorny user interface, to separate business logic from display logic and generally make it easier to maintain. The reigning architect decided we needed a complete rewrite, in direct opposition to the opinion of everyone else on the team. Nobody objected strongly, though everyone quietly agreed that a rewrite probably wasn’t needed–it’s lot more fun to write new code than to modify old. Nobody asked what the minimum effort needed to meet the requirements was. About two years and a couple million dollars later, the new system is, indeed, quite a bit better-structured than the old one. It’s not clear if the new UI will produce allow faster, cleaner updates than the old one–but it sure cost a lot to build: about twice the initial estimate, and about 6 times the original proposal. (By the way: the rewrite is considered a success by all involved. See “What Could Possibly Be Worse Than Failure?” by Alex Papadimoulis.)
A second role implied in minimizing irreversibility is “mentor”. Writing good code is hard; writing well-structured code without someone to bounce your design off of is doubly hard. I spend a lot of time talking with the members of my teams, trying to make sure we have a design that’s flexible and understandable. A lot of what we think of as “architecture” starts out as a small feature being implemented by a relatively junior developer. I try to make sure (s)he has someone to work with in the early stages of that work, or at least a trial design to start from.
I love Martin Fowler’s writing: he always gives me something good to think about.

iTunes Export 2.2.1 Released

Posted in Eric Daugherty on February 12th, 2010 by admin

admin originally posted this on EricDaugherty.com.

iTunes Export exports playlists defined in your iTunes Music Library to standard .m3u, .wpl (Windows Media), .zpl (Zune), or .mpl (Centrafuse) playlists. iTunes Export also supports copying the original music files with the playlist to facilitate exporting to other devices. iTunes Export is open source and freely available for use.

The 2.2.1 release features updates and bug fixes to the console and GUI versions

In both versions:
  • Enhanced the playlist name filter to include characters from the Latin 1 Supplement Block.
  • Added(Console)/Changed(GUI) 'addIndex' logic. Now uses incrementing index instead of iTunes Song Index. Index is in the order iTunes has the songs in for each playlist.
For the Console version:
  • Replaced ad-hoc URL decoding of file paths with URLDecode class. Now non-ASCII characters are handled correctly in file names.
If you find any issues or have questions please email me (eric@ericdaugherty.com). Please include which application and version (GUI or Console, 2.2.1 etc.) of iTunes Export and the operating system you are using.