TAFC to TAFJ

Why Old Descriptor Logic Often Breaks in TAFJ

The DICT item still exists. The routine compiles. The field name still appears in tools. Everything looks fine. And yet the behaviour is different. This is the descriptor trap, and it catches teams who assume that if the metadata survived the migration, the runtime must have too.

There is a particular kind of TAFJ migration defect that is infuriating because everything looks fine. The DICT item is still there. The routine compiles without errors. The field name appears in enquiries and versions. You run a test and something is subtly wrong — a value that should be there is not, a selection that should work returns nothing, a derived field shows up blank.

The first instinct is to blame the routine. You check the logic. It looks correct. You check the DICT item. It looks correct. You check the compilation output. No errors. You check the JAR. The class file is in there. Everything is fine. And yet the behaviour is wrong.

This is the moment when experienced migration people start asking about descriptors.

What a descriptor actually is

In T24, a DICT item defines a field. It tells the system what the field is called, what type it is, where its data comes from, and how it should behave in selection, sorting, and display.

Most DICT items are straightforward. They point to a physical position in a record, or they define a simple conversion. But some DICT items are descriptors — they define a field whose value is derived at runtime rather than stored in the record.

In TAFC, descriptors worked through a mechanism that was deeply embedded in the runtime. The DICT item defined the derivation logic, and the runtime executed it transparently whenever the field was accessed. You did not need to call anything explicitly. The system just handled it.

In TAFJ, that transparent runtime behaviour is not always available in the same way. The DICT item may still define the derivation, but the runtime may not execute it automatically. The field exists. The definition is correct. But the behaviour is different.

The trap

The trap is that the evidence is misleading. A DICT item that still exists and still looks valid gives you a false sense of safety. You check the metadata, it passes inspection, and you move on. The defect is not in the metadata. It is in the assumption that the metadata still controls the runtime behaviour the way it used to.

This is different from a compilation error or a missing file. Those are loud failures. A descriptor that silently stops working is a quiet failure. The routine runs. The output file is generated. The header and footer are correct. But the detail lines are empty because the selection logic depended on a descriptor that TAFJ does not evaluate the same way.

If you have ever spent three hours debugging a routine that compiles fine, runs fine, and produces the wrong answer, you have probably met this problem.

What kind of DICT items cause trouble

Not all DICT items are risky. The ones that cause problems in TAFJ tend to share certain characteristics:

  • Descriptor-driven fields. Fields whose value is derived from other fields via descriptor logic in the DICT item. In TAFC, the runtime resolved these automatically. In TAFJ, the resolution may not happen unless the code explicitly requests it.
  • I-type fields used as stored attributes. An I-type field defines a calculation or lookup, but in practice the code treats it as if the value were physically stored in the record. In TAFJ, the I-type behaviour may not trigger in all contexts.
  • Selection logic that depends on derived metadata. A SELECT or SSELECT that uses a descriptor field as a selection criterion. In TAFC, the runtime resolved the descriptor during selection. In TAFJ, the selection engine may not evaluate the descriptor the same way.
  • Dictionary entries that point into indirect or enquiry-like processing. DICT items that reference other routines or enquiries for their value. The indirection may work in TAFC but fail silently in TAFJ.

The common thread is that the behaviour depends on the runtime resolving something automatically. In TAFC, the runtime was generous about this. In TAFJ, it is more literal. If the code does not explicitly fetch or compute the value, the value may not appear.

Why this catches teams out

The reason this defect is so common in migrations is that older T24 code often hides business logic inside dictionary definitions. Over years of production use, the team stops thinking of the DICT item as metadata and starts treating it as part of the application logic. The descriptor becomes invisible — it is just how the field works.

During migration, the same DICT item is migrated as-is. It looks correct. It passes validation. Nobody questions it because nobody remembers that the behaviour depends on a runtime feature that TAFJ handles differently.

The result is a defect that surfaces in testing or, worse, in production, and that is extremely hard to trace because the metadata looks fine and the routine compiles fine. The only way to find it is to know what to look for.

What to do instead

The safer pattern is to move the business logic out of the DICT item and into something explicit:

  • Enquiry-level conversion logic when the behaviour is presentation-oriented — the field needs to display a derived value in an enquiry or version.
  • Routine-level processing when the logic drives selection or batch outcomes — the routine should compute the value explicitly rather than relying on the DICT item to do it at runtime.
  • Direct file reads when the real value lives on another file or lookup record — read it explicitly in the routine rather than depending on a DICT-level reference.

This change usually improves more than just TAFJ compatibility. It also makes the code easier to support because the dependency is no longer hidden behind metadata. A new team member reading the routine can see where the value comes from without having to cross-reference the DICT item.

A good migration checklist item

If you are reviewing older routines for TAFJ readiness, flag these early:

  • descriptor-driven DICT items
  • I-type fields used as if they were stored attributes
  • selection logic that depends on derived metadata behaviour
  • dictionary entries that point into indirect or enquiry-like processing

A routine that still compiles is not automatically safe. In this area, migration testing needs to validate behaviour, not just build success.

The bottom line

Seeing a DICT item is not the same as having a supported runtime pattern. The metadata can survive the migration perfectly while the behaviour behind it changes silently. The only defence is to know which DICT patterns are risky and to test the behaviour, not just the compilation.

Or, to put it another way: if your routine compiles fine, runs fine, and produces the wrong answer, do not look at the routine. Look at the DICT item. The problem may not be in the code at all.