Avoka Blog: Adobe LiveCycle

October 31, 2008

What is Reader Extensions?

Filed under: Designing Forms, LiveCycle, LiveCycle Architecture — htreisman @ 9:44 am

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:

  1. 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.)
  2. 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

October 30, 2008

Submitting from a form in PDF Format

Filed under: Designing Forms, LiveCycle — htreisman @ 3:21 pm

When you put a Submit button on a form, you can select either XML or PDF format (as well as some others that we’ll ignore for now.)

  • XML format contains only the data from your form, in XML format.
  • PDF format contains a copy of the form being filled in, as a PDF file.

Submitting as XML always works. However, submitting as PDF may or may not work. Here’s what happens:

  • If you open the form in Acrobat, it will submit correctly as PDF.
  • If you open the form in Reader, it will silently fail when you try to submit. (There will be no warning or error messages – it just doesn’t appear to work. This will not impress your customers 🙂 )

The reason for this is that only Acrobat can create a “new” PDF file; Reader is only for reading existing files. Since you’ve typed new information into the fields on your form, submitting as PDF would effectively create a “new” PDF file and is not allowed in Reader.

You have a number of options for resolving this problem:

  1. Ensure that everyone filling the form has Acrobat rather than Reader. (Difficult to do if this is a public form.)
  2. Buy an Adobe product called LiveCycle Reader Extensions for your form – this will allow you to “extend” the capabilities of Reader to allow it to send the completed form as PDF.
  3. If there are fewer than 500 recipients of your form, there is a limited version of Reader Extensions built into Acrobat. You simply need to convert the form after saving it. Open it in Acrobat, use Forms/Distribute… and select Save for later.
  4. Change from PDF submission to XML. You will either need to:
  • Teach the recipient of the XML how to import the XML data back into a blank copy of the form. Open the original blank form in Acrobat, select Forms/Manage Form Data…/Import Data…
  • Use Adobe LiveCycle on the server (LiveCycle Forms or LiveCycle Output is the product you’ll need) to merge the XML data back into the original blank PDF template.

    For more details on Reader Extensions, check this out:

    What is Reader Extensions?

    If you’d like any further information about Reader Extensions or anything else in this blog post, please contact info-at-avoka.com

    October 20, 2008

    Customize User Task Escalation After Assignment

    Filed under: Designing Processes — kendyyus @ 10:47 am

    Background

    LiveCycle Process Management has a number of built-in facilities for managing reminders, escalations, and deadlines for User Tasks. But sometimes the built-in features may be a little limited.

    For example, you may want one of the following features:

    • In the first reminder, send it directly to the assigned user. But for the second reminder, cc that user’s manager. For the third reminder, send it to the user, their manager, and the CEO.
    • Have different text in the first, second and third reminder emails, with each email getting increasingly abusive.
    • Send the first reminder after 5 days, the second reminder after 2 days, the third reminder after 1 day, and subsequent reminders every 10 minutes after that.
    • You may need to check the status of an external system or database prior to deadlining or escalating the task. For example, the project relating to the task may have been cancelled by the customer, and the task is no longer relevant – in this case, we’d like to simply terminate the entire process.

    These type of escalations cannot be accommodated by the built-in features, and require some sneaky techniques.

    Calling a Sub-process to Handle Custom Task Escalation

    One of the possible ways to solve the above scenario is to call a sub-process to handle the task after the task assignment. We need to actually kick off the sub-process before we actually allocate the task, because once we hit the User step, the process won’t continue till after the step has been completed.

    The idea is:

    • call a sub-process before just before the user step asynchronously (in other words, without waiting for it to complete)
    • pass the parent process id to the sub-process (so that the sub-process can reference the parent process’s tasks)
    • the first step of the sub-process set to wait for a minute or two, to ensure that the parent process has time to allocate the task to the user.
    • the sub-process will then have sufficient information to look-up for the active task that would have been assigned

    With the task information, the sub-process can be configured according to your business needs to do custom task reminder notifications, escalations, deadlines, and can even terminate the parent process if necessary.

    This provides an extremely simple way of achieving almost unlimited functionality in the way that reminders, escalations and deadlines are handled. It also allows you to handle escalations for multiple User steps in a single place – changing the sub-process will change the way it’s handled for all User steps.

    This approach involves some of the custom components Avoka has developed to perform those task operations outside of the User step.

    Please refer to the link below for the full article of this approach to the described scenario, containing the example process and sample LCA file for download:

    http://avoka.dnsalias.com/confluence/display/Public/Customize+User+Task+Escalation+After+Assignment .

    August 19, 2008

    Using the LiveCycle SQL (JDBC) component – Part I

    Filed under: Designing Processes, LiveCycle — htreisman @ 1:51 pm

    Overview

    The LiveCycle JDBC/SQL component is probably the most useful component in the Foundation category. You can use it to query a database, which can help pre-populate forms, make routing decisions, and more. It’s a very powerful component, but it can get a bit complicated, particularly when you want to pass process variables to your query. In this blog, we investigate the JDBC component in detail.

    Datasource name

    The datasource name is a way of getting the application server to do all the hard work of connecting to a database. Basically, you configure a pool of data connections to a particular database by configuring the application server. The application server will connect to the database on your behalf, using the connection information you provide, and make the connections available for your use. This is done differently in different application servers. Check out the LiveCycle installation guide or application server documentation for instructions on how to create connection pools.

    All you need to provide is the name of the datasource. In most cases, you will be using an “in memory” connection pool, which means that you will need a “java:/” prefix to your pool name.

    For example, to connect to the LiveCycle database itself (which we will use in these examples), use:

    java:/IDP_DS

    Simple query

    A simple query is shown below:

    Passing a process variable as a parameter – “Embedded Xpath”

    If you want to pass a process variable as a parameter to your query, you start by creating a variable, such as “begins_with”, of type String. You can use the “Xpath…” button to replace the “D” with the process variable, and insert it into the query. Your sql query will look like this:

    select oid,id from tb_sc_service_category
    where id like '{$ /process_data/@begins_with $}%'

    Note that:

    • the single quotes are still there, indicating to the SQL engine that we’re using a string
    • the percent symbol is still there, indicating a SQL wild-card
    • the variable name has been “wrapped” in {$ … $}. This indicates to the process engine when the process runs, it should replace the {$…$} with the actual value of that variable.

    So if you run this process, and set the variable begins_with = “D”, you should get exactly the same results.

    However, if you click the Test button, you won’t get any data. This is because when you click the Test button, the process engine is not running, so the {$…$} wrapping is not replaced by anything, and you’re trying to locate a data that doesn’t exist.

    This gets even worse if you use non-string variables, such as:

    select oid,id from tb_sc_service_category
    where oid ={$ /process_data/@some_id $}

    In this case, you will actually get a SQL error:

    Exception: You have an error in your SQL syntax;
    check the manual that corresponds to your MySQL server
    version for the right syntax to use near '' at line 2.

    This is because the snippet of text “{$ /process_data/@some_id $}” doesn’t look anything like the integer that the SQL engine is expecting. When the process actually runs, this text will be substituted with the actual value of the some_id variable, such as “1”, and this would work fine – it’s only during testing that you have a problem.

    Things would also not if you were trying to find a category called “Bob’s stuff”. After variable replacement, you would get a SQL statement that looks like this:

    select oid,id from tb_sc_service_category
    where id like 'Bob's stuff%'

    You now have three quote characters in your SQL, and the SQL processor will get confused.

    The way to fix all these problems is to use a Parameterized Query.

    Passing a process variable as a parameter – “Parameterized”

    With a parameterized query, rather than embedding the parameter directly into the query, we use a “?” to indicate the parameter. We can then provide both a test value and a runtime-variable to be used when the query is executed. This is shown below:

    Note that:

    • We check the box that says “Use Parameterized Query”
    • We added a single row to the table because we have a single ? in our query. You must have the same number of rows as ?’s.
    • We can specify a test value to be used for testing the query, and a variable name for when the query actually runs in the process.
    • The wild-card character % must be embedded in the test data and the variable value.
    • We no longer need the quote characters in our SQL query, because we’re explicitly setting the type of the parameter to a string. We also don’t include quotes in our test data or variable value. This eliminates the problems related to having quotes in your parameter value.

    Avoka’s Added Value

    Avoka provides an added value component that makes SQL queries easier and more powerful.

    This component is shown below:

    Some of the additional features in Avoka’s component include:

    • Browsing and insertion of tables and column names into your query (shown above)
    • Additional output data formats, including XML, comma separated values, a CSV file, process variables of type “List”, and insertion of data directly into XFAForm variables.

    You can see more examples of usage here:

    http://avoka.dnsalias.com/confluence/display/Public/Retrieving+data+from+a+database+and+populating+a+form+with+the+data

    http://avoka.dnsalias.com/confluence/display/Public/Retrieving+data+from+a+database+and+saving+as+concatenated+strings+or+lists+in+process+variables

    http://avoka.dnsalias.com/confluence/display/Public/Retrieving+data+from+a+database+and+saving+as+CSV+file

    You can download a trial version here:

    Download trial

    Summary

    Using parameterized queries simplifies and enhances your ability to define and test your SQL queries. We generally recommend that you use a parameterized query rather than embedding the variable directly into the string.

    July 30, 2008

    A fix for some cosmetic differences between Reader 8 and 9

    Filed under: Designing Forms, LiveCycle — htreisman @ 5:07 pm

    When Reader 9 starts up, by default it clicks the “Highlight Fields” toggle button. In Reader 8, this was unchecked by default.

    In general, this is a good thing. It makes it much more obvious to end-users which documents are fillable/editable PDFs, and which are plain PDFs that can only be printed.

    However, in some cases, where your user-base is already expecting fillable forms, this means that all your carefully color-coordinated forms now don’t look as good on startup.

    Another issue is when you have required fields, which show up with red borders – apart from looking a bit garish, our usability testing has indicated that it can make new users freak out, thinking they’ve already made a mistake before they’ve even done anything.

    This is compounded if you have fields with caption above the field, which in Reader 9 is rendering as two red borders, as shown here:

    There is a very simple way to preserve the Reader 8 behavior – simply add the following line to the root node of your form:

    On Initialize
    app.runtimeHighlight = false;

    This has been tested in Reader 8.1 and Reader 9.

    Note: In Reader 9 the “Highlight Fields” seems as it is clicked even though this line of code deactivate it. Therefore, If you want to click it to highlight the fields you have to click it twice for the first time (1.Deactivate 2. Activate).

    Thanks to Mohammad Al-omari for coming up with this code.

    Avoka has a LiveCycle Forms JavaScript library that allows you to handle validation errors in a more graceful way, as well as providing a whole lot of other useful utility functions that makes building forms easier, quicker, and more effective. If you’re interested in more information about this library, please email info(at)avoka.com.

    July 8, 2008

    Form Guide Rendering Explained – Part II

    Filed under: LiveCycle, LiveCycle Architecture — htreisman @ 6:12 pm

    A number of people (Gareth and Mark from Adobe – thanks guys) indicated that the first blog on this topic was correct, but incomplete.

    Here is the rest of the story…

    Q: What is an orchestration?

    A: An orchestration is really a LiveCycle process that runs as if it were really just Java code. You design an orchestration by dragging a series of steps into a “short-lived” process, and joining those steps together using lines. Each step is really a method call on an object, and the process engine simply follows the lines, and executes each method call in the correct order. It’s basically visual programming.

    You can invoke an orchestration from Java or C## or other code, via SOAP, from another orchestration, etc. When you call it, it’s almost identical to calling a real Java program, except that:

    • The logic of the code is visible graphically
    • It can be maintained and modified by non-programmers
    • It’s much easier and quicker to change
    • It runs a teeny bit slower than if you’d written the code in Java

    There is a sample orchestration for rendering a Form Guide as a step inside of LiveCycle Workspace – you can refer to that if you want to take a closer look at both an orchestration, and also an orchestration rendering a Form Guide.

    Q: What if I’m using the feature where you can switch between the Form Guide and a PDF?

    A: Well, things do get a little more complicated.

    Form Guide With PDF

    Form Guide With PDF

    In this case, a few extra things happen:

    1. After loading the SWF file, the SWF file checks to see whether the minimum version of Reader/Acrobat is available.
    2. If so, creates a new, hidden DHTML iframe.
    3. Into the iframe, it loads a URL that points back to the LC Forms servlet.
    4. When invoked, the servlet in turn invokes the LC Forms Render process. It supplies different parameters, this time requesting a PDF to be returned, rather than SWF.
    5. The PDF is returned to the hidden iframe.
    6. The Form Guide enables a button that allows the end user to toggle between the Form Guide and the PDF view.
    7. When the user clicks the PDF toggle button, the Form Guide extracts the current state of the XML contained in the Form Guide, and dynamically injects it into the PDF.
    8. The Form Guide then hides itself, and displays the iframe containing the PDF.
    9. When the user toggles back, the current value of the XML is obtained from the PDF, and injected back into the Form Guide, and the hide/show happens.
    10. Voila

    Notes:

    • The injection of XML data into the PDF is achieved using something called the Form Bridge, which is a combination of JavaScript in the form itself, and some Javascript in the iframe. This basically allows the Form Guide to communicate to the PDF. You can either manually insert the Form Bridge into your form (in Designer, look for it in the Custom palette), or you can dynamically inject the Form Bridge into your form in the orchestration, using a service called the Form Augmenter.
    • Like the generation of the Form Guide SWF itself, the PDF will also be cached by LC Forms – on subsequent invocations, the PDF will be obtained from the cache.

    Please click on the “Comments” link for some excellent additional material – a big thank you to John for contributing.

    June 30, 2008

    Form Guide Rendering Explained

    Filed under: Designing Forms, LiveCycle, LiveCycle Architecture — htreisman @ 4:05 pm

    You probably already know that Form Guides are an exciting way to render an Adobe dynamic form via a Wizard-style interface. See this link for more details: http://help.adobe.com/en_US/livecycle/es/fggettingstarted.pdf

    However, all this document says about how rendering a Form Guide works is:

    “The process for rendering form guides is similar to the process used to render forms in PDF or HTML. You must create a new process in Workbench ES that uses the form guide rendering operation renderFormGuide.”

    How does rendering a Form Guide really work?

    The short answer is that it is similar to rendering a PDF. The longer answer is that there are some subtle differences, and these differences can have an impact on how you architect your solution. In particular, a Form Guide actually consists of three separate parts:

    1. An html page containing the Form Guide SWF file.
    2. Some Javascript libraries (mostly dealing with Browser Flash detection).
    3. The SWF file that is the Form Guide itself.

    Each of these is loaded in a different interaction between the user’s browser, your custom servlet, a special LiveCycle servlet, and LiveCycle Forms itself.

    The easiest way to explain this is via a sequence diagram:

    Click For Full Size

    (Click for larger image)

    1. HTML page
      1. The user clicks on the link to your Form Guide, sending a http request to your custom servlet.
      2. The servlet will invoke an orchestration defined in LiveCycle Workbench.
      3. The orchestration will obtain pre-population data if required (usually from some sort of database, using the logged-in user’s details)
      4. The orchestration will then invoke the LiveCycle Forms “render” operation, passing through the name of the XDP template, and the pre-population data.
      5. The render operation will return an html page. This page will contain some JavaScript references, and an <object> tag containing the SWF.
      6. The object tag will identify a uniquely named SWF file on the LiveCycle server
      7. The object tag will also include a “Flash Variable” embedded within the page – this Flash variable contains the pre-population data in an encoded form.
      8. The html page will be returned to the browser.
      9. Note: You could use Java code to directly invoke the LiveCycle Forms API, rather than using an orchestration.
    2. JavaScript
      1. The browser will identify the JavaScript libraries on the page, and request them from the LiveCycle server. Note that the request goes directly to JavaScript resources located within a web application on the LiveCycle server – your orchestration is not involved.
    3. Form Guide (SWF file)
      1. The browser will identify the object tag on the page.
      2. It will make a request to the LiveCycle server to obtain the object referenced in this page. This request goes directly to the LiveCycle supplied servlet, it does not involve your orchestration or custom code.
      3. The servlet will look at the unique object id specified, and will use this to locate the correct XDP template to turn into a SWF. (This is the same template that you specified when you called the “render” method.)
      4. The servlet will convert the XDP into MXML/ActionScript, and invoke the Flex compiler to generate the SWF file.
      5. It will then save the SWF file into the LiveCycle Forms cache. As long as the underlying XDP file doesn’t changed, (and assuming you don’t manually clear the cache), the servlet will serve up the SWF file from the cache from now on. This is because compiling the SWF file can be quite time-consuming.
      6. Finally, the SWF will be returned to the browser.
    4. Final display.
      1. The browser now has everything it needs to render the page. It will run the Javascript, and execute the SWF file, passing into it all the encoded pre-population data.
      2. Voila

    Notes:

    • In a clustered environment, it doesn’t matter whether #2 and #3 go to the same member of the cluster, or a different member of the cluster – what’s returned to the browser is always identical.
    • LiveCycle only needs to generate the SWF the first time, because it’s always identical. The pre-population data is embedded in the html file, which is generated each time the client requests a Form Guide, and may be different for each invocation.
    • You should manually load the Form Guide the first time you publish the Form Guide into production – otherwise the first user to load it will experience a longer than usual delay.

    Things can get a little more complicated in a real production environment.

    Click to View Larger

    The second diagram indicates a more real-life environment, where:

    • An Apache server has been introduced which front-ends the Application Server. The end-user can only “see” the Apache server, and cannot directly access the custom servlet or the LiveCycle Forms application server. This is generally considered to be a more secure way to architect any public-facing web application.
    • A firewall has been introduced between the custom servlet, and the LiveCycle server. Another firewall is usually inserted between the Apache server and the custom servlet, although this is omitted from the diagram.
    • A variation on this architecture is that the custom servlet may run on the LiveCycle application server.
    • The LiveCycle server may run in either the DMZ or within the corporate zone, depending on it’s accessibility requirements to databases and other corporate resources.

    This requires some modifications to the architecture of our application.

    1. When rendering the form using LiveCycle Forms “render”, you must specify the URL of the Apache server, rather than the URL of the LiveCycle server. This ensures that the client’s browser will interact with the Apache server, rather than attempting to communicate directly with the LiveCycle server.
    2. You must set up Apache to “pass-through” requests for both the custom servlet and the LiveCycle servlet.
    3. You must somehow allows requests to the LiveCycle servlet to pass from Apache through to the LiveCycle servlet on the LiveCycle server. There are a number of ways of doing this:
      1. If the Apache server can “see” the LiveCycle server, you can set up a proxy rule to allow traffic for the servlet to be passed through.
      2. You may need to write a simple proxy service within your custom servlet. This is basically a servlet with the same name as the LiveCycle servlet, which passes any requests through to the LiveCycle servlet, and forwards any responses back to the browser.

    Thanks to Rak Siva of Avoka and Gareth Faulkner of Adobe for assistance with this blog.

    June 19, 2008

    Best practise for pre-populating a Drop Down with data?

    Filed under: Designing Forms, Designing Processes, LiveCycle — htreisman @ 1:53 pm

    One of our internal consultants recently asked: “What is best practice for populating a Drop Down list in a PDF form with data?”

    There are several ways to do it, and there is no “best” or “recommended” way. The suggestions below are roughly in order of complexity.

    1. You can just hard code the values in the form template.
    2. You can populate a hidden field with comma-separated data, and use JavaScript to split the items and add them to the drop down. (If you use a comma separator, make sure that your data doesn’t have any commas in it).
    3. You can bind a Drop Down directly to element in your form’s XML, using a feature called Dynamic Properties (in Designer). Then, instead of populating a hidden field, you just populate elements directly into your XML. No javascript required, but a bit more work in your XML Schema.
    4. You can have your form calling a web service in order to get the data it needs, and use Javascript to process the results, and populate the Drop Down. You can build the web service any way you like, including as a LiveCycle orchestration. This is often the only way to approach things if the contents of the drop down depends on other data in your form.

    For #2 and #3, you can modify the LiveCycle Default Render process to inject the data into your XML.

    The screenshot below shows how to turn on “Dynamic Properties” in Designer.

    Dynamic Properties in LiveCycle Designer

    If anyone reading this blog needs more information on exactly how to do this, email info-at-avoka.com

    June 16, 2008

    LiveCycle directories – Global Storage/Temp, clustering, and more…

    Filed under: LiveCycle, LiveCycle Administration, LiveCycle Architecture — htreisman @ 11:03 am

    The information in this Blog is correct to the best of my knowledge – if you discover any errors, please post on the comments area.

    Thanks to Pete Spencer of Adobe for his expertise.

    General

    • You need to specify various directories when you configure LiveCycle using the Configuration Manager. These include:
      • Global Document Storage (GDS) Directory
      • Temporary Directory
      • Font Directories
    • The values you enter into Configuration Manager are stored within the LiveCycle ear file. The values in this ear file are only used during initializing (bootstrapping) the LiveCycle database – after this, they are no longer used, and the values from the database are used instead.
    • All of the directories must be specified from the perspective of the application server, NOT the perspective of the machine running Configuration Manager. In other words, these directories must exist on the application server. It’s therefore simplest if you actually run Configuration Manager on the target machine.
    • You can modify the directory names in the database using Adminui at any time, including after installation. Home > Settings > Core System Settings > Configurations. You must restart the server before your changes take effect. You MUST move files from the old GDS to the new GDS while the server is stopped. You do not need to reconfigure or redeploy your ear files.
    • There is only one directory location stored in the database, no matter how many instances you have in your cluster. In a clustered environment, you must set up your servers so that all of them have the same GDS, temp and font directory names. (There’s a way around this for the temp directory – see below.)

    For example: if you’re running LiveCycle on different operating systems, you cannot set the System Font directory to c:\windows\fonts on one machine, and c:\winnt\fonts on a different machine. You will have to make the directory the same on all machines, even if this means copying files to matching directories.

    Another example: You cannot set the Global Storage Directory to “C:\Adobe\Global” on one machine, and “\\machine1\c$\Adobe\Global” on another. You can use “\\machine1\c$\Adobe\Global” on both machines (although this would create a single point of failure).

    • Make sure that the user under which you run the Application Server has read/write access to the temp/GDS directories, and read access to the Font directories.
    • You can use the same LiveCycle ear files for installs onto multiple boxes (eg Dev, Test, Production), even if the actual directories on a second box don’t match those that you specified for the first box. You can deploy the LiveCycle ear files, run LiveCycle, and bootstrap the database. Then you can modify the directories using Adminui, and restart LiveCycle. Once you’ve done this, you can complete the configuration by installing components and samples, etc. (Note: We haven’t thoroughly tested this, and don’t know for sure that those directories in the LiveCycle ear file aren’t used for some other purpose – we recommend that you create separate LiveCycle ear files for each machine configuration.)

    Font Directories

    • These can be shared, or each application server in a cluster can have its own copy on a local drive.
    • If you’re running Configuration Manager on one machine, and deploying to another, you must copy the LiveCycle fonts from the installation directory (usually C:\Adobe\LiveCycle8\fonts) to a location on the application server machine.
    • Under Windows, the system fonts are generally either in C:\windows\fonts or c:\winnt\fonts.

    Global Document Storage Directory (GDS)

    • The GDS should be considered an extension to the database, and is part of the persistent state of the LiveCycle system. Don’t “clean up” the files in this directory.
    • You should back up the files in this directory simultaneously with the database. See my previous post on this topic.
    • The GDS must be a single directory that is shared between all instances of LiveCycle in a cluster. Usually this means setting up the GDS on a shared drive, or a Storage Area Network (SAN).
    • It must also be referred to by exactly the same pathname for all instances of LiveCycle.
    • If you change the location of the GDS, you must ALSO move all the files to the new location while the server is stopped.

    Temporary directory

    • Each running instance of LiveCycle requires its own temporary directory. There are a number of ways of specifying the temporary directory:
    • If you specific a non-blank directory in Configuration Manager (which also means a non-blank directory in adminui), then LiveCycle will use this value.
    • If you specify a blank directory in Configuration Manager/Adminui, then LiveCycle will use the Java VM java.io.tmpdir system property.
    • The java.io.tmpdir property can be set in several ways:
      • You can specify it explicitly in the command line that you use to launch the Java VM that runs LiveCycle. For example, “java -Djava.io.tmpdir=C:\temp …”
      • If you do not specify it explicitly, Java will set this value based on operating system defaults (eg value of “TEMP” system variable)
    • If you are using vertical clustering, the members of the cluster will each need their own temp directory, but they are sharing the same physical drive. Therefore
      • Leave the temporary directory blank in Configuration Manager/Adminui.
      • Specify a different java.io.tmpdir Java system property for each instance of LiveCycle.

    June 6, 2008

    Hot Back-ups of LiveCycle

    Filed under: LiveCycle, LiveCycle Administration, LiveCycle Architecture — htreisman @ 4:17 pm

    Most of LiveCycle’s data is held in the LiveCycle database. Backing up the database is easy – just use the native backup facilities provided by your database vendor.

    Usually you can do a “hot” backup, while the application (i.e. LiveCycle) is still running. What the backup utility does is to set a “marker” in the database transaction log – the backup is the state of the entire database at the point in time the marker was set. The database will continue to run, and execute transactions, but the data from these new transactions won’t appear in the backup – so no matter how big the database is, you always get a consistent set of data.

    LiveCycle is a bit more complicated, because it has the Global Document Storage directory (GDS). The GDS is really an extension or overflow for the database. For any large documents, these are actually stored in the GDS, rather than in the database – this helps with performance, and also helps to ensure that your database doesn’t grow too rapidly.

    You always need to ensure that when you do a backup of your database, you do a backup of your GDS. Similarly, if you do a restore, you should also restore both the GDS and the database at the same time.

    The trick is: how do you ensure that the database and GDS are consistent with each other? Any missing files in the GDS will cause LiveCycle to start throwing exceptions.

    One technique is to shut down LiveCycle while you’re doing the backup. If you need to do hot backups, then there are different approaches depending on your version of LiveCycle.

    LiveCycle 8 Update 1

    In LiveCycle 8 update 1 (at the time of writing, in beta), Adobe have added “backup mode” to enable backups to be made more reliably. The steps are:

    • Turn on “backup mode” in the adminui – this will temporarily prevent LiveCycle from deleting any files from the GDS.
    • Backup the database.
    • Backup the GDS.
    • Turn backup mode off.

    LiveCycle 8

    There is no backup mode in LiveCycle 8. The following procedure is the one that we recommend for hot backups.

    • Backup the GDS
    • Backup the database
    • Backup the GDS again, to the same backup location. Ensure that you use a backup mode that adds any new or modified files, but does NOT remove any files that have been removed since the first backup.

    You should also try to ensure that the entire process above occurs as quickly as possible. This may mean that you initially copy the files to a temporary location, and then perform the real backup (to tape or whatever) from there.

    There is apparently a small window of possibility that errors occurs – if a file in the GDS is created and removed between the time that the first backup starts and the second backup completes. This is generally a small window. Thank you to Rob Ryan of Adobe for pointing this out.

    « Newer PostsOlder Posts »

    Blog at WordPress.com.