Conway’s Law and Code Ownership

Conway’s Law is one observation we can use as a guide on the initial stages of a Software project, it basically states that development modules organize themselves around the communication structure of an organization. So simply put, if you get three guys in a room that want to quickly roll-out a compiler and not interfere with each other’s work, you will have a three part compiler. Why? because each person does not want to know what the other is doing as long as each has stuck to an agreed interface, everyone is happy.

So, an architectural decision has been made, not by a best practice but by social communication. If the same three developers collaborated on a high-level architecture, a good design, and worked closely on its implementation, my guess is that they would have better results. Not only in the quality of work produced but also other intangibles.

Ever have one developer that is over-worked while the other ten developers wished they could help? Well, not paying attention to Conway’s law is probably the culprit. It is easy to fall into the the argument that: by giving each module an owner we have one throat to choke.

This type of thinking forgets some important items:

  1. People work on projects, someone will take unforeseen time-off.
  2. Dividing up modules does not necessarily divide work equally. Ever have a developer that had a super-easy module and wanders around like the floor like he’s the only one that has his act together?
  3. Unforeseen work presents a challenge on which module it belongs as each module owner will attempt to push the new work onto another. For example, where should certain validations be placed: front-end, middle tier, or at the persistence layer? I bet you the group that with the least political leverage will get this extra work.

So what can we do to break down the social communication barrier? One technique is to implement review practices. Requirements Reviews, Design Reviews, or even Pair Programming, just as long as people are talking.

Remember, a majority of Software Engineering problems can be boiled down to a lack of communication, so don’t avoid communication. The days of the unsociable introvert coder hiding in a dark basement as to avoid human contact is over.

Jar Jar to the rescue

I think we have all seen a JAR conflict on an application server, I still use JDOM and usually run into a conflict with an older version of the JAR installed somewhere on the system that I usually can’t touch.

So, what I did was to use an Ant task called Jar Jar that is available at: http://code.google.com/p/jarjar/

Jar Jar will take a Jar file or (a group of Jar files), change the package names, and repackage the result in a new Jar File. The idea is that you can create your own Jar file with your dependencies packaged in.

I use the BeanShell scripting language (www.beanshell.org) which is what the LiveCycle ES Workbench Script Object is based on. There is no JAR file that I deploy but a script, therefore no compiled code to deploy. So, I use Jar Jar a little differently then what is documented on Jar Jar’s Wiki. I create my own package for JDOM and one of its dependencies Jaxen and I place the new Jar file in the classpath.

My, Ant file looks like the following:

<project name="CustomJDOM" default="jar" basedir=".">

     <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="./jarjar-1.0rc7.jar"/>

     <target name="jar">

        <jarjar jarfile="jdom_custom.jar">

               <zipfileset src="lib/jaxen-core.jar"/>

              <zipfileset src="lib/jaxen-jdom.jar"/>

             <zipfileset src="lib/jdom.jar"/>

             <rule pattern="org.jaxen.**" result="org.jdom_1_1.jaxen.@1"/>

             <rule pattern="org.jdom.**" result="org.jdom_1_1.@1"/>

        </jarjar>

     </target>

</project>

 

Taking it a line by line:

<project name="CustomJDOM" default="jar" basedir=".">

Standard Ant project tag, the default target is "jar" which kicks of the Jar Jar task.

<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="./jarjar-1.0rc7.jar"/>

This is how you declare a new Ant task (or one of the ways), make sure you update the "classpath" variable to where ever you installed the "Jar Jar" Jar file.

<target name="jar">

I’m declaring a task to be run.

<jarjar jarfile="jdom_custom.jar">

This line kicks-off the Jar Jar task and writes the result to a file called: jdom_custom.jar

<zipfileset src="lib/jaxen-core.jar"/>

<zipfileset src="lib/jaxen-jdom.jar"/>

<zipfileset src="lib/jdom.jar"/>

The list of Jar files that will be repackaged in the new Jar file with a new package name.

<rule pattern="org.jaxen.**" result="org.jdom_1_1.jaxen.@1"/>

<rule pattern="org.jdom.**" result="org.jdom_1_1.@1"/>

I’m changing the package name from org.jaxen to org.jdom_1_1.jaxen and org.jdom to org.jdom_1_1.

To use the new Jar File. Include "jdom_custom.jar" in your classpath and use the new package names. So instead of using the package name: org.jdom in your code use: org.jdom_1_1. You never have to worry about a Jar file conflict again.

Acrobat 9 is shipping and Here is how to communicate between PDF and Flash/Flex

Prior Acrobat 9, we were able to communicate between a PDF and a Flash/Flex application residing in the same browser window (e.g. the iframe approach). Acrobat 9 introduces a new feature called Rich Media Annotation that allows you to amazing stuff with Flash … one of them being the ability to embed Flash into a PDF and communicate with it via JavaScript. The example here is simple PDF document with an embedded Flex application that takes a product ID from the PDF and queries Amazon Web Services for product information (features, price, release date etc.).

Continue reading…

Zen and the Art of Offline Data Capture

Whenever, I meet with developers on how to use LiveCycle technologies (or PDF in general), I usually run into: the user fills out the data here … and the PDF is generated here. Generating a PDF for printer friendly output is good, but that’s not all a PDF can do. A PDF can capture data and save you a lot of time and overhead.

So take a traditional web-based application where a user needs to fill-out a form. Look at the over-head that is behind the web form: User Management for the user to save/retrieve a form, Load Balancing during peak-usage, complexity if the user wants to forward the form to another user, and Availability if you want to add a second form to your web-application without down-time.

Enter the world of off-line submission, provide the end user a fillable PDF; this will allow an anonymous user to fill, save, and forward the PDF to another individual (via e-mail or USB drive). When the user is done, have the user e-mail the filled PDF back to your server. The e-mail might take a few hours before reaching your server, but who cares? The end-user isn’t waiting on a spinning hourglass to stop. If you need another form, then create a new PDF and publish it. A new PDF doesn’t necessarily have to be created by the developer of your Web Application team. Another group can create the PDF as long as both of you agree to an XML Schema. See, a nice decoupled system, when was the last time you can leverage a User Interface from another team?

Not all clients implement this solution in exactly the same way as above, some have the need to submit a 200 Megabyte PDF. In this case e-mail would not work and would have to revert back to an HTTP submission, they will loose some benefits but also gain some as well. Hopefully, the reader gets some new ideas in solving some old problems.

So, if you want to prototype the solution, then the LiveCycle products you would need: LiveCycle Forms to pre-populate and extract data, LiveCycle Reader Extensions, this will allow (amongst other things) a PDF to be saved locally with Adobe Reader. And finally LiveCycle Designer that helps you create your PDF.

Using Image in Acrobat JavaScript Dialog

I have had customers asking about how to brand Acrobat JavaScript dialog boxes with images in Adobe LiveCycle Designer. I did some research and found that it was not as simple as defining an <img href=”image.png”/> tag (I wish it was that easy though). As an overview, images used in a Acrobat JavaScript dialog has to be in a icon stream format represented by a hex-encoded string. The data string also needs to be 32 bits per pixel with 4 channels (ARGB) or 8 bits per channel with the channels interleaved. The hex-encoded string looks something like this, "fffffffffff…efdf8fff0e3beffd3b". Beautiful. Anyway, moving on.

There are a number of free and commercial third party tools you could use to convert images to hex-encoded strings. However, none of the tools fits my workflow in terms of flexibility and extensibility. So I have created a Java utility library, called Acrobat Dialog Image Generator (ADIG), which allows you to generate a hex-encoded string or a skeleton Acrobat dialog box with an embedded image.

You can invoke ADIG via a command-line interface, ANT or an API call. Here are some sample invocations:

Command-line

java -jar adig.jar /Users/lerlop/Pictures/test.jpg /Users/lerlop/Desktop/

This will reads in test.jpg and generates a JavaScript dialog file called test.jpg.txt on my desktop. Here is a sample.

ANT

ant -buildfile adig.xml

This will also produce the same result as the command-line option but everything is defined in the following build file.


<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="GeneratorAcrobatDialogImage" basedir=".">
<taskdef
name="adig"
classname="com.adobe.consulting.ant.tasks.GenerateAcrobatDialogImage"
classpath="../../build/adig.jar"/>

<target name="GeneratorAcrobatDialogImage">
<adig imagePath="/Users/lerlop/Pictures/test.jpg" outputPath="/Users/lerlop/Desktop"/>
</target>
</project>

API Call

String hexString = AcrobatDialogImageGenerator. generateHexEncodedString(imagePath);

By calling this static method in your Java code, you can generate a hex-encoded string from an image and assign it to a String object. This particular option is very useful when you try to perform any kind of batch operations. For instance, I can call this method to dynamically insert an image to a JavaScript dialog defined in an XDP before calling LiveCycle Forms to render it as a PDF.

To use the generated dialog JavaScript code in your form design, you can follow these simple steps:

  1. Run ADIG via command-line or ANT to get a generated file. The generate code should like this.
  2. Open your form in LiveCycle Designer (note: XFA form not AcroForm).
  3. Create and name a new script object. It does not matter where the script object is located as long as you can reference it later. For simplicity, create it on page 1 and let’s call it DialogSO.
  4. Copy all the code from the generated file and paste it into the script object.
  5. Now create a button object so you can use it to launch the dialog box. Note that you could launch the dialog box in any event such as form::docReady or form::initialize.
  6. The last thing is to make the button launch the dialog box. In the click event of the button, type in the following function call: DialogSO.launchDialog();

There you have it. You can extend the dialog box in any way you like by adding dialog elements to the dialog body. Please refer to the JavaScript for Acrobat API Reference.

I want to note that there are commercial tools out there that will let you design and extend Acrobat dialog boxes far more than just adding an image and generating dialog JavaScript template. If you are looking for a WYSIWYG tool to design dialog boxes, WindJack’s AcroDialogs may be more suitable for your needs.

Downloads:

Adobe Consulting, Public Sector – Genesis

Hello everyone, the Adobe Consulting Public Sector group has been around for a number of years mainly working on LiveCycle and Flex projects. We decided that it was time to start communicating to the world the experiences we are gaining from working out at the field.

A little bit about our selves, we are not an Engineering, Marketing, or a Sales team, we are simply humble souls that need to get projects working at our customer’s site. So what will we blog about? Anything that we run into(or have) in our current or past projects that the world might gain from. We are Computer Scientists by nature and education, so anything within the field should be expected.

So let the blogging begin….