Avoka Blog: Adobe LiveCycle

April 29, 2009

PDF and Flex Accessibility – part 1

Filed under: 1, Designing Forms, LiveCycle — Tags: , — pcopeland @ 7:57 am

The bottom line

Despite some misconceptions, PDF and Flex/Flash solutions can be highly accessible. However, it does not happen automagically. Project commitment is required to attain the desired level of accessibility. It is advocated that ITC professionals spend time to understand accessibility, regulatory compliance, the capabilities of Adobe technologies and apply the appropriate level of consideration in project planning. It is far more expensive to retro-fit changes, rescue a failed project or limit brand damage caused by building a solution that, for example, is unavailable to an important community of Mac users or is complained about in a public forum by a blind user. This blog is the first in a series that explores the, often misunderstood, field of accessibility. This introduces the basic concepts and sets the context for subsequent blogs which will cover the practical aspects of implementing accessible PDF and Flex solutions.

What is accessibility?

Accessibility can be considered the degree to which electronic services and products can be accessed by the largest number of users possible. Although, often focused on disabled people, this is relevent to all people, including those that are on slow broadband, using non mainstream operating systems, using a mobile device or speaking non native languages. Accessibility is closely related to the concept of usability. Usability can be considered the ease with which a specified group of people can use an electronic service or product.

Why should I care about accessibility?

Technological progress and the meteoric rise of the Internet continues to fuel the trend of delivering services and goods through electronic channels. As the trend progresses, the opportunities and responsibilities of accessibility increase. The three primary reasons to care about accessibility are:

  1. It is good for business – increase leads and convertion to sales
  2. It is good for society – provide access for more people to the benefits of technological advancement
  3. You have to – legislation has been passed around the world that mandates accessibility requirements

Accessibility and disability

Although, accessibility is often set in the context of totally blind people, there are different categories of disabilities with different accessibility requirements.

Types of disability

The major categories of disability types are:

Visual disability Visual Blindness, low vision, color-blindness
Hearingdisability Hearing Deafness
Motor disability Motor Inability to use a mouse, slow response time, limited fine motor control
Cognitive disability Cognitive Learning disabilities, distractibility, inability to remember or focus on large amounts of information

What is Assistive Technology?

Assistive technology refers to any product or software program that has been developed or modified to make it accessible for the disabled. Of the wide range of assistive technologies available, the most relevent to PDF and Flex solutions are screen readers, text-to-speech, screen magnifiers and braille output devices.

Screen Readers

Screen readers are software that interprets what is being displayed on screen and re-presents it as synthesised speech or on a Braille output device. According to the WebAIM Survey of Preferences of Screen Readers Users completed in January 2009, the top three screen readers being used by 1121 respondents were:

JAWS and Window-Eyes are commercial products that offer evaluation licences. NVDA is a free, open-source screen reader. Screen readers are highly configurable, complex software that is designed to enable the operation of a computer in ways that are very different from the traditional keyboard and mouse methods employed by fully sighted users. The WebAIM screen reader simulation tool is an interesting way for a fully sighted user to experience the use of screen readers. It is recommended that screen reader testing be performed by specialist users.

Text to Speech

Text to speech software re-present normal language text as an artificial production of human speech. This software is used by screen readers and can be used independently. Common programs include ReadPlease and NaturalReader.

Screen Magnifiers

Screen magnifiers are software that interface with a computer’s graphical output to present enlarged screen content for the partially sighted.

Braille output devices

Braille output devices re-present text as braille by raising pins through a flat surface in braille characters.

What is the web standard for accessibility?

Since 1999 the primary international standard for website accessibility has been the Web Content Accessibility Guidelines (WCAG) developed by the W3C. This has formed the basis for accessibility legislation around the world, including Section 508 in the US and the 2000 Government Online Strategy in Australia. In December 2008, the W3C released WCAG 2.0 recommendation. Version 2 is a significant update to its predecessor. WCAG 2.0 is build around four basic principles:

Perceivable Information and user interface components must be presentable to users in a way that they can perceive
Operable User interface components and navigation must be operable
Understandable Information and the operation of user interface must be understandable
Robust Content must be robust enough that it can be interpreted reliably by a wide variety of user agents, including assistive technologies

Each of these four principles contains a number of guidelines outlining how a website should meet all users’ needs. Within the guidelines there are a number of success criteria which outline how the web content should be developed to meet the guidelines. There are three levels of conformance within WCAG 2.0, A, AA and AAA (the highest level). In order to conform to WCAG 2.0, the web content must satisfy at least level all of the Level A success criteria. The diagram below shows the minimum success criteria that must all be satisfied for web content to conform to WCAG 2.0: WCAG 2.0 - Level A WCAG 2.0 introduces the notion of “Accessibility Supported” and the requirement that only “accessibility supported ways of using technologies” can be relied upon to satisfy the success criteria. As both Adobe Reader and Flash Player are free and generally available from the Adobe web site, PDF and Flex satisfy the first of the basic requirements for it to be considered “accessibility supported” under the standard:

  • Users of the web must be able to obtain user agents for the Web Content technology that are accessibility supported. The W3C suggests this can be achieved in one of four ways.
    • In its basic state the technology is accessible to common user agents – e.g. HTML is supported by browsers. OR
    • The technology is supported by an accessible plug in such as Flash that is generally available. OR
    • he content is to be used in a closed environment such as a university or corporate network, where the necessary accessibility supported technologies are supplied. OR
    • The user agent that allows the technology to be accessible is easy for a person with a disability to obtain and it doesn’t cost any more than it would for someone without a disability.

Developments in the Adobe Acrobat, Reader and Flash Player in partnership with assitive technology vendors results in PDF and Flex passing the second of the basic requirements:

  • The way a particular web content technology is used must be supported by the assistive technology, that is, if you use JavaScript or PDF, for example, you must do so in a way that allows the final product to be accessed by assistive devices like screen readers and switches.

The accessibility myth

It is a misconception that PDF and Flex solutions cannot be accessible. There are two primary reasons for this:

Many existing PDF and Flex solutions on the web are not highly accessible

This is either due to projects not investing in accessibility or, particularly in the case of PDF technology that has been around for a long time, and was developed prior to versions of Reader and Flash Player that do support accessibility. Although HTML supports accessibility, it is possible (even easy) to implement HTML web-sites that are horribly inaccessible. Just because HTML supports accessibility does not mean that all HTML sites are automatically accessible – it takes effort and care to achieve this. In the same way modern versions of Reader and Flash do support accessibility and it is possible to build PDF and Flash content that is accessible. It is up to PDF and Flash developers to learn about these features and implement them correctly.

A bias of the earlier standard WCAG 1.0 was towards W3C web technologies

WCAG 1.0 has been the W3C endorsed standard for nine years and is the referenced standard for accessibility legislation around the world. WCAG 1.0 is technology dependent; Guideline 11 of the standard has two checkpoints relating to what technologies are accessible:

  • Checkpoint 11.1 has priority 2 (should) and says to use W3C technologies
  • Checkpoint 11.4 has priority 1 (must) and says that if you cannot create an accessible page, then an alternate accessible page that uses W3C technologies must be provided

One of the key drivers to WCAG 2.0 was to become technology agnostic, thereby opening the standard to non-W3C technologies such as PDF and Flex.

Advertisements

April 7, 2009

Processes, Orchestrations, Services, and other confusing terminology

Filed under: Components, Designing Processes, LiveCycle, LiveCycle Architecture — htreisman @ 11:47 am

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.

process

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.

components

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.

services1

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.

March 17, 2009

Speedup JBoss LiveCycle Startup

JBoss Start-up Performance

Starting JBoss with a fully configured LiveCycle installation can take an awfully long time! We’ve done some digging and found that a large portion of this time is spent unpacking the LiveCycle EAR file – and copying these files into the jboss/server/all/tmp directory. In fact a fully configured LiveCycle EAR can amount to over 800 MB of data being written – which adds a considerable amount of time to the start-up.

JBoss supports unpacked EAR and WAR files in the deploy directory, which will save these files from being unpacked at start-up time. To simplify this we’ve created a small utility that unpacks the LiveCycle EAR file and all of its contents into the deploy directory.  

We’ve found that its halved the JBoss start-up time – on my laptop this saved nearly 8 minutes – which is lots when you have to restart Jboss often.

Instructions:

Download Link
 

 

 

  1. Download the utility and unzip the file. You should have a file called “AdobeJBossEarUnpacker.jar
  2. Run the Jar – it will prompt you for the location of the JBoss deploy directory (typically its under your LiveCycle install directory in /jboss/server/all/deploy).
  3. That’s it. It will create a copy of your LiveCycle.ear file then proceed to unpack LiveCyle inside your deploy directory. Whenever you need to redeploy LiveCycle make sure you delete the exploded directory first. 

Startup Sequence

While we are on the topic of starting JBoss another really handy trick is to make use of the “deploy.last” sub-directoy. Any files placed in this directory won’t be deployed until all the files in the main deploy directrry have started. This can be very handy when you have an application that is dependant on a LiveCycle service – which means that you don’t want it to start until LiveCycle its-self has fully started.

PS – Thanks to Malcolm Edgar for some great investigative work and creating the unpacker util.

March 2, 2009

Which “bit” of LiveCycle do I need?

Filed under: Components, LiveCycle, LiveCycle Architecture — htreisman @ 7:45 pm

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.

March 1, 2009

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:

process-fields-in-designer

The scenarios

When integrating with Process Management, the form will be presented inside Workspace. There are a number of scenarios:

  1. A user is submitting a form within Workspace (either to initiate a process, or as an item in their To Do list)
  2. The user has taken an initialization form offline
  3. 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:

approvedeny

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.

February 10, 2009

How to read a LiveCycle stack trace

Filed under: Application Servers, LiveCycle, LiveCycle Administration — htreisman @ 11:01 am

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.

February 9, 2009

Using the Avoka XQuery Service Component

Filed under: Components, Designing Processes — Jason Hendry @ 8:46 am

Livecycle has some useful Service components for manipulating files, database rows and XML documents. And while XSLT is a powerful and useful language, it can sometimes be a little unwieldy to express simple logical problems.

I recently had to perform some simple logical programming on the server side to select one of three text fields on a form. The text fields were comments from users and the last user to touch the form before exiting the flow had their comments inserted into an email back to the form originator. There are a multitude of different ways of handling this problem on the form instead of on the server, however, this problem came to me as a system maintainer and there were constraints I had to observe.

Avoka’s XQuery component makes it possible to construct strings and XML fragments using the XQuery language. XQuery, as you may know, has a syntactic structure called FLWOR or

For
Let
Where
Order
Return

This is typified by the example given on W3Schools using the Books XML data sample:

for $x in doc("books.xml")/bookstore/book
where $x/price>30
order by $x/title
return $x/title

*Note that the Let is implied in $x in doc(…)/bookstore/book

But what I needed was not an iterative solution (at least, not one that required a for loop), but a way to simply express the conditional logic to select the first non-empty XML text node.

To test the hierarchy of user’s for the last commenter, I could have used a number of Decision and Set components, but why take 3 steps when you can take 1?

Alternately, I could have implemented similar logic using the Livecycle script component and while it would have performed in a single workflow step, the script component can be unwieldy when manipulating form values. Do you really want to …

patExecContext.getProcessDataStringValue("/process_data/status");

… just to test a couple of values?

Step 1: Workflow

There are two possible types of invocation on the XQuery Service Component, Single Document and Merge Document.  The Merge Document invocation is intended to be more powerful so in this example we’ll be considering the Single Document invocation of the XQuery component.

I inserted the XQuery component (Last Commenter) into the workflow, just before the email step to notify the originator of the last user’s comments.   This is where we’ll test the form data variable for the comment fields, and then copy them into another process variable to be inserted in the email.

Inserting the XQuery service object into the workflow

Inserting the XQuery service object into the workflow

Step 2: Service Configuration Parameters

The XQuery object is fairly simple to setup, only requiring an XQuery statement and an Output location. In the example here, I’m using a variable, emailCreditComments, to capture the comment tex which I’ll re-use in the following email workflow step.

Configuring the Avoka XQuery Service Component

Configuring the Avoka XQuery Service Component

Step 3: XQuery Statement

First, I chose a location in my process variables to act as the root of my XQuery statement. This is a parameter of the statement, rather than the XQuery configuration and acts to reduce the size of the document the XQuery statement operates on.  Since I’m looking for comment fields, I set the location deep into my XFA form variable structure:

/process_data/form/object/data/xdp/datasets/data/DocumentRoot

In this example, I’m using the root of the XFA data passed into the process as a form variable.

Next, as a matter of style, I set the form comments text into re-usable variables that I can test.

let $sp := //FormData/SeniorPartner/Comments/text()

Then, I constructed a logic statement that allowed for graceful regression without forcing the flow. In most functional programming languages, this style of cascading if() statement is to be avoided since it can become a real headache for maintainers. However, the nature of service components in Livecycle means that we can consider (and re-use!) pieces of functionality independently.

let $sp := //FormData/SeniorPartner/Comments/text()
let $hod := //FormData/HeadOfDepartment/Comments/text()
let $mgr := //FormData/Manager/Comments/text()
return if (string-length($sp) = 0)
	then if(string-length($hod) = 0)
		then $mgr
	else $hod
else $sp

As you can see the statement itself is quite simple, cascading from each if() statement, testing for validity in the order of the user hierarchy (Senior Partner, Head of Department, Manager). Validity in this case is a test for string length, such that any test that fails indicates we have a non-empty comment text node.  The first test to fail gets it’s comment text returned via the else clause and inserted into the configured output location.

XQuery Service Configuration Statement
Lastly, since the result of the XQuery statement will be inserted into an email, rather than re-used as an XML data set, we tell the XQuery service component to omit the XML processing instruction. Other options include the ability to ‘pretty print’ the output and to re-use namespaces from the source process definition.

Summary

This example demonstrates a simple, if somewhat unusual use of the XQuery language implemented using the Avoka XQuery Service Component.

References

http://manly.avoka.com/confluence/display/Public/XQuery+DSC

http://www.w3schools.com/xquery/default.asp

February 2, 2009

Free Desktop Alerter for LiveCycle Workspace

Filed under: LiveCycle Administration, LiveCycle Workspace — htreisman @ 9:01 pm

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!

alerter

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.

More information and download link.

January 12, 2009

Populating a drop-down using XML and Dynamic Binding

Filed under: Designing Forms, LiveCycle Forms — htreisman @ 8:45 pm

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

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.

Form Design

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

data_connection

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:

xml

Step 5:Turn on Dynamic Binding

This is available from the drop-down menu of the Object palette in Designer.

Dynamic Properties

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:

drop_down_bindings

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.

preview_data

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

final_form

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

November 8, 2008

Creating a Read-only copy of a form

Filed under: Designing Forms, Designing Processes, LiveCycle — htreisman @ 2:27 pm

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.

Older Posts »

Blog at WordPress.com.