LiveCycle @ MAX
Last week I had the privilege of attending MAX, Adobe’s annual conference, and being part of the buzz and excitement around Adobe’s strategy and direction.
There is always a lot going on at MAX, and it’s always difficult to decide what to attend, and what to blog about – so I thought I’d focus on LiveCycle, and leave Flex and Flash and Creative Suite to others.
Some of the highlights for me were:
- Walking in to the LiveCycle pre-conference tutorial on Sunday (yes, people gave up their weekends to attend technical training) and seeing an entire roomful of people (at a rough count, about 70 workstations) banging away building applications using the LiveCycle ES2 beta. Apparently, LiveCycle was the only one tutorial that was completely sold out, as were several LiveCycle sessions during MAX.
- Two new products added to the LiveCycle platform: LiveCycle Mosaic (http://www.adobe.com/products/livecycle/mosaic/) and LiveCycle Collaboration Services (http://www.adobe.com/products/livecycle/collaborationservice/ )
- LiveCycle WorkSpace approvals via mobile devices.
- Seeing LiveCycle and Enterprise Development being showcased at the opening keynote by Ben Forta and Rob Tarkoff . http://max.adobe.com/online/keynote_monday/ – About 62 minutes in for Rob and 71 minutes for Ben. Both talks includes a few sample enterprise applications, as well as demos of Mosaic, approvals via mobile devices, and more.
- The new version of Form Guides, or just Guides, as they now seem to be known. We’ve been playing with the early versions of the new Guide Builder for a little while now, and we think Adobe have done an awesome job on this release – Guides are now very powerful and very easy – we’re very very happy.
- The Adobe Data Model. In the Enterprise, everything usually starts and stops with data in a database somewhere. Data model driven development is part of LiveCycle Data Services, but is also used as the basis for the data storage in the new Guides. We’re very excited about this.
http://tv.adobe.com/watch/max-2009-develop/modeldriven-development-using-flash-builder-4-and-livecycle-data-services-es/
You can view many of the Adobe sessions on Adobe TV here:
http://tv.adobe.com/show/max-2009-develop/
including this one, on What’s New in LiveCycle ES2
http://max.adobe.com/online/session/46
This is Jayan’s pick of the sessions:
http://blogs.adobe.com/livecycle/2009/10/max_2009_sessions_about_livecy.html
One other amusing note: The mythical John Jacobs, who is a “sample” user that appears in many of LiveCycle’s samples and demos, actually exists. He was at the MAX conference, and attended the pre-conference tutorials. Hello John!
Form Design for the Rest of Us – Avoka SmartForm Composer
There are some people who have an instinctive feel for design – color, balance, typefaces, effective use of whitespace – and who can create beautiful looking forms. I can’t. My forms generally look like they were designed by a six-year-old with a box of crayons. I usually rely on someone else with creative design skills to help me to come up with a good looking form.
On the other hand, I can build forms with great functionality, because I’ve got a programming background, I’ve been building forms using LiveCycle Designer for 5 years, and I’ve read large portions of the 3000+ pages of API documentation that Adobe provide (yes, really). Plus I have a team of very experienced LiveCycle developers around me who I can call on to help me if I get stuck.

Composer Design Window
You may be a bit of a geek like me, or perhaps the thought of programming bores you to tears. You may have some of the creative talents that I lack, or perhaps you’re “creatively-challenged” like me. Or maybe you’re a pragmatist who doesn’t care about style or programming, all you’re really concerned about is the business problem of collecting the data that you need, and making it as easy and intuitive for your users to interact with your form.
Whichever category you fit into, it’s unlikely that you have the complete set of skills and experience to build a SmartForm from beginning to end.
This is exactly why we built Avoka SmartForm Composer – for you!
We’ve taken all of the knowledge that our Form Design Team have gained in dozens of person-years of experience in building forms, and we’ve encapsulated all that knowledge in Composer. We’ve wrapped that knowledge up into a web-based Flex application that makes it really easy to build forms.

Smart Templates
With Composer, you simply select one of our pre-defined Smart Templates, and you’ll end up with a form that looks great, no matter what your design skills. Add business logic easily using our intuitive rules editors – no programing required. Or choose from our specially designed pre-fabricated “blocks” that embed professionally coded business logic into your form. Click the “Publish” button, and Composer will generate an Adobe XFA compliant PDF SmartForm, and optionally publish to the LiveCycle Repository or Avoka FormCenter. Need to change something across all your forms? Simply tweak the master Style Sheet to change colors, fonts, margins, logos and other visual aspects of your form.
I’m biased, of course, but I’m very excited about Composer. I think it will enable all of us to build intelligent, interactive PDF SmartForms easily, quickly and reliably, and ultimately help to streamline our business processes.
For more information about Composer (including demos), or to stay informed or sign up for our beta program, please visit: http://www.avoka.com/composer
Processes, Orchestrations, Services, and other confusing terminology
Introduction
There are a number of different terms used in Adobe LiveCycle Process Management, including process, orchestration, workflow, service, and component. These can be confusing.
Part of the reason for the proliferation of terminology is the history of the Process Management product and industry trends, and this blog entry tries to provide this perspective. This is my understanding of how these terms fit together, and should not be regarded as a definitive explanation.
If you don’t care about the historical perspective, skip to the end for a summary.
Workflow
The first version of Process Management was called “Adobe Workflow”. And the things you created were called “Workflows”. Even today, many people will generically refer to any combination of boxes and lines that you create in Workbench as a “workflow”.
However, the term workflow was used primarily in the 80’s and 90’s to refer to more traditional image storing and routing applications, and doesn’t really adequately describe the much more useful data-oriented and integration capabilities of LiveCycle. In the 2000’s, the terms BPM or Business Process Management started to become more widely used, not just as a technology, but also as a way of thinking about and improving your business. Various BPM disciplines evolved, including Six Sigma, Lean, and others. LiveCycle fits in much more closely with BPM than it does with the older imaging-oriented workflow systems, so…
Adobe Workflow became LiveCycle Process Management, and Workflow was replaced with …
Process
A Process is no different to a workflow, really, it’s just a term that better reflects the data-orientation and integration capabilities of the LiveCycle platform.
In LiveCycle, a process is almost always associated with a Form, and a series of human interactions that allow people to interact with the form and its data. There are almost always integration steps as well, such as pre-filling the form, writing to a database, adding a digital signature, sending emails, etc. These are also known as “long lived processes”, because they involve people interating with the form over a period of days or weeks.
Long lived process have a unique process-id, have every step recorded and audited, can be re-tried if any step fails, and can be viewed and managed through the Adminui interface.
Orchestration
In LiveCycle ES, we started seeing an increasing number of processes that are short-lived, and don’t include human steps. An example is the Default Render Process in LiveCycle ES. These processes used to be written as Java code in LiveCycle 7 – in ES, they have the advantage that being processes, we end-users can see and modify them very easily. It’s really just visual drag-and-drop programming. You can also easily build your own orchestrations to do something useful – for example, you may want to grab some data from an XML file, populate a form with it, encrypt the form with a password, and email the result to someone. There are no human steps in that, just a series of operation that need to be performed as quickly as possible. You could do this using the API’s, but implementing this as an orchration is quicker, more reliable, and much easier to change.
These short-lived or “straight-thru” processes do not store an audit trail, run as fast as possible (very close to native Java speeds), and do not have a unique process-id that identifies them. They cannot be managed through Adminui, and if they fail, they simply throw an exception back to the caller, rather than being able to be re-tried thru Adminui.
Someone coined the term “Orchestration” to refer to this type of process, and the name has stuck. I’m not sure where the use of this term originated, but it’s used in several other standards BPM standards and products.
Notes:
- Adobe do not officially use this term in their documentation (see http://blogs.adobe.com/livecycledocs/2009/02/the_livecycle_terminology_secr.html) but I think it’s a helpful term that differentiates a process as being short-lived.
- You can still use a long-lived process for something that doesn’t involve humans. We often use long-lived-processes for processes that geneally run very quickly, because of the advantages of having each step audited, and for the ability to re-try a step if anything goes wrong. I would still call this an orchestration, because it doesn’t involve any human steps.
Here is a screenshot from WorkBench. This shows a process, its implementation, and its properties. This is a short-lived process, so I would call it an orchestration.
Component
A LiveCycle Component is basically a bunch of Java code, packaged up into a jar file, and deployed into the LiveCycle server.
LiveCycle Components are brilliant. I love ‘em. They are my insurance policy. I know that there is no problem that I can’t solve in the process world, because if i get stuck, I can write Java code to implement it. Then I can turn it into a LiveCycle component, drop it into LiveCycle, and bingo, I can use it my processes. And the real beauty of it is that anyone else can use my component too, without needing to understand programming. In LiveCycle, Adobe have created the best implementation of a server-side component model that I’ve ever seen – it’s a bit like those Visual Basic ocx controls that you can buy to build your GUI – but on the server.
The concept of LiveCycle server-side components came from a predecessor of Process Management, and were originally called QPACs – Quick (QLink for the real old-timers) Process Action Components.
Each component defines one or more services (see below). Although in reality, most components only define a single service, so components and services are somewhat interchangable.
A service can define one or more operations. An operation is the thing that actually does the work – like sending an email, encrypting a PDF, or writing a file to disk. Services group common operations together – so the File Utilities component contains a FileUtilsService, which in turn contains operations to read, write, create and delete files. Operations each define a number of input and output parameters.
For Java programmers:
- Component == .jar file
- Service == Class
- Operation == method
Here is a screenshot of a Component within LiveCycle.
Avoka has been building components to solve real business problems with LiveCycle for many years, and we turn most of our components into re-usable components that anyone can use. We have a large library of components that solve most of the problems we’ve encountered over the last 5 years. So most of the time, you don’t even have to learn how to build components – if it’s not already in the Adobe “box”, then check out our website – there’s a good chance we may already have built it for you.
For more information, see: http://www.avoka.com/avoka/escomponents.shtml, or email info@avoka.com
Service
Another concept that was introduced in LiveCycle ES was that of a “Service Bus” or “Service Oriented Architecture”. LiveCycle is internally implemented as a service bus. In simple terms, any bit of functionality within the LiveCycle server can be exposed to the outside world as a “Service”, and can be invoked in a number of different and useful ways. Once you’ve defined a service, you can define one or more EndPoints for that service. So for example, I might have a service that encrypts a PDF – I could add a Web Service Endpoint that allows me to invoke that service using Web Services. And I could also add a Watch Folder endpoint that allows me to invoke that service by dropping a file into a folder.
Now things get a little confusing. Services can be implemented as either some Java code, or as a LiveCycle process.
- If you need to write Java code, you create a component, deploy that, and you get a service.
- Or you can do it by creating an orchestration (or process), you define your orchestration, activate it, and you get a service.
- Either way, you get a service. The choice of whether to use an orchestration or Java code depends on the complexity of the service you’re trying to create, and whether it can be created by joining together (or orchestrating) a number of other existing services.
The LiveCycle process engine doesn’t really care whether your service is implemented in Java or as an orchestration, you invoke and manipulate it in exactly the same way. You can either call a service externally (by defining an endpoint), or you can invoke one service from another, simply by dragging the service into process. This is a very neat way to handle things – why should you care how something is implemented, you should be able to use it the same way.
Note: An orchestration only ever defines a single operation, always called “invoke”. Whereas a component can define multiple operations.
This screenshot shows two services, one implemented as a component, and the other as an orchestration.
Summary
- Process: Something that you build in Workbench, and looks like a flowchart. Can be user-oriented/long-lived, or straight-thru/short-lived.
- Orchestration: An unofficial but commonly-used term for a straight-thru/short-lived process.
- Workflow: An older term for a process.
- Component: A jar file containing some code to do something “useful”, that you deploy to the LiveCycle server. A component contains services, which in turn contain operations. All the Adobe services are built as components, as are all the Avoka add-on services.
- Service: Something that lives in the LiveCycle server that provides some sort of “service”. Can be implemented either as Java code (as a component) or as a process/orchestration.
Which “bit” of LiveCycle do I need?
Overview
LiveCycle has a lot of components, somewhere around 15 last time I counted. Some run on the server, some run on the client, some you cannot actually buy but are bundled with others – it’s really confusing, even for those of us who specialize in LiveCycle. But if you’re new to LiveCycle, we don’t blame you for feeling a little lost.
This blog entry attempts to match up your requirements to the various bits of LiveCycle that you may need.
I want to…
Put a “print and fill” PDF form on my site
What you need: Acrobat.
You don’t need LiveCycle, you just need Acrobat. Create your form using whatever tools you like (InDesign, FrameMaker, Word, even Excel) and convert it to a PDF using Acrobat. Your users can download it, print it out, and use a pen to fill it out.
What else you get:
- You get the joy of having to open a whole lot of envelopes, sort the contents, and give the illegible hand-writing to someone to do the data entry into your systems.
- You get the added joy of having incomplete or invalid information in the forms, and having to get back in touch with the user to gather the missing and/or correct information.
- Sigh…
Put a PDF SmartForm on my site, and allow users to fill it out electronically and print it out
What you need: LiveCycle Designer.
Use LiveCycle Designer to create the SmartForm. If your SmartForm is pretty straight forward, you may be able to do this yourself. Alternately, you may need to attend a Designer Training Course, or enlist the help of an Adobe Partner. <shameless-plug>www.avoka.com </shameless-plug>. LiveCycle Designer is a very powerful tool, and you can do amazing things with it – but if you don’t have a programming background, you will quickly get lost in the more complex aspects of the tool.
What else you get:
- You still need to have someone read the printed form and enter the data into your backend systems. However, it’s much easier to read a printed form than a hand-written one.
- OCR (Optical Character Recognition) is much more reliable and accurate with typed forms than hand-written ones.
- SmartForms can really make it easier for your end users by providing in-line help, can automatically hide those sections of the form that aren’t relevant, auto-complete, auto-fill, and provide other assistance to your users when filling in forms.
- SmartForms can ensure that the data you receive is complete and error free, by identifying mandatory fields and validations. Forms won’t print until all mandatory fields and validations pass.
Allow a user to submit a SmartForm back to me via email
What you need: LiveCycle Designer
Use LiveCycle Designer to create the form, and add a “Submit by Email” button to your form.
Note: You will receive the form data as XML. You will then need to use Acrobat to re-inject this XML data back into a blank copy of your form. If you want to avoid this manual process, and allow your users to submit the form directly as PDF, you will need Reader Extensions for your SmartForm or Acrobat for your users (see below).
Allow a user to submit a SmartForm back to me via the web (i.e. http or https) avoiding manual data re-keying
What you need: LiveCycle Designer, some server infrastructure
Just use LiveCycle Designer to create the form, and add a “Submit” button to your form.
Notes:
- You will need to create a Java servlet or ASP.net server or PHP server or some other technology to actually receive or process the incoming submission. This means that you will need to get programmers involved – they can use the tools of their choice – it’s just the usual web request “thing”.
- Alternately, you can use a LiveCycle server to process the incoming http request. You will then be able to process the incoming request in a completely graphical “workflow” environment without any coding. You will need to acquire a copy of:
- LiveCycle Foundation (at a minimum). You cannot buy Foundation, it is bundled with other LiveCycle services, so you will need to pick the most appropriate one. Contact info@avoka.com for advice.
- Avoka’s Process Invoker. This is the “bridge” between the incoming web request and the LiveCycle engine. http://www.avoka.com/avoka/addons.shtml#invoker
- If you want to turn the submitted XML back into a PDF, you’ll need either LiveCycle Forms or LiveCycle Process Management.
Allow a user to save a partially completed form offline or call a web service from within a Form or Submit or Send a form as PDF rather than XML
What you need: LiveCycle Designer and LiveCycle Reader Extensions for your form, or Adobe Acrobat for each of your users.
Using the free Adobe Reader, your users can save a copy of your blank SmartForm to their machines. But once they start entering data, they can’t save that partially completed form (they can only print it or submit it). There are also a number of additional capabilities that can only be performed in Acrobat (and not in Reader), including:
- Invoking a web service from a form (for example, to convert a dollar amount to some other currency)
- Commenting on a form
- Digitally signing a form
- Submitting or sending a form as PDF (a normal submission just sends the XML data contained in the form, but not the form itself)
If you want to allow your users to save a partially completed form, or perform one of these other actions, then you can purchase “Reader Extensions” for your form. By applying Reader Extensions to a particular form, this temporarily extends the capabilities of Reader to allow these features for this particular form. You can purchase Adobe Reader Extensions from Adobe Enterprise Partners.
Alternately, you can purchase a copy of Acrobat for each of your users – this may be more cost effective if you have a large number of forms and a small number of users.
Alternately, Adobe Acrobat provides a “cut-down” version of Reader Extensions built it. It only provides some of the above features, and is limited to a small number of forms and small number of end-users. Contact your Adobe Enterprise Partner to find out whether you can use this feature for your scenario.
Pre-fill a form with information that I already know about the user (or some other information)
What you need: LiveCycle Forms or LiveCycle Process Management
Your user has already logged into your site, so you know who they are and other information about them. When they open a form, it’s “polite” to pre-fill the PDF with information you already know about them, to a) avoid them having to re-key it b) reduce errors in their typing. LiveCycle Forms is a server product that that allow you to inject data into any LiveCycle Form prior to serving it up to your users. LiveCycle Process Management is actually a tool for automating human-oriented activities within your organization, but it also includes a light-weight version of the service that allows you to inject data into a form. Contact your Adobe Enterprise Partner for more information on which of these two services is best for your needs.
What else you get:
- Common and Foundation
Provide a user with a printable record or receipt of their interaction with my site
What you need: LiveCycle Output
Your user has already performed some sort of interaction with your site (bought something, filled in a html or PDF form, made a booking, or whatever), and you want to present them with a PDF that is a permanent and printable record of that interaction. Build a LiveCycle SmartForm, and use LiveCycle Output to turn that form into a “flattened” PDF form. It’s now a regular PDF document, without the ability to make any changes to the values of any fields.
What else you get:
- Common and Foundation (see below)
- LiveCycle Output also includes facilities for printing PDF forms directly from the server to a network printer.
- LiveCycle Output also allows you to create documents of record in an ISO archiving format.
Digitally sign my outbound documents to give my users a sense of security that it did come from me and hasn’t been changed
What you need: LiveCycle Digital Signatures
With Livecycle Digital Signatures, you can apply a digital signature to a PDF you’ve created with LiveCycle Designer, or any other PDF document. This can be signed with your corporate (or personal) digital signature. The signing process is automated on the LiveCycle server, and can be invoked programmatically from existing applications, or can be easily incorporated into human processes.
What else you get:
- By signing a document, you make it tamper-proof – if anyone attempts (either maliciously or accidentally) to modify the document in any way, it will invalidate the signature.
- Common and Foundation (see below).
Enter into binding agreements with my customers or suppliers without paper signatures
What you need: LiveCycle Digital Signatures and Reader Extensions
Create a PDF SmartForm with a digital signature field. Post this form on your web site. When users have completed the form, they can use their digital signature to sign the form, and submit it back to you as a signed PDF. You can use the Digital Signatures service on the LiveCycle server to authenticate the signature, obtain information about the person signing, and validate that the document has not been changed since it was signed.
You can use the signature for non-repudiation – in other words, if the person who signed the document says that it wasn’t them, you can show them their digital signature, and since only they can sign things with their digital signature, it had to be that person.
Note: You will need to have a closed user group where you can roll out electronic signatures. For electronic signatures to be valuable, they have to be issued by a certification authority who make you prove who you are, and will attest that you are who you say you are. (You can create self-signed certificates quite easily, but there’s nothing from stopping me from creating one that says I’m Warren Buffet. A certification authority will require proof that I am in fact Warren Buffet before issueing me a signature in that name. Some countries and organizations are starting to roll out digital certificates more broadly.)
What else you get:
- By signing a document, your users make it tamper-proof – if anyone attempts (either maliciously or accidentally) to modify the document in any way, it will invalidate the signature. That way you can prove that it hasn’t been tampered with.
- You can also add a digital signature field to any PDF document on the server (not just SmartForms), and send that to your users for signature.
- You also get services for encrypting a PDF with a password or certificate.
- Common and Foundation (see below).
Capture data from a printed PDF Smartform with 100% reliability and without Optical Character Recognition or manual data entry.
What you need: LiveCycle Barcoded Forms
Create a PDF SmartForm with a 2-D barcode field on it. The barcode can store up to about 512 characters of information, and can be set up to automatically capture information from the SmartForm fields as the user types into the form. When the form is printed, the barcode contains all the information entered into the form. Instead of OCR-ing the text in the form, simply scan the barcode and get all the data. 100% accuracy – you get all the data in one scan.
Turn Office documents into PDFs on the server.
What you need: LiveCycle PDF Generator
Pass any common office document (Word, Excel, Powerpoint, Open Office, many picture formats and other document formats) to PDF Generator, and it will turn it into a PDF. The recipient will not need to have the original application in order to read the document. Can be easily integrated into manual, ad-hoc processes, or invoked from other appliations in order to automate backend processes.
Add Reader Extensions, and cater for ad-hoc commenting and review processes using the capabilities of Adobe Reader.
What else you get:
- You can also do a lot of other types of translations, such as images to PDF, PDF to images, etc.
Store any documents created using LiveCycle (or any other document) in a Document Management System
What you need: LiveCycle Content Services or ECM (Enterprise Content Management) Connectors
You may want to store your documents in a document repository for archiving, or so that users can find all document relating to a particular subject or case or client or whatever. Adobe provide ECM (Enterprise Content Management) Connectors that allow you to store, retrieve and manage documents in many different enterprise document repositories. If you don’t already have a document repository, Adobe provide Document Services, a light-weight but powerful and scalable document management system that is fully integrated with the LiveCycle system.
Content services contains it’s own user interface for browsing, searching, editing, and uploading documents called ContentSpace.
Create approval or back-office processes within my organization
What you need: LiveCycle Process Management
LiveCycle Process Management is a state of the art human-oriented Business Process Management System (BPMS). Processes are generally invoked when someone submits a form (although there are lots of other ways of invoking a process). You can then route a form to a manager or process worker for approval or action. You can also augment the data in the form by fetching additional data from other internal systems (e.g. databases), save form data out to internal systems (e.g. file system, document management systems), send and receive emails, add attachments, send reminders, automatically escalate or deadline tasks to ensure Service Level Agreements, and much more.
What else you get:
- Workspace: An end-user portal where you can initiate new processes, or view your inbox to find tasks that have been allocated to you or a group you belong to.
- Business Activity Monitoring: Dashboards and reports that allow you to view workloads and throughputs, bottlenecks in your process and much more.
- By combining with other LiveCycle services, you can archive documents, merge documents together, send emails, etc.
Host documents on a public-facing site, with pre-population, save-online, receipts, branding, online payment processing, versioning
What you need: Avoka Form Center
Adobe LiveCycle provides all the core services to create, host, pre-populate and process SmartForms. However, if you actually want to create a portal for doing all these things, you have to build it yourself in Java or .Net or some other technology – it’s not provided “in the box”.
Avoka Form Center is built upon Adobe LiveCycle. It provides a rich form-hosting portal that allows public or occasional internal users to:
- Locate forms
- Fill them in
- Save partically completed forms in a drafts location online
- Pre-fill forms based on configurable “profile” information
- Brand the same SmartForm differently depending on the origin of the request, or the user login details
- Automate payment processing for forms that incur a cost
- Provide a history of all submitted forms
- Provide an automatic receipt on completion
Form Center also provides an extensive administrative module, that allows forms to be uploaded, configured, versioned, branded, and much more.
http://www.avoka.com/avoka_formcenter/formcenter.shtml
What are “Common” and “Foundation”?
Common and Foundation are a set of lower level services that are bundled along with other LiveCycle services. You cannot buy these on their own. Foundation is always included with every LiveCycle product. The Common services that are bundled vary from product to product. Please contact info@avoka.com for more details if you’re unsure.
- Common includes services for combining multiple PDFs into one, adding watermarks, adding table of contents, headers, and footers, extracting and injecting data and meta-data, encryption, and more.
- Foundation gives you fantastic integration capabilities with databases, email, file system, messaging and directory services, XML manipulation, and more. This is stuff that the EAI (Enterprise Application Integration) vendors charge you big bucks for, and Adobe gives you for free (with other products).
- The orchestration engine underlying the whole of LiveCycle provides a graphical user interface for defining your “workflows” – no coding required.
- The orchestration engine is inherently extensible – we’ve never found something that a client wanted it to do that we couldn’t make it do.
What do the LiveCycle ‘Process Fields’ really do?
Background
In order to integrate a LiveCyc le PDF form into LiveCycle Process Management, you need to embed some special fields into your form.
The LiveCycle documentation does indicate what these fields are for, but doesn’t really explain exactly how they are used and populated.
Process Field Documentation Link
This blog entry explains how it all really works.
The Fields
The Process fields inside Designer look like this:
The scenarios
When integrating with Process Management, the form will be presented inside Workspace. There are a number of scenarios:
- A user is submitting a form within Workspace (either to initiate a process, or as an item in their To Do list)
- The user has taken an initialization form offline
- The user has taken a form from their inbox offline.
Submitting a form within Workspace
In fact, for this basic scenario, you don’t need the process fields at all. All you really need is a Submit button.
However, if you do use the process fields, you get a few extra capabilities, including user choices, and the option to take the form offline.
The field AWS_SUBMIT is a regular button that contains some Javascript code. This code, among other things, checks whether you’re running in an online (within Workspace) or offline mode. If you’re running online, it simply sends a “click” event to the real submit button, FSSUBMIT_ (which is a hidden http submit button).
Apart from the choice fields described below, none of the other fields are necessary – LiveCycle knows exactly who you are, and what you’re doing, because you’re logged into a live session in Workspace. It’s only when you take a form offline that the other fields are necessary.
Giving the user a choice
Sometimes you want to give your users a choice, which will affect the routes that are taken within the LiveCycle process. If you put a bit of text into the AWS_CHOICE text field, such as “Approve,Deny”, the Javascript code will:
- Display the Action dropdown (if there are no choices, it will be hidden)
- Populate the Action dropdown with the values from the AWS_CHOICE field.
It will look something like this:
You can put your own comma-separated text into AWS_CHOICE, but LiveCycle will automatically do a whole bunch of useful things for you.
- When you create a User Assign Task step in your workflow, check the checkbox that says “Populate Form with Routes”. LiveCycle will then look at all the route names coming out of your User step, and populate AWS_CHOICE with the route names.
- When the user submits the form, LiveCycle will interrogate the value of the Action dropdown, and automatically route the process down the selected route.
Note: If you choose not to use this option, you can simply create rules in your routes that interrogate other data within your form to decide which route to follow.
Note: Certain route names are associated with special icons in Workspace. These are “Approve” and “Reject” (or maybe “Deny”, I forget.) You can configure these special icons and their associated routenames from Adminui.
Taking a form offline.
Once you take a form offline, it is “disconnected” from Workspace. You can fill it in, and when you click the Submit button, it will be submitted via email, rather than over the web. The AWS_Submit button has logic to determine whether you’re online or offline, and submit either via the web or via email.
If you’re submitting via email, the form needs to know what email address to submit it to. This email address is automatically populated by LiveCycle into the AWS_MAILTO field when you take the form offline. Like all the other fields, there’s no real magic – you can set the field to an email address manually or in code if you want to, but generally it’s easier and safer to let the LiveCycle server take care of this for you.
Note: In order to allow offline submissions, you need to set up a email box, and configure LiveCycle to monitor this email box. That’s the subject of another blog sometime. Email info-at-avoka.com if you’re having trouble.
When you submit your form data via email, LiveCycle no longer knows anything about you, or why you’re submitting the form. It simply knows that an email arrived in an inbox containing some XML as an attachment. So…
When you take the form offline, LiveCycle injects some data into a few fields:
- When you take an initialization form offline, the LiveCycle server will populate AWS_PROCESSTYPE with the name of the process that should be initiated when you submit the form. When you submit the form via email, LiveCycle will start the named process on your behalf, using the data from the email attachment.
- When you take a form in your inbox offline, the LiveCycle server will populate AWS_TASKID with the id of the task that this relates to. When the submit the form via email, LiveCycle will complete that task on your behalf.
- In both cases, LiveCycle will use the email address of the sender of the email of the email to determine who the “completer” was. Warning: make sure you send from an email associated with your LiveCycle identity – if LiveCycle doesn’t recognize the sender, it will treat the email as spam, and silently discard the incoming email. (I haven’t verified this lately, but it used to work this way.)
- In both cases, the LiveCycle server will populate the AWS_ASSIGNEDID with the internal LiveCycle ID of the user who was originally assigned this form. I have no idea whether this is used for anything, or why it might be useful to either you or LiveCycle.
- Finally, once you submit via email, Reader will set the AWS_STATUS field from ” ” to “Submitted”. Once this field has the “Submitted” value, you will not be able to submit the form again. This simply prevents duplicate submissions being accidentally emailed.
Summary
While there’s quite a bit of logic associated with these fields, both within the form and with the LiveCycle server, you don’t really need to know how it all works. Just drop the fields into your form, and LiveCycle takes care of the rest. It is helpful, however, to know how this works, so that you can tweak the behaviour if necessary.
How to read a LiveCycle stack trace
When an error occurs in LiveCycle, you’ll usually get some sort of stack trace in the application server log files. It’s very important to be able to read and understand the stack trace, because this is your best opportunity to find out what went wrong.
A typical stack trace often looks quite daunting at first, something like this: (Don’t try to read it, just scroll down…)
javax.ejb.TransactionRolledbackLocalException: Got error 139 from storage engine; CausedByException is:
Got error 139 from storage engine
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:247)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:335)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:166)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:153)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:624)
at org.jboss.ejb.Container.invoke(Container.java:873)
at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:415)
at org.jboss.ejb.plugins.local.StatelessSessionProxy.invoke(StatelessSessionProxy.java:88 )
at $Proxy180.writeObject(Unknown Source)
at com.adobe.pof.omapi.POFObjectManagerLocalEJBAdapter.writeObject(POFObjectManagerLocalEJBAdapter.java:135)
at com.adobe.workflow.datatype.POFVariableContainer.write(POFVariableContainer.java:133)
at com.adobe.workflow.pat.service.PATExecutionContextImpl.writeResults(PATExecutionContextImpl.java:108 )
at com.adobe.workflow.engine.ProcessEngineBMTBean.continueBranchAtAction(ProcessEngineBMTBean.java:2944)
at com.adobe.workflow.engine.ProcessEngineBMTBean.asyncContinueBranchCommand(ProcessEngineBMTBean.java:2392)
at sun.reflect.GeneratedMethodAccessor528.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:214)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:149)
at org.jboss.webservice.server.ServiceEndpointInterceptor.invoke(ServiceEndpointInterceptor.java:54)
at org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:48 )
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:106)
at org.jboss.ejb.plugins.AbstractTxInterceptorBMT.invokeNext(AbstractTxInterceptorBMT.java:158 )
at org.jboss.ejb.plugins.TxInterceptorBMT.invoke(TxInterceptorBMT.java:62)
at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:154)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:153)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:624)
at org.jboss.ejb.Container.invoke(Container.java:873)
at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:415)
at org.jboss.ejb.plugins.local.StatelessSessionProxy.invoke(StatelessSessionProxy.java:88 )
at $Proxy200.asyncContinueBranchCommand(Unknown Source)
at com.adobe.workflow.engine.ProcessCommandControllerBean.doOnMessage(ProcessCommandControllerBean.java:133)
at com.adobe.workflow.engine.ProcessCommandControllerBean.onMessage(ProcessCommandControllerBean.java:94)
at sun.reflect.GeneratedMethodAccessor439.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
at org.jboss.ejb.MessageDrivenContainer$ContainerInterceptor.invoke(MessageDrivenContainer.java:475)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:149)
at org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDrivenInstanceInterceptor.java:101)
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:106)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:335)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:166)
at org.jboss.ejb.plugins.RunAsSecurityInterceptor.invoke(RunAsSecurityInterceptor.java:94)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
at org.jboss.ejb.MessageDrivenContainer.internalInvoke(MessageDrivenContainer.java:389)
at org.jboss.ejb.Container.invoke(Container.java:873)
at org.jboss.ejb.plugins.jms.JMSContainerInvoker.invoke(JMSContainerInvoker.java:1077)
at org.jboss.ejb.plugins.jms.JMSContainerInvoker$MessageListenerImpl.onMessage(JMSContainerInvoker.java:1379)
at org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:256)
at org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:904)
at org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:160)
at org.jboss.mq.SpySession.run(SpySession.java:333)
at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:180)
at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:748 )
at java.lang.Thread.run(Thread.java:595)
Note that there’s a second separate exception here. This line doesn’t start with “at”. This is usually the “caused by” part of the same exception.
java.sql.SQLException: Got error 139 from storage engine
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2928 )
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1124)
at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:676)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1166)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1082)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1067)
at org.jboss.resource.adapter.jdbc.CachedPreparedStatement.executeUpdate(CachedPreparedStatement.java:81)
at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeUpdate(WrappedPreparedStatement.java:227)
at com.adobe.pof.adapter.JDBCAdapter.updateObject(JDBCAdapter.java:519)
at com.adobe.pof.adapter.JDBCAdapter.updateObject(JDBCAdapter.java:442)
at com.adobe.pof.omapi.POFObjectManagerImpl.writeObject(POFObjectManagerImpl.java:254)
at com.adobe.pof.omapi.POFObjectManagerRemoteBean.writeObject(POFObjectManagerRemoteBean.java:271)
at sun.reflect.GeneratedMethodAccessor381.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:214)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:149)
at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:154)
at org.jboss.webservice.server.ServiceEndpointInterceptor.invoke(ServiceEndpointInterceptor.java:54)
at org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:48 )
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:106)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:335)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:166)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:153)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:624)
at org.jboss.ejb.Container.invoke(Container.java:873)
at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:415)
at org.jboss.ejb.plugins.local.StatelessSessionProxy.invoke(StatelessSessionProxy.java:88 )
at $Proxy180.writeObject(Unknown Source)
at com.adobe.pof.omapi.POFObjectManagerLocalEJBAdapter.writeObject(POFObjectManagerLocalEJBAdapter.java:135)
at com.adobe.workflow.datatype.POFVariableContainer.write(POFVariableContainer.java:133)
at com.adobe.workflow.pat.service.PATExecutionContextImpl.writeResults(PATExecutionContextImpl.java:108 )
at com.adobe.workflow.engine.ProcessEngineBMTBean.continueBranchAtAction(ProcessEngineBMTBean.java:2944)
at com.adobe.workflow.engine.ProcessEngineBMTBean.asyncContinueBranchCommand(ProcessEngineBMTBean.java:2392)
at sun.reflect.GeneratedMethodAccessor528.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:214)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:149)
at org.jboss.webservice.server.ServiceEndpointInterceptor.invoke(ServiceEndpointInterceptor.java:54)
at org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:48 )
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:106)
at org.jboss.ejb.plugins.AbstractTxInterceptorBMT.invokeNext(AbstractTxInterceptorBMT.java:158 )
at org.jboss.ejb.plugins.TxInterceptorBMT.invoke(TxInterceptorBMT.java:62)
at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:154)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:153)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:624)
at org.jboss.ejb.Container.invoke(Container.java:873)
at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:415)
at org.jboss.ejb.plugins.local.StatelessSessionProxy.invoke(StatelessSessionProxy.java:88 )
at $Proxy200.asyncContinueBranchCommand(Unknown Source)
at com.adobe.workflow.engine.ProcessCommandControllerBean.doOnMessage(ProcessCommandControllerBean.java:133)
at com.adobe.workflow.engine.ProcessCommandControllerBean.onMessage(ProcessCommandControllerBean.java:94)
at sun.reflect.GeneratedMethodAccessor439.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
at org.jboss.ejb.MessageDrivenContainer$ContainerInterceptor.invoke(MessageDrivenContainer.java:475)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:149)
at org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDrivenInstanceInterceptor.java:101)
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:106)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:335)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:166)
at org.jboss.ejb.plugins.RunAsSecurityInterceptor.invoke(RunAsSecurityInterceptor.java:94)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
at org.jboss.ejb.MessageDrivenContainer.internalInvoke(MessageDrivenContainer.java:389)
at org.jboss.ejb.Container.invoke(Container.java:873)
at org.jboss.ejb.plugins.jms.JMSContainerInvoker.invoke(JMSContainerInvoker.java:1077)
at org.jboss.ejb.plugins.jms.JMSContainerInvoker$MessageListenerImpl.onMessage(JMSContainerInvoker.java:1379)
at org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:256)
at org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:904)
at org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:160)
at org.jboss.mq.SpySession.run(SpySession.java:333)
at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:180)
at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:748 )
at java.lang.Thread.run(Thread.java:595)
Usually, if there are two exceptions, the second one, often preceded by “Caused by” gives you more detailed information. So I’m just going to ignore the first exception for now, halving the amount of detail I need to worry about.
Then I typically ignore anything that doesn’t belong to Adobe or the component implementation (i.e. All the “jboss” stuff)
Now that I’ve reduced it down to a manageable amount, I start from the bottom up, trying to work out what’s going on when the error occurred. This helps us both to understand, diagnose, and potentially reproduce the problem. The very top line usually contains the actual error. See annotations below, working from the bottom up:
java.sql.SQLException: Got error 139 from storage engine
4. error 139: We got a strange error from the “storage engine”, meaning the database itself. Let’s go google that. (I’ll leave this as an exercise for the reader.)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2928 )
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1124)
at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:676)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1166)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1082)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1067)
…
3. executeUpdate: We seem to be updating a row in the database using the mySQL JDBC driver
at com.adobe.pof.adapter.JDBCAdapter.updateObject(JDBCAdapter.java:519)
at com.adobe.pof.adapter.JDBCAdapter.updateObject(JDBCAdapter.java:442)
at com.adobe.pof.omapi.POFObjectManagerImpl.writeObject(POFObjectManagerImpl.java:254)
at com.adobe.pof.omapi.POFObjectManagerRemoteBean.writeObject(POFObjectManagerRemoteBean.java:271)
at $Proxy180.writeObject(Unknown Source)
at com.adobe.pof.omapi.POFObjectManagerLocalEJBAdapter.writeObject(POFObjectManagerLocalEJBAdapter.java:135)
at com.adobe.workflow.datatype.POFVariableContainer.write(POFVariableContainer.java:133)
at com.adobe.workflow.pat.service.PATExecutionContextImpl.writeResults(PATExecutionContextImpl.java:108 )
2. writeResults: Yup, the engine is now trying to write the results that the component returned back into the process variables
at com.adobe.workflow.engine.ProcessEngineBMTBean.continueBranchAtAction(ProcessEngineBMTBean.java:2944)
1. continueBranchAtAction: a particular step is being “continued” – probably means that the component itself has already been executed, now we need to “continue” it to completion
at com.adobe.workflow.engine.ProcessEngineBMTBean.asyncContinueBranchCommand(ProcessEngineBMTBean.java:2392)
We still don’t know exactly why this failure occurred, but we have a much better idea of where and why it happened, and we’re well placed to diagnose further.
Obviously, every stack trace is different, but hopefully this gives you a technique that will help you to understand what went wrong, and fix it.
Free Desktop Alerter for LiveCycle Workspace
Avoka Alerter for Workspace provides notification of new tasks in your LiveCycle ES Workspace queues by sending task alerts to your desktop.
You can now be notified of LiveCycle ES Workspace tasks without having an open browser to host Workspace, or your email application to monitor notifications. Alerter also allows you to open, view and prioritize tasks, directly from the desktop!
The Alerter AIR application can just sit in the system tray. New tasks are alerted to your desktop as yellow “toast” popups. The opened application shows your personal work queue and each of your group queues as bars in a barchart. The longer the bar, the more tasks allocated to that queue.
Clicking on any task will open its respective form. Views are automatically refreshed.
And Yes, it’s completely FREE.
Populating a drop-down using XML and Dynamic Binding
In one of our previous blogs, we mentioned several techniques for populating a drop-down list with data. In this posting, we’re going to use a technique called “Dynamic Binding”. We’re going to use an XML file to populate the drop-down, as well as for populating a repeating lists of questions.
The form we’re going to develop is a general purpose survey form, where both the list of questions, and the answers allowed, are pre-populated with XML. Since Designer only supports a single XML file, we’re going to store the drop-down values, the questions, and the answers that the end-user selects, all in the same XML file.
The Sample PDF is here: dynamic_survey_with_embedded_data. Try it out before you start the exercise, so you can see what we’ll end up achieving.
Note:
- You can just open this file in Reader to try it out
- You can open it in Designer to see how it works
- The PDF has two attachments, the XML schema and a sample XML file. Click on the paper-clip icon to get at these.
It also contains the sample XML and schema files as embedded attachments.
Step 1: create the schema

Note that “Question” and “ResponseItem” are repeating, with a cardinality of 1..*. “Questions” will be used to populate the list of questions dynamically. “ResponseItems” will be used to populate the drop-down list containing the user’s responses.
Step 2: Create a simple form
You must save it as a Dynamic PDF form, because it’s going to grow based on the data we put into it. Also, because we’re going to grow the number of questions based on the data in the XML file, we need to use a Flowed rather than Positioned layout.
Note that the table has only one row (set to “repeating” on the binding tab), and a DropDown list with no values specified.
Step 3: Add the schema to the form

Add the schema to the form by defining a new data connection. Embedding the schema is optional, but useful if you’re ever going to use this form within a LiveCycle process.
Step 4: Create the XML file
Make sure it conforms to your schema. Here’s a snippet:
Step 5:Turn on Dynamic Binding
This is available from the drop-down menu of the Object palette in Designer.

Step 6: Bind the schema elements to the form objects
Use the Binding sub-tab of the Object palette.
- Bind Row1 to the Question[*] repeating group – this will ensure that for every row of Question data in the XML, we’ll get a new Row1 in the form.
- Bind the Question and Answer fields to the sub-elements of the repeating group. Note that you use relative binding, because the repeating element is already bound to Row1.
Step 7: Dynamic Binding
Bind the drop-down’s values and labels to the elements defined in the schema. Click on the green “Specify Item Values” link, and in the Dynamic properties dialog, enter the repeating element, and the sub-items containing the text (the values displayed) and value (the values stored in the data). This is summarized in the screenshot below:

If you don’t see the green link, revisit Step 5.
Step 8: Preview the form
In Designer, set the “Data File” to point to your sample xml file.

Click on the Preview tab. You should see something like this:

Try changing the data in the sample XML file (for example, adding “No opinion” to the drop-down data, or a new question), and then preview again. You should see the new question and drop-down items appear.
Finally
You can embed the XML data into the form manually using Acrobat or automate it on the server via LiveCycle Forms or Process Management. Using a LiveCycle orchestration, you could of course generate the XML using a database query or some other source.
If you’d like more information on how to do this, please contact info@avoka.com
Creating a Read-only copy of a form
Overview
Very often, as part of a process, you’ll want to create a read-only copy of a form, and store it somewhere, or email it to someone. There are various ways of achieving this, and they vary in different ways.
Making the fields read-only
It’s possible to make all the fields in the form read-only, using some Javascript coding. This is fairly straight forward, and looks something like:
TextField1.access="readOnly"
If you have a few fields on your form, you can just do this for each field. If you have a lot of fields, you’ll probably want to write this as a recursive function, and do all fields in a single function call. This can be quite fiddly, because you need to correctly handle all the different types of form objects. (Avoka can help with this – contact info-at-avoka.com for assistance.)
Pros
- Inexpensive
Cons
- Can be fiddly to program
- While this makes the form appear to be read only, a clever end-user could still modify it. To modify it, open the form in Acrobat, use Forms/Manage Form Data…/Export Data… to export the data as XML, modify the XML, and then re-import the XML data using Forms/Manage Form Data…/Import Data… The form data will have changed, and nobody is any the wiser.
“Flattening” the form
Adobe have a server product called LiveCycle Output. One of the things that LC Output will do is “flatten” a form – that means that it will be converted from an editable type of PDF document to a more traditional “read-only” document. The fields are no longer editable fields, they are really now just boxes and text drawn onto the page.
Pros
- This is much more secure than setting fields to read only. The XML data no longer exists, and cannot be modified.
- No JavaScript programming required to achieve this – simply route your form to LiveCycle Output, and generate the flattened PDF.
Cons
- It’s still possible to modify the PDF file to change what appears on the form. This is much harder, because the PDF is now in a binary format, but it’s possible.
- Requires server-side integration
- Requires purchasing LiveCycle Output (but LC Output does other useful things, so this may really be an overall benefit to your organization).
Digitally Signing the Document
Digitally signing the document doesn’t actually prevent the document from being modified, so needs to be used in conjunction with one of the above techniques. However, it does take a “snapshot” of the document, and if any changes are made, the signature will be invalidated. This enables you to guarantee that the version of the file you saved has not been modified since it was produced.
Pros
- Guarantees that the PDF has not been modified since it was saved.
Cons
- If signing is performed directly by the client, it requires Adobe Acrobat (or Reader Extensions)
- If signing is performed on the server, then you must purchase a copy of LiveCycle Digital Signatures, and integrate this into your process.
Summary
There are several different techniques for making a form read-only. The one to use depends primarily on how willing you are to accept the risk of the document being changed (accidentally or maliciously) after it’s been produced, and how much you are willing to spend to achieve the level of protection you want.
What is Reader Extensions?
Adobe have two products for dealing with PDF files:
- Adobe Acrobat – mainly for creating new PDF files, in many different ways.
- Adobe Reader – mainly for reading existing PDF files. Can also be used to fill in forms. Reader is free.
There are some additional limitations in Reader. In particular, when you fill in a form, there are several things that you can ONLY do if the form is opened in Acrobat, and will not work in Reader. These include:
- Saving a copy of the form with the form data embedded in it. (This is considered to be creating a “new” form, which can only be done in Acrobat.)
- Submitting the form as PDF. (Again, this is considered to be creating a new PDF.) Submitting as XML is always possible in both Reader and Acrobat.
- Digitally signing the form. (Again, this is considered to be creating a new version of the form.)
- Adding comments or annotations. (Ditto.)
- Invoking web services directly from the form.
So what do you do if you’ve created a PDF Form, and you want to publish it on your web site, and want your users to be able to do any of the above?
Enter Reader Extensions! Tadaaah!
Reader Extensions allows you to apply a special “tag” to a PDF document. When that document is opened in Reader, all the features listed above will miraculously be available (just for that one document).
There are two ways to apply Reader Extensions to your document:
- Purchase a Reader Extensions certificate for your document from Adobe (<plug>through one of Adobe’s authorized partners, such as Avoka </plug>) You will need to install Adobe LiveCycle on one of your servers to actually apply the certificate to your document – but once the certificate has been applied, you don’t need to use the server any more. (Although you do get LiveCycle Foundation with Reader Extensions – so you have a server with a whole lot of really useful features.)
- Use the limited-use, cut-down version of Reader Extensions available in Acrobat. This only enables a subset of the capabilites above, and is limited to a maximum of 500 recipients. In Acrobat, use Forms/Distribute Form…
For more information about Reader Extensions, see:
http://www.avoka.com/ad_livecycle_es/reader_extensions_es.shtml
If you’re interesting in more information, or purchasing Reader Extensions, please email sales-at-avoka.com







