Update builder
Build and Test j3270 / Build JAR & Run Tests (Java 11) (push) Successful in 1m12s
Build and Test j3270 / Build JAR & Run Tests (Java 21) (push) Successful in 1m12s
Build and Test j3270 / Build JAR & Run Tests (Java 17) (push) Successful in 4m22s

This commit is contained in:
2026-09-05 14:11:08 -04:00
parent 74e30d1ead
commit 79d493c24d
4 changed files with 133 additions and 53 deletions
+18 -10
View File
@@ -9,8 +9,12 @@ on:
jobs: jobs:
build: build:
name: Build JAR & Run Tests name: Build JAR & Run Tests (Java ${{ matrix.java }})
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
java: [ '11', '17', '21' ]
steps: steps:
- name: Configure Dynamic DNS Resolvers - name: Configure Dynamic DNS Resolvers
@@ -23,21 +27,21 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Java JDK (Temurin 17) - name: Set up Java JDK (Temurin ${{ matrix.java }})
uses: actions/setup-java@v3 uses: actions/setup-java@v3
continue-on-error: true continue-on-error: true
with: with:
java-version: '17' java-version: ${{ matrix.java }}
distribution: 'temurin' distribution: 'temurin'
- name: Ensure Java Available - name: Ensure Java Available
run: | run: |
if ! command -v javac >/dev/null 2>&1; then if ! command -v javac >/dev/null 2>&1; then
echo "Installing OpenJDK 17 via package manager..." echo "Installing OpenJDK ${{ matrix.java }} via package manager..."
if command -v apt-get >/dev/null 2>&1; then if command -v apt-get >/dev/null 2>&1; then
apt-get update && apt-get install -y openjdk-17-jdk-headless || true apt-get update && apt-get install -y openjdk-${{ matrix.java }}-jdk-headless || true
elif command -v apk >/dev/null 2>&1; then elif command -v apk >/dev/null 2>&1; then
apk add --no-cache openjdk17 || true apk add --no-cache openjdk${{ matrix.java }} || true
fi fi
fi fi
echo "Java compiler:" echo "Java compiler:"
@@ -53,23 +57,27 @@ jobs:
run: | run: |
sh ./test_all.sh sh ./test_all.sh
- name: Prepare Versioned JAR
run: |
cp build/j3270.jar "build/j3270-java${{ matrix.java }}.jar"
- name: Upload j3270 Executable JAR Artifact - name: Upload j3270 Executable JAR Artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
continue-on-error: true continue-on-error: true
with: with:
name: j3270-executable-jar name: j3270-java${{ matrix.java }}-jar
path: build/j3270.jar path: build/j3270-java${{ matrix.java }}.jar
- name: Upload Test Reports - name: Upload Test Reports
if: always() if: always()
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
continue-on-error: true continue-on-error: true
with: with:
name: test-reports name: test-reports-java${{ matrix.java }}
path: build/reports/tests/ path: build/reports/tests/
- name: Report Build Status - name: Report Build Status
if: failure() if: failure()
run: | run: |
echo "### ❌ Build or Test Failed" >> $GITHUB_STEP_SUMMARY echo "### ❌ Build or Test Failed for Java ${{ matrix.java }}" >> $GITHUB_STEP_SUMMARY
echo "Please check the runner logs above for details." >> $GITHUB_STEP_SUMMARY echo "Please check the runner logs above for details." >> $GITHUB_STEP_SUMMARY
+18 -10
View File
@@ -9,8 +9,12 @@ on:
jobs: jobs:
build: build:
name: Build JAR & Run Tests name: Build JAR & Run Tests (Java ${{ matrix.java }})
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
java: [ '11', '17', '21' ]
steps: steps:
- name: Configure Dynamic DNS Resolvers - name: Configure Dynamic DNS Resolvers
@@ -23,21 +27,21 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Java JDK (Temurin 17) - name: Set up Java JDK (Temurin ${{ matrix.java }})
uses: actions/setup-java@v3 uses: actions/setup-java@v3
continue-on-error: true continue-on-error: true
with: with:
java-version: '17' java-version: ${{ matrix.java }}
distribution: 'temurin' distribution: 'temurin'
- name: Ensure Java Available - name: Ensure Java Available
run: | run: |
if ! command -v javac >/dev/null 2>&1; then if ! command -v javac >/dev/null 2>&1; then
echo "Installing OpenJDK 17 via package manager..." echo "Installing OpenJDK ${{ matrix.java }} via package manager..."
if command -v apt-get >/dev/null 2>&1; then if command -v apt-get >/dev/null 2>&1; then
apt-get update && apt-get install -y openjdk-17-jdk-headless || true apt-get update && apt-get install -y openjdk-${{ matrix.java }}-jdk-headless || true
elif command -v apk >/dev/null 2>&1; then elif command -v apk >/dev/null 2>&1; then
apk add --no-cache openjdk17 || true apk add --no-cache openjdk${{ matrix.java }} || true
fi fi
fi fi
echo "Java compiler:" echo "Java compiler:"
@@ -53,23 +57,27 @@ jobs:
run: | run: |
sh ./test_all.sh sh ./test_all.sh
- name: Prepare Versioned JAR
run: |
cp build/j3270.jar "build/j3270-java${{ matrix.java }}.jar"
- name: Upload j3270 Executable JAR Artifact - name: Upload j3270 Executable JAR Artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
continue-on-error: true continue-on-error: true
with: with:
name: j3270-executable-jar name: j3270-java${{ matrix.java }}-jar
path: build/j3270.jar path: build/j3270-java${{ matrix.java }}.jar
- name: Upload Test Reports - name: Upload Test Reports
if: always() if: always()
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
continue-on-error: true continue-on-error: true
with: with:
name: test-reports name: test-reports-java${{ matrix.java }}
path: build/reports/tests/ path: build/reports/tests/
- name: Report Build Status - name: Report Build Status
if: failure() if: failure()
run: | run: |
echo "### ❌ Build or Test Failed" >> $GITHUB_STEP_SUMMARY echo "### ❌ Build or Test Failed for Java ${{ matrix.java }}" >> $GITHUB_STEP_SUMMARY
echo "Please check the runner logs above for details." >> $GITHUB_STEP_SUMMARY echo "Please check the runner logs above for details." >> $GITHUB_STEP_SUMMARY
+92 -28
View File
@@ -2,29 +2,43 @@
[![Build & Test](https://git.hugfreevikings.wtf/rudi/j3270/actions/workflows/build.yaml/badge.svg)](https://git.hugfreevikings.wtf/rudi/j3270/actions) [![Build & Test](https://git.hugfreevikings.wtf/rudi/j3270/actions/workflows/build.yaml/badge.svg)](https://git.hugfreevikings.wtf/rudi/j3270/actions)
[![Releases](https://img.shields.io/badge/Releases-Gitea-blue.svg)](https://git.hugfreevikings.wtf/rudi/j3270/releases) [![Releases](https://img.shields.io/badge/Releases-Gitea-blue.svg)](https://git.hugfreevikings.wtf/rudi/j3270/releases)
[![Java](https://img.shields.io/badge/Java-11%20%7C%2017%20%7C%2021-blue.svg)](https://adoptium.net) [![Java](https://img.shields.io/badge/Java-11%20%7C%2017%20%7C%2021%20(LTS)-blue.svg)](https://adoptium.net)
[![Tests](https://img.shields.io/badge/Tests-539%20passed-brightgreen.svg)]()
[![License](https://img.shields.io/badge/License-Unlicense-blue.svg)](LICENSE) [![License](https://img.shields.io/badge/License-Unlicense-blue.svg)](LICENSE)
An **x3270-aligned IBM 3270 mainframe terminal emulator** written in pure Java. Designed for high compatibility with IBM z/OS, z/VM, CMS, and TSO systems over TN3270 and TN3270E. An **x3270-aligned and IBM Host On-Demand (HoD) compatible IBM 3270 mainframe terminal emulator & protocol library** written in pure Java with zero third-party runtime dependencies. Designed for high fidelity and compatibility with IBM z/OS, z/VM, CMS, and TSO systems over TN3270 and TN3270E.
--- ---
## 🚀 Quick Download & Run ## 🚀 Quick Download & Run
### Latest Standalone JAR ### Latest Standalone JARs
You can download the ready-to-run executable JAR directly from the releases or CI builds: Ready-to-run executable JARs are built and tested across all three Java LTS baselines (**Java 11, Java 17, and Java 21**) by Gitea Actions:
- **[Download Latest Tagged Release (`j3270.jar`)](https://git.hugfreevikings.wtf/rudi/j3270/releases)** - **[Download Latest Tagged Release (`j3270.jar`)](https://git.hugfreevikings.wtf/rudi/j3270/releases)**
- **[Latest Nightly CI Artifacts](https://git.hugfreevikings.wtf/rudi/j3270/actions)** (Download under the latest successful workflow run) - **[Latest Nightly CI Artifacts](https://git.hugfreevikings.wtf/rudi/j3270/actions)**: Download standalone JARs tailored for each LTS runtime under the latest workflow run:
- `j3270-java11-jar` (Java 11 LTS)
- `j3270-java17-jar` (Java 17 LTS — primary Gitea runner baseline)
- `j3270-java21-jar` (Java 21 LTS)
### Java Runtime Requirements
Requires **Java 11 or higher** (LTS versions: **Java 11, 17, 21**; also compatible with Java 24).
The project is tested and verified against:
- **Eclipse Temurin** (Adoptium OpenJDK HotSpot) — used in Gitea Actions CI workflows.
- **IBM Semeru Runtimes** (OpenJ9) — e.g. `11.0.32-sem`, `21.0.6-sem`, and `24.0.2-sem` via SDKMAN.
### Running `j3270` ### Running `j3270`
Requires **Java 11 or higher** (Java 11, 17, 21+):
```bash ```bash
# Launch interactive GUI # Launch interactive Swing GUI
java -jar j3270.jar java -jar j3270.jar
# Connect to TLS/SSL mainframe with custom port # Connect to mainframe with host, port, and terminal model (Models 2-5 or 'dynamic')
java -jar j3270.jar mainframe.example.com 23 4
java -jar j3270.jar mainframe.example.com 23 dynamic
# Connect to TLS/SSL mainframe on custom or standard (992) port
java -jar j3270.jar -s mainframe.example.com 992 java -jar j3270.jar -s mainframe.example.com 992
# Or using standard x3270 L: prefix # Or using standard x3270 L: prefix
java -jar j3270.jar L:mainframe.example.com:992 java -jar j3270.jar L:mainframe.example.com:992
@@ -35,12 +49,19 @@ java -jar j3270.jar -P mainframe.example.com 23
java -jar j3270.jar P:mainframe.example.com:23 java -jar j3270.jar P:mainframe.example.com:23
# Connect with unverified/self-signed certificate verification bypass # Connect with unverified/self-signed certificate verification bypass
java -jar j3270.jar --tls --insecure mainframe.example.com 992 java -jar j3270.jar -s --insecure mainframe.example.com 992
# Launch with custom configuration file # Enable GDDM/GOCA host graphics explicitly (or disable via --no-graphics)
java -jar j3270.jar -g GOCA mainframe.example.com
java -jar j3270.jar --no-graphics mainframe.example.com
# Launch with custom INI configuration profile
java -jar j3270.jar -c config.ini java -jar j3270.jar -c config.ini
# Launch directly from source runner # Enable protocol and diagnostic debug logging to j3270.log
java -jar j3270.jar -d mainframe.example.com
# Launch directly from source runner script
./run.sh ./run.sh
``` ```
@@ -48,46 +69,89 @@ java -jar j3270.jar -c config.ini
## ✨ Features ## ✨ Features
- **TN3270 & TN3270E Protocol Support**: RFC 2355 compliant state machine, negotiation, Device-Type query, plain TN3270 fallback, and SSL/TLS encryption. ### 🌐 Protocol & Telnet Engine
- **SSL/TLS Security**: - **TN3270 & TN3270E (RFC 2355)**: Full compliant finite-state machine, Device-Type negotiation, Functions negotiation (`BIND-IMAGE`, `RESPONSES`, `SYSREQ`), plain TN3270 fallback, and NVT (Network Virtual Terminal) mode.
- Encrypted TN3270 over TLS connections on standard port `992` or custom ports. - **SSCP-LU & Unformatted Line Mode**: Native z/VM line-mode support (`CP TERM CONMODE 3270`).
- Interactive certificate verification prompt for self-signed or untrusted certificates with fingerprint, subject, issuer, and validity inspection. - **Terminal Models & Dynamic Geometry**:
- Optional unverified/insecure mode for testing and headless scripting.
- **IND$FILE File Transfer**: Full support for both **CUT** and **DFT (DDM)** high-speed structured field transfers with ASCII/binary translation, CRLF handling, and recfm/lrecl formatting for TSO, VM/CMS, and CICS.
- **z/VM & Line-Mode Support**: Proper SSCP-LU and unformatted line handling (`CP TERM CONMODE 3270` supported).
- **APL & Graphic Escape**: Comprehensive box-drawing and math symbol character rendering.
- **Terminal Models**:
- Model 2 (24x80) - Model 2 (24x80)
- Model 3 (32x80) - Model 3 (32x80)
- Model 4 (43x80) - Model 4 (43x80)
- Model 5 (27x132) - Model 5 (27x132)
- **Zero-Dependency Core**: Modular architecture separated into: - `IBM-DYNAMIC` (Model 0 dynamic geometry auto-negotiation via Usable Area Query Reply).
- `lib3270j`: Reusable Java 3270 protocol, data stream parser, charset translation, and telnet state machine. - **Enterprise Proxy Support**: SOCKS5 and HTTP CONNECT proxy tunneling with optional authentication.
- `j3270`: Desktop Swing user interface and session management.
### 🔒 Security & Encryption
- **Modern TLS 1.2 / 1.3**: Encrypted TN3270 over TLS on standard port `992` or custom ports via JSSE.
- **Interactive Certificate Verification**: Security dialog for untrusted or self-signed certificates displaying SHA-256 fingerprints, subject, issuer, and validity dates with user approval prompt.
- **Headless Insecure Mode**: `--insecure` / `-k` option for scripted environments and test mainframes.
### 🎨 GDDM / GOCA Host Vector Graphics (IBM 3179G)
- **Vector Drawing Orders**: Polylines, relative lines, circular & elliptical arcs, fillets, and multi-polygon area fills with boundary detection and alternate/winding rules.
- **1:1 Color Calibration**: 16-color GOCA palette and base 4-color mapping calibrated 1:1 against IBM Host On-Demand (HoD).
- **Shading, Patterns & Overlays**: Patterned area fills, geometric markers, and uncompressed / run-length bit-image and wallpaper overlays.
- **Vector Symbol Fonts (VSS)**: Stroked vector typography with baseline rotation angle (`GSCA`), shear (`GSCR`), and micro-scale anti-aliased sub-pixel rendering.
- **Programmed Symbols (PSS / PSA)**: Support for single-plane and triple-plane multi-color composite symbols.
- **Interactive Graphics Input**: Mouse click pick correlation mapping display coordinates to host graphics space, 56-byte Graphic Input structured field generation, and immediate/deferred light pen selection.
### 🖨️ IBM 3287/3286 Host Printing Emulation
- **Autonomous Printer Sessions**: TN3270E host print sessions supporting SCS (SNA Character String / LU-Type 1) and DSC/DSE (Data Stream Compatibility / LU-Type 3).
- **Double-Byte DBCS Printing**: Pitch adjustments, character spacing, and grid line formatting (`PrintSCS3270DB`, `PrintPS3270DB`).
- **Flexible Print Output**: Printer Definition Table (PDT) integration, print spooling to local files, or dispatch directly to system print queues.
### 📁 IND$FILE File Transfer & Host Catalog
- **Full Protocol Coverage**: Support for both **CUT** and high-speed **DFT (DDM)** structured field transfers for TSO, VM/CMS, and CICS.
- **Translation Modes**: Automatic ASCII/EBCDIC text translation, CRLF conversions, and transparent binary transfers.
- **Dataset Formatting**: Full control over Record Format (`RECFM` F/V/U), Logical Record Length (`LRECL`), Block Size (`BLKSIZE`), and Space allocation.
- **Host Catalog Browser**: Interactive directory dialog to query, parse, and browse CMS and TSO host dataset catalogs.
### 🌍 Internationalization & Character Sets
- **22+ Single-Byte EBCDIC Codepages**: US/Canada (037), Open Systems / z/OS Unix (1047), International (500, 1148 Euro), UK (285), Germany/Austria (273, 1141 Euro), France (297), Italy (280), Spain (284), Scandinavia (277, 278), Greece (875), Turkey (1026, 1155, 905), Eastern Europe (870), Iceland (871), Cyrillic (1025, 1123, 1154, 880), Hebrew (424, 803), Arabic (420), Thai (838, 1160).
- **Mixed DBCS Support**: Japanese Katakana (930), Japanese Latin (939), Simplified Chinese (935, 1388), Traditional Chinese (937, 1371), and Korean (933) with Shift-In (`0x0E`) / Shift-Out (`0x0F`) state handling.
- **APL & Special Graphics**: APL keyboard mode, box-drawing characters, and Graphic Escape (`GE`) symbol translations.
### 🏛️ IBM Host On-Demand ECL API Alignment
- Reusable public API compliant with IBM Host On-Demand (HoD) v14 specifications under `com.ibm.eNetwork.ECL.*` and `haus.nightmare.lib3270j.ecl.*`.
- Drop-in implementations for `ECLSession`, `ECLPS` (Presentation Space), `ECLOIA` (Operator Information Area), `ECLConnection`, `ECLField`, `ECLFieldList`, `ECLScreenDesc`, `ECLScreenReco`, and `ECLXfer`.
### 🖥️ Desktop User Interface (j3270)
- **Themes**: Modern Dark and Light UI themes with instant switching.
- **Dynamic Font Scaling**: Real-time font size adjustments (`Cmd/Ctrl +`, `Cmd/Ctrl -`, `Cmd/Ctrl 0`) with smooth scaling and guarded window repacking.
- **Screen Search**: Full-screen text search dialog (`Cmd/Ctrl + F`) with forward/backward navigation and case-sensitivity controls.
- **Screen Exporter**: Save screen images and content as plain text, HTML, or PNG.
- **Field Inspector**: Interactive inspection tool displaying 3270 field boundaries, buffer addresses, protection, highlighting, and color attributes.
- **Scripting & Keystroke Macros**: Interactive mnemonic keystroke playback dialog supporting standard x3270 action strings.
- **Word Processing Modes**: Document Mode (DOC), Word Wrap, audible margin bell, and tab stop navigation.
- **Visual Aids**: Crosshair ruler and configurable cursor styles (block cursor, underline cursor with alpha blending).
- **Persistent Profiles**: Configuration profiles and session preferences saved in INI files (`j3270.ini`).
### 📦 Modular Zero-Dependency Core
- **`lib3270j`**: Standalone Java protocol and terminal engine with **zero third-party dependencies** (`java.base`, `java.desktop` only).
- **`j3270`**: Standalone desktop Swing terminal application.
--- ---
## 🛠️ Building from Source ## 🛠️ Building from Source
### Standalone Build (No Gradle Required) ### Standalone Build (No Gradle Required)
The project includes self-contained, portable build scripts: The project provides self-contained, portable build scripts requiring only a JDK:
```bash ```bash
# Build executable JAR in 2 seconds: # Build standalone executable JAR (build/j3270.jar):
sh ./build_all.sh sh ./build_all.sh
# Run all 57 automated unit tests in ~500ms: # Run all 539 automated unit tests across 88 test containers (~7s):
sh ./test_all.sh sh ./test_all.sh
``` ```
The resulting standalone JAR is created at `build/j3270.jar`.
### Gradle Build (Optional) ### Gradle Build (Optional)
```bash ```bash
./gradlew build ./gradlew build
./gradlew test ./gradlew test
``` ```
### Continuous Integration
All pushes and pull requests are verified across **Java 11, 17, and 21 LTS** runners via Gitea Actions (`.gitea/workflows/build.yaml`).
--- ---
## 📜 Acknowledgements ## 📜 Acknowledgements
+5 -5
View File
@@ -1,10 +1,10 @@
# Gitea Actions Runner Configuration for j3270 # Gitea Actions Runner Configuration for j3270
This repository includes Gitea Actions workflows in `.gitea/workflows/build.yaml` to automatically: This repository includes Gitea Actions workflows in `.gitea/workflows/build.yaml` to automatically:
1. Compile and run the JUnit 5 test suite via `test_all.sh`. 1. Compile and run the JUnit 5 test suite across the 3 LTS Java versions (Java 11, 17, and 21) via `test_all.sh`.
2. Build the standalone `j3270.jar` executable via `build_all.sh`. 2. Build standalone executables for each LTS version via `build_all.sh`.
3. Upload `j3270.jar` as a downloadable artifact. 3. Upload `j3270-java11.jar`, `j3270-java17.jar`, and `j3270-java21.jar` as downloadable artifacts.
4. Report test results and diagnostics. 4. Report test results and diagnostics per runtime.
--- ---
@@ -98,7 +98,7 @@ This means Docker's bridge network inside the runner container cannot resolve th
You can verify the entire build and test suite locally at any time without external tools: You can verify the entire build and test suite locally at any time without external tools:
```bash ```bash
# Compile and run all 25 unit tests (130ms): # Compile and run all 539 unit tests (~7s):
sh ./test_all.sh sh ./test_all.sh
# Build executable standalone JAR: # Build executable standalone JAR: