diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 9db9091..be1385c 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -9,8 +9,12 @@ on: jobs: build: - name: Build JAR & Run Tests + name: Build JAR & Run Tests (Java ${{ matrix.java }}) runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + java: [ '11', '17', '21' ] steps: - name: Configure Dynamic DNS Resolvers @@ -23,21 +27,21 @@ jobs: with: fetch-depth: 0 - - name: Set up Java JDK (Temurin 17) + - name: Set up Java JDK (Temurin ${{ matrix.java }}) uses: actions/setup-java@v3 continue-on-error: true with: - java-version: '17' + java-version: ${{ matrix.java }} distribution: 'temurin' - name: Ensure Java Available run: | 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 - 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 - apk add --no-cache openjdk17 || true + apk add --no-cache openjdk${{ matrix.java }} || true fi fi echo "Java compiler:" @@ -53,23 +57,27 @@ jobs: run: | 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 uses: actions/upload-artifact@v3 continue-on-error: true with: - name: j3270-executable-jar - path: build/j3270.jar + name: j3270-java${{ matrix.java }}-jar + path: build/j3270-java${{ matrix.java }}.jar - name: Upload Test Reports if: always() uses: actions/upload-artifact@v3 continue-on-error: true with: - name: test-reports + name: test-reports-java${{ matrix.java }} path: build/reports/tests/ - name: Report Build Status if: failure() 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 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9db9091..be1385c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -9,8 +9,12 @@ on: jobs: build: - name: Build JAR & Run Tests + name: Build JAR & Run Tests (Java ${{ matrix.java }}) runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + java: [ '11', '17', '21' ] steps: - name: Configure Dynamic DNS Resolvers @@ -23,21 +27,21 @@ jobs: with: fetch-depth: 0 - - name: Set up Java JDK (Temurin 17) + - name: Set up Java JDK (Temurin ${{ matrix.java }}) uses: actions/setup-java@v3 continue-on-error: true with: - java-version: '17' + java-version: ${{ matrix.java }} distribution: 'temurin' - name: Ensure Java Available run: | 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 - 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 - apk add --no-cache openjdk17 || true + apk add --no-cache openjdk${{ matrix.java }} || true fi fi echo "Java compiler:" @@ -53,23 +57,27 @@ jobs: run: | 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 uses: actions/upload-artifact@v3 continue-on-error: true with: - name: j3270-executable-jar - path: build/j3270.jar + name: j3270-java${{ matrix.java }}-jar + path: build/j3270-java${{ matrix.java }}.jar - name: Upload Test Reports if: always() uses: actions/upload-artifact@v3 continue-on-error: true with: - name: test-reports + name: test-reports-java${{ matrix.java }} path: build/reports/tests/ - name: Report Build Status if: failure() 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 diff --git a/README.md b/README.md index e1eb142..bc58931 100644 --- a/README.md +++ b/README.md @@ -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) [![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) -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 -### Latest Standalone JAR -You can download the ready-to-run executable JAR directly from the releases or CI builds: +### Latest Standalone JARs +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)** -- **[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` -Requires **Java 11 or higher** (Java 11, 17, 21+): ```bash -# Launch interactive GUI +# Launch interactive Swing GUI 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 # Or using standard x3270 L: prefix 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 # 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 -# 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 ``` @@ -48,46 +69,89 @@ java -jar j3270.jar -c config.ini ## ✨ Features -- **TN3270 & TN3270E Protocol Support**: RFC 2355 compliant state machine, negotiation, Device-Type query, plain TN3270 fallback, and SSL/TLS encryption. -- **SSL/TLS Security**: - - Encrypted TN3270 over TLS connections on standard port `992` or custom ports. - - Interactive certificate verification prompt for self-signed or untrusted certificates with fingerprint, subject, issuer, and validity inspection. - - 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**: +### 🌐 Protocol & Telnet Engine +- **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. +- **SSCP-LU & Unformatted Line Mode**: Native z/VM line-mode support (`CP TERM CONMODE 3270`). +- **Terminal Models & Dynamic Geometry**: - Model 2 (24x80) - Model 3 (32x80) - Model 4 (43x80) - Model 5 (27x132) -- **Zero-Dependency Core**: Modular architecture separated into: - - `lib3270j`: Reusable Java 3270 protocol, data stream parser, charset translation, and telnet state machine. - - `j3270`: Desktop Swing user interface and session management. + - `IBM-DYNAMIC` (Model 0 dynamic geometry auto-negotiation via Usable Area Query Reply). +- **Enterprise Proxy Support**: SOCKS5 and HTTP CONNECT proxy tunneling with optional authentication. + +### 🔒 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 ### 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 -# Build executable JAR in 2 seconds: +# Build standalone executable JAR (build/j3270.jar): 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 ``` -The resulting standalone JAR is created at `build/j3270.jar`. - ### Gradle Build (Optional) ```bash ./gradlew build ./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 diff --git a/docs/gitea-runner.md b/docs/gitea-runner.md index 2bb4d94..fbf20c2 100644 --- a/docs/gitea-runner.md +++ b/docs/gitea-runner.md @@ -1,10 +1,10 @@ # Gitea Actions Runner Configuration for j3270 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`. -2. Build the standalone `j3270.jar` executable via `build_all.sh`. -3. Upload `j3270.jar` as a downloadable artifact. -4. Report test results and diagnostics. +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 standalone executables for each LTS version via `build_all.sh`. +3. Upload `j3270-java11.jar`, `j3270-java17.jar`, and `j3270-java21.jar` as downloadable artifacts. +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: ```bash -# Compile and run all 25 unit tests (130ms): +# Compile and run all 539 unit tests (~7s): sh ./test_all.sh # Build executable standalone JAR: