TAFC to TAFJ

Why Your TAFJ Changes Aren't Doing Anything

In TAFC, you edit a routine, catalog it, and it runs. In TAFJ, editing the source file changes nothing. There is a compile step. And a packaging step. And a deployment step. And possibly a restart.

Most teams discover the compilation step by accident. A developer changes a routine, tests it, and nothing changes. They change it again. Still nothing. Somewhere between the second and fifth attempt, someone mentions that you have to compile it first.

This is the single biggest mindset shift in the TAFC to TAFJ upgrade. In TAFC, the T24 BASIC runtime interprets your code each time it runs — the source file is the program. In TAFJ, the BASIC code is compiled into Java bytecode and the JVM runs that bytecode. The source file is not the program. The compiled class file inside a JAR is the program.

A change to the source file with no subsequent compile is a change to something the running system is not reading.

The tools in the pipeline

Four tools handle compilation and packaging. You need to know what each one does and when to use it.

tCompile — compile a BASIC file to a class file

tCompile [-cf <confFile>] [-I <insertDir>] <program_path_and_name>

Examples:

tCompile F.WRITE                    Compiles F.WRITE in the current directory
tCompile /home/t24/T24.BP/F.WRITE   Compiles the specific file
tCompile /home/t24/T24.BP           Compiles everything in T24.BP
tCompile /home/t24/T24.BP/F.*       Compiles files starting with F.

Exclude files with -reject:

tCompile -reject */EB.* /home/t24/T24.BP
tCompile -reject "*/SUB/*|*/SUB2/*" /home/t24/T24.BP

Output: .class files in the Java destination directory defined by temn.tafj.directory.classes in your TAFJ configuration.

tIntegrate — bulk compile and package into JARs

tIntegrate [–cf properties] <version>

The version argument names the output JARs. tIntegrate R24 produces:

  • R24.jar — all compiled class files
  • I_R24.jar — all insert files

Use this for full environment builds. It reads all BASIC folders defined in temn.tafj.directory.basic.

tComponentSplitter — split class files into component JARs

tComponentSplitter [–cf properties]

Reads F.PGM.DATA.CONTROL to find which component each class belongs to, then creates a separate JAR per component. Classes with no component go into a default JAR (called GENERAL unless configured otherwise). After it runs, the .class files are deleted — only JARs remain.

tMerge — merge a patch JAR into an existing release JAR

tMerge <source> <destination>
tMerge C:\T24\patch\Patch.jar C:\T24\lib\T24.jar

Takes classes from the patch JAR and merges them into the destination JAR, creating a backup first. This is how you apply a targeted fix to a live release without recompiling the whole codebase.

Two more useful tools

tRun — executes a compiled program from the command line without going through Browser. Useful for testing.

tRun [-cf <config>.properties] <BASIC program> [parameters]

tDiag — shows your full TAFJ environment configuration: Java version, TAFJ version, directory paths, database connection, project setup. Run this first when something is broken and you need to confirm what the environment thinks it is looking at.

tDiag [-cf <config>.properties]

The full TAFC vs TAFJ development cycle

TAFC

  1. Edit the routine
  2. Catalog
  3. Test — change is live

TAFJ

  1. Edit the routine in Eclipse or Design Studio
  2. Run tCompile against the file → produces a .class file
  3. Package the .class into the appropriate JAR (tIntegrate for a full build, tMerge for a targeted patch)
  4. Place the JAR in the correct location
  5. Restart the application server, or hot-deploy if your setup supports it
  6. Test

On a well-configured environment with scripting in place, steps 2–5 can run in under a minute. On a fresh or undocumented environment, they can take an hour the first time — usually the wrong hour.

The critical step is 5: knowing whether a restart is needed and how to do it safely. On a live bank environment, restarting the application server has implications. This is not something to figure out during an incident.

BASIC code that worked in TAFC but causes problems in TAFJ

Not all valid TAFC BASIC compiles cleanly in TAFJ. The JBC compiler enforces stricter rules.

TAFC codeProblem in TAFJReplacement
!HUSHIT! prefix not supportedHUSHIT
ABORTAbrupt transaction terminationProper error handling
CALLCNot supportedIntegration Events or direct Java call
CHAINControl never returns to invokerRefactor the flow
CHARDeprecatedCHARX
GOTONot recommendedGOSUB
CRTIncompatible with Browser and GUIUse the logger
DBRPerformance impactFull record read
DCOUNT in FOR loopPerformance at scaleAssign to variable outside the loop
Code after THEN/ELSE on same lineStyle violationMove to separate lines

The most dangerous are the silent failures — code that compiles but misbehaves at runtime. ABORT is the classic: it compiles, it runs, but interacts badly with TAFJ's transaction management in ways that may not surface immediately.

Compilation error vs runtime error

Compilation error — tCompile could not produce a .class file. You see the error immediately. Nothing changed in the running environment.

Runtime error — the code compiled fine but fails or misbehaves when executed. Harder to spot. The application server is running the compiled class and something in it behaves unexpectedly.

This is why maintaining a JAR backup before any deployment is not optional. tMerge creates a backup automatically. Manual JAR replacements need to manage their own.

What most teams miss before go-live

Not scripting the compile-deploy cycle. Doing it manually under pressure during an incident is slow and error-prone. Before go-live, someone should have a script that compiles, packages, and deploys — and the team should have run it at least a dozen times in non-production.

Not documenting which JAR each routine lives in. After tComponentSplitter runs, routines are in different JARs. If you need to patch one in production, you need to know which JAR to target. If nobody knows, tDiag and a search of the component splitter output is the fastest answer.

Not rehearsing the application server restart. It needs to be a documented, practised step — not something the team figures out at 2am.

Quick reference

ToolWhat it doesWhen to use
tCompile <file>Compile single BASIC file to .classIndividual changes
tCompile <directory>Compile all files in a directoryBatch compilation
tIntegrate <version>Compile all BASIC folders, create version JARsFull environment builds
tComponentSplitterSplit .class files into component JARsAfter bulk compilation
tMerge <patch> <target>Merge patch classes into an existing JARTargeted production fixes
tRun <program>Execute compiled program from command lineTesting outside Browser
tDiagShow full TAFJ environment configurationDiagnosing environment problems