FormsRefresh: proof that a migrated Oracle Forms application behaves like the original
FormsRefresh is for consultancies that migrate Oracle Forms applications. It runs the original application, records exactly what it does, and checks the replacement against that record, screen by screen and row by row. Every number below links to its evidence on formsrefresh.carretera.se.
The problem
A Forms migration is accepted when the customer believes the new application does what the old one did. Conversion is becoming cheap; showing equivalence is not. It is usually shown with hand-written tests and user acceptance testing, and those tests are written from what people think the old system does.
The behaviour that breaks is the kind nobody writes down. When a sequence value is drawn. Which column a form inserts as NULL. When a trigger computes a total. Which alert follows a commit, and where the cursor goes after Tab. Database checks and API tests see the stored rows, and only for the inputs someone thought of. They do not see what the user saw, in which order, or what the form refused to save. On the sample rebuild shown here, an independent database and API evaluation passed most of its checks, and the first recorded scenario still found nine defects that the evaluation had not reported (evidence).
Setup
The runner connects to the original Forms application in the customer's own licensed environment: their Forms Services, their database, one test schema and a client host. FormsRefresh installs no Oracle software.
A small Java agent in the Forms client reads the client's component tree, in which Forms names every item
BLOCK.ITEM. The runner finds each element by that name and sends real keystrokes and clicks to it, so input
passes through format masks, KEY- triggers, enabled and disabled items, lists of values and alerts as a user's
would. It never uses screen coordinates or image matching.
Scenarios
An LLM agent reads the Forms source (the XML export of each module and the PL/SQL) and writes scenarios: business-level steps that address items by name. It keeps writing them until every trigger, program unit and branch is exercised.
Each scenario starts from a restored database baseline. The runner records a golden record for it: after every step, every item on the canvas, the focus, the message line, open alerts and lists of values, and at the end the full database change set (rows inserted, updated and deleted, and every sequence value drawn). Values that depend on the clock or the run date are masked, so a golden record is the same in every run, on any day.
Coverage is measured, not guessed. Forms Runtime Diagnostics shows which triggers and program units fired, and
DBMS_PLSQL_CODE_COVERAGE shows the database PL/SQL blocks that ran. Every trigger, unit and branch ends up
covered, unreachable (a candidate for retirement before anyone converts it) or blocked with a stated reason.
Conversion
Conversion is done by ordinary coding agents or by the consultancy's own team, on whatever target stack the customer chooses. FormsRefresh is not a converter and produces no target code.
Validation
The same scenarios replay against the new application through an adapter for its stack: the web adapter used here drives the browser and reads the PostgreSQL database. Every recorded value is classified:
- match: the same value;
- tolerated: different only within a written policy rule (money to two decimals, a generated key matched by the order it was drawn in, a date default);
- waived: a source behaviour the customer has decided not to replicate;
- defect: a difference to repair;
- unmapped: an item the mapping does not name yet.
A repair agent fixes the defects from the diff and the golden records alone, without the Forms source, and the scenarios run again. Source behaviour that the customer chooses not to keep, such as a debugging message left in a trigger, becomes an explicit waiver with its reason. Each waiver is pinned to the values it covers and is listed in every diff with the number of values it applied to, so nothing is waived silently.
Value
Measured on two public Forms applications, a retail order system (6 modules) and an HR application (3 modules):
| Measure | Retail | HR |
|---|---|---|
| Coverage of Forms triggers and program units | 60 of 60 | 24 of 24 |
| Decision branches classified | 18: 14 covered, 2 unreachable, 2 blocked | 32: 24 covered, 4 unreachable, 4 blocked |
| Scenarios, each repeating byte for byte in three runs | 17 | 17 |
| Defects found in the first conversion | 403 values; 1 of 17 scenarios at parity | 73 values in 13 of 17 scenarios |
| Repair rounds to parity on all 17 scenarios | 1 (19 min of agent repair, 4 files changed) | 1 (about 4 min, 58 lines changed) |
| Waivers proposed for the customer's decision | 10 | 2 |
Onboarding a new application: the HR application took 2 h 39 min of one agent from receiving the source to a passing coverage report, with a full recording loop of 169 seconds per scenario on average. Converting it to .NET took one coding agent about 20 minutes.
Both migrated applications run on this site with the original Forms source linked next to them: retail and HR.
Going forward
What a consultancy gets. For every migrated screen: the scenarios, the golden records, a coverage line and a classified diff the customer can check. A defect list a developer or a repair agent can act on without reading Forms code. Unreachable code listed before anyone pays to convert it. Source quirks turned into explicit waiver decisions for the customer instead of silent fixes.
The limits today.
- Only the Forms Standalone Launcher on Forms 14.1.2 has been tested. Forms 12.2.1.x and the Java plugin and Web Start clients still in the field are untested.
- One target adapter exists: a web application in a browser, on PostgreSQL.
- Both applications are small public samples. Behaviour at the size of a customer application (hundreds of forms, PL/SQL libraries, Reports, integrations) is unproven. Files, reports, mail and HTTP calls are not yet recorded.
- Licensing is on the customer's side: the runner needs their licensed Forms Services and database, and they confirm the Java licence for the client host. The results above come from an Oracle trial installation used for evaluation only.
A clean diff means no difference in the behaviour the scenarios exercise under the agreed policy. It does not mean the applications are equivalent in every respect.
Choosing the next target platforms. Each target stack needs its own adapter and mapping; scenarios and golden records are written once and replay against any of them. Partners choose the next targets from the stacks their customers are moving to (APEX, Java, .NET, others). The natural first engagement is a joint pilot on one module of a real customer application, on that customer's client version, which builds the adapter for the partner's stack and retires the two largest open questions: client versions and scale.
The live demos share one database per app: visitors see each other's changes, and the data resets to the scenario fixture every night.