How to Automate Oracle Forms Builds from the Command Line

Compile a whole Oracle Forms 14.1.2 application in the right order from a script, and keep forms as XML to see every change.

An application of a hundred forms is not maintained one click at a time. Compiling everything after a change to a library, or comparing this week's version of a form with last week's, are jobs for scripts. Oracle Forms has the tools: command-line versions of its compiler and converters.

This guide covers the Oracle Forms 14.1.2 command-line tools, a tested script that compiles a whole application in the right order, and converting forms to XML so version control can show what changed.

Sample Form for This Guide

The examples and screenshots use the sample form CH08_INVOICES from the Oracle Forms code repository on GitHub. Download it, open it in Forms Builder, and connect as CAREWELL to follow along.

FormFileWhat it shows
CH08_INVOICESforms/ch08/ch08_invoices.fmbThe invoices form used in the XML examples

The forms run against the CareWell Clinic sample schema, which you install first.

The Command-Line Tools

Each tool is a script in the bin directory of the Forms instance (.sh on Linux, .cmd on Windows), which sets the environment and runs a program of the Oracle home.

ToolDoes
frmcmp_batchCompiles modules, converts libraries to and from text, upgrades old modules.
frmf2xml, frmxml2fConvert forms, menus, and object libraries to XML and back.
frmxmlvValidates XML against the Forms XML schema.
frmxmlsgWrites that schema.
frmf2xlf, frmxlf2fExtract a module's texts to XLIFF files for translation, and merge the translations back.
frmplsqlconvThe Forms Migration Assistant, described in how to upgrade Oracle Forms applications to 14.1.2.

frmcmp_batch Options for Scripts

Syntax:

frmcmp_batch module=<file> userid=<user/password@db> [module_type=FORM|MENU|LIBRARY]
             [compile_all=YES] [batch=YES] [output_file=<file>] [script=YES] [parse=YES]
             [debug=YES] [statistics=YES] [print_version=YES] [upgrade=YES] [logon=NO]
  • compile_all compiles all the PL/SQL of the module, not only what changed: always use it in scripts.
  • batch writes messages to the error file only; errors of a module go to <module>.err in the current directory.
  • script=YES writes a library as text (.pld), and parse=YES reads a .pld into a .pll, so libraries can be kept as text.
  • print_version tells which release last saved the module, such as Module ch08_invoices.fmb last saved by version 14.1.2.0.0.
  • upgrade converts modules of Forms 4.5, and debug compiles with debugging information.

The compiler's other parameters are covered in how to compile Oracle Forms modules using the Form Compiler.

Compile a Whole Application in the Right Order

Forms needs libraries compiled before the forms and menus that attach them, and a library that attaches another compiled after that one; then menus, then forms. Object libraries are not compiled, because their objects are copied into forms when the forms are compiled.

compile-all.sh compiles libraries in passes until a pass compiles nothing new, so it needs no list of which library attaches which. It is in the tools folder of the Oracle Forms code repository on GitHub.

The script compile-all.sh:

#!/bin/bash
# Compiles every module of an application in the order Forms needs:
# libraries (.pll -> .plx), then menus (.mmb -> .mmx), then forms (.fmb -> .fmx).
# A library that attaches another compiles only after it: libraries are compiled in passes,
# until a pass compiles nothing new.
#   compile-all.sh <directory> <userid>
# The directory must be in FORMS_PATH, so that attached libraries are found.
dir=${1:?directory}; userid=${2:?userid}
cd "$dir" || exit 1
declare -a failed
compile() {                          # compile <file> <type>: 0 if the compiled file was written
  local out
  case $2 in LIBRARY) out=${1%.*}.plx;; MENU) out=${1%.*}.mmx;; FORM) out=${1%.*}.fmx;; esac
  rm -f "$out" "${1%.*}.err"
  frmcmp_batch module="$1" userid="$userid" module_type=$2 compile_all=yes batch=yes > /dev/null 2>&1
  [ -f "$out" ]
}

# libraries, in passes
todo=( $(ls *.pll 2>/dev/null) )
while [ ${#todo[@]} -gt 0 ]; do
  left=()
  for f in "${todo[@]}"; do compile "$f" LIBRARY || left+=("$f"); done
  [ ${#left[@]} -eq ${#todo[@]} ] && break            # no progress: the rest fail
  todo=("${left[@]}")
done
failed+=("${left[@]}")

for f in $(ls *.mmb 2>/dev/null); do compile "$f" MENU || failed+=("$f"); done
for f in $(ls *.fmb 2>/dev/null); do compile "$f" FORM || failed+=("$f"); done

total=$(ls *.pll *.mmb *.fmb 2>/dev/null | wc -l)
echo "compiled $((total - ${#failed[@]})) of $total modules"
for f in "${failed[@]}"; do
  echo "FAILED $f: $(grep -m1 -E 'FRM-[0-9]+|PL/SQL ERROR|PDE-' "${f%.*}.err" 2>/dev/null)"
done
[ ${#failed[@]} -eq 0 ]

The directory must be in FORMS_PATH, so the compiler finds attached libraries while it compiles. Run on a copy of all 58 sample modules, it printed this.

Output:

compiled 54 of 58 modules
FAILED ch11_tchart.fmb: FRM-30454: Unsupported item type.
FAILED ch27_fee_proc_wizard.fmb: FRM-30173: Module contains no canvases.
FAILED ch37_legacy_before.fmb: PL/SQL ERROR 201 at line 9, column 3
FAILED customers.fmb: PL/SQL ERROR 201 at line 3, column 10

real    0m31.293s

The four failures were expected leftovers: a form with the chart item that 14.1.2 no longer supports, a half-made copy of the stored-procedure block form, the legacy form before its upgrade, and a test form. The script lists each failure with its first error, so a build pipeline can stop on them. On Windows, the same loops are written in PowerShell or a .cmd file with for %%f in (*.pll).

Keep Forms as XML

A .fmb file is binary: version control stores it, but cannot show what changed. frmf2xml writes a module as XML, and frmxml2f reads it back.

Convert a form to XML and back:

frmf2xml.sh OVERWRITE=YES ch08_invoices.fmb           writes ch08_invoices_fmb.xml
frmxml2f.sh OVERWRITE=YES ch08_invoices_fmb.xml       writes ch08_invoices.fmb
  • By default, only properties that differ from their defaults are written (DUMP=OVERRIDDEN). DUMP=ALL writes every property, but cannot be read back.
  • COMPAT_VERSION=12.2.1.4.0 leaves out properties newer than that release, for the XML tools of 12c.

Each object is an element, and each property an attribute. Here is a text item of the invoices form.

A text item in the XML:

<Item Name="INVOICE_DATE" Prompt="Date" PromptAttachmentEdge="Start" Width="70" ItemType="Text Item"
      DataType="Date" XPosition="190" YPosition="12" DatabaseItem="true" CanvasName="MAIN_CNV"
      ColumnName="INVOICE_DATE" Height="16"/>

See Changes as Lines

Kept in version control beside the .fmb, or instead of it, the XML shows each change as a line. After a program gave the form's date items a format mask, the difference between the two versions was two attributes.

Output of diff:

7c7
<  <Item Name="INVOICE_DATE" ... DataType="Date" XPosition="190" YPosition="12" DatabaseItem="true" CanvasName="MAIN_CNV" ...
---
>  <Item Name="INVOICE_DATE" ... DataType="Date" XPosition="190" YPosition="12" DatabaseItem="true" FormatMask="DD-MON-YYYY" CanvasName="MAIN_CNV" ...
28c28
<  <Item Name="PAID_ON" ... DataType="Date" ... DatabaseItem="true" CanvasName="MAIN_CNV" ...
---
>  <Item Name="PAID_ON" ... DataType="Date" ... DatabaseItem="true" FormatMask="DD-MON-YYYY" CanvasName="MAIN_CNV" ...

The XML went back to a .fmb with frmxml2f, which compiled, and frmxmlv confirmed it valid against the Forms XML schema. Libraries have their own text form, the .pld written with script=YES. The program that made the change is shown in how to use the Oracle Forms Java API.

Conclusion

frmcmp_batch compiles modules, converts libraries to and from text with script and parse, and reports which release saved a module; always use compile_all=YES in scripts. Compile an application libraries first, in passes when libraries attach libraries, then menus and forms, as compile-all.sh does while listing every failure. frmf2xml and frmxml2f turn modules into XML and back, so you can compare versions, keep forms in version control, and validate them with frmxmlv.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE and software veteran with 25+ years of experience, passionate about AI and IT innovation.

guest

0 Comments
Oldest
Newest Most Voted
00