59925c2787
Build and Test j3270 / Build JAR & Run Tests (Java 17) (push) Successful in 34s
Build and Test j3270 / Build JAR & Run Tests (Java 11) (push) Successful in 42s
Build and Test j3270 / Build JAR & Run Tests (Java 21) (push) Successful in 1m13s
Release j3270 / Build & Publish Release (push) Successful in 1m8s
469 lines
17 KiB
PowerShell
469 lines
17 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
j3270 Terminal Emulator - Setup and Build Script (PowerShell)
|
|
Detects Java 11+ JDK and builds j3270 standalone executable JAR.
|
|
|
|
.DESCRIPTION
|
|
Searches for a compatible Java Development Kit (JDK 11+ / LTS 11, 17, 21),
|
|
verifies compiler (javac) and archiver (jar) toolchains, compiles the lib3270j
|
|
protocol core and j3270 Swing desktop application, and packages the standalone
|
|
executable JAR file (build/j3270.jar).
|
|
|
|
.PARAMETER Run
|
|
Launch j3270 immediately after successful build.
|
|
|
|
.PARAMETER Test
|
|
Run unit test suite after successful build.
|
|
|
|
.PARAMETER Clean
|
|
Remove previous build artifacts before compiling.
|
|
|
|
.PARAMETER Help
|
|
Display usage help message.
|
|
|
|
.EXAMPLE
|
|
.\setup.ps1
|
|
Builds the standalone j3270.jar.
|
|
|
|
.EXAMPLE
|
|
.\setup.ps1 -Clean -Run
|
|
Cleans previous build, builds j3270, and immediately launches the application.
|
|
|
|
.EXAMPLE
|
|
.\setup.ps1 -Run -- mainframe.example.com 23 4
|
|
Builds and connects to specified host, port, and terminal model.
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param (
|
|
[switch]$Run,
|
|
[switch]$Test,
|
|
[switch]$Clean,
|
|
[switch]$Help,
|
|
[Parameter(ValueFromRemainingArguments = $true)]
|
|
[string[]]$RunArgs
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Resolve script root directory
|
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
if (-not $ScriptDir) {
|
|
$ScriptDir = Get-Location
|
|
}
|
|
Set-Location $ScriptDir
|
|
|
|
# Helper functions for colored terminal output
|
|
function Write-LogInfo($msg) { Write-Host "[INFO] $msg" -ForegroundColor Cyan }
|
|
function Write-LogSuccess($msg) { Write-Host "[OK] $msg" -ForegroundColor Green }
|
|
function Write-LogWarn($msg) { Write-Host "[WARN] $msg" -ForegroundColor Yellow }
|
|
function Write-LogError($msg) { Write-Host "[ERROR] $msg" -ForegroundColor Red }
|
|
|
|
if ($Help) {
|
|
Write-Host @"
|
|
j3270 Terminal Emulator - Setup & Build Script (PowerShell)
|
|
|
|
Usage:
|
|
.\setup.ps1 [-Run] [-Test] [-Clean] [-Help] [-- <run-arguments>]
|
|
|
|
Options:
|
|
-Run Build and immediately launch j3270
|
|
-Test Run automated unit tests after build
|
|
-Clean Remove previous build artifacts before compiling
|
|
-Help Show this help message
|
|
|
|
Examples:
|
|
.\setup.ps1
|
|
.\setup.ps1 -Clean
|
|
.\setup.ps1 -Run
|
|
.\setup.ps1 -Run -- mainframe.example.com 23 4
|
|
.\setup.ps1 -Test
|
|
"@
|
|
exit 0
|
|
}
|
|
|
|
Write-Host "`n=== j3270 Setup & Build (PowerShell) ===`n" -ForegroundColor White
|
|
|
|
# Determine platform
|
|
$isWindows = if (Test-Path variable:IsWindows) { $IsWindows } else { $env:OS -eq "Windows_NT" }
|
|
$exeSuffix = if ($isWindows) { ".exe" } else { "" }
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 1. Helper: Parse Major Java Version
|
|
# ------------------------------------------------------------------------------
|
|
function Get-JavaMajorVersion([string]$verStr) {
|
|
if (-not $verStr) { return 0 }
|
|
if ($verStr -match 'javac\s+([0-9][0-9._]*)' -or
|
|
$verStr -match 'version\s+"?([0-9][0-9._]*)"?' -or
|
|
$verStr -match '([0-9]+(\.[0-9]+)*)') {
|
|
$token = $matches[1]
|
|
if ($token -match '^1\.(\d+)') {
|
|
return [int]$matches[1]
|
|
}
|
|
if ($token -match '^(\d+)') {
|
|
return [int]$matches[1]
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 2. Helper: Test JDK Candidate Directory
|
|
# ------------------------------------------------------------------------------
|
|
function Test-JdkCandidate([string]$candHome) {
|
|
if (-not $candHome -or -not (Test-Path $candHome)) {
|
|
return $null
|
|
}
|
|
|
|
$javacPath = Join-Path $candHome "bin\javac$exeSuffix"
|
|
$jarPath = Join-Path $candHome "bin\jar$exeSuffix"
|
|
$javaPath = Join-Path $candHome "bin\java$exeSuffix"
|
|
|
|
if (-not (Test-Path $javacPath) -or -not (Test-Path $jarPath) -or -not (Test-Path $javaPath)) {
|
|
return $null
|
|
}
|
|
|
|
try {
|
|
$pInfo = New-Object System.Diagnostics.ProcessStartInfo
|
|
$pInfo.FileName = $javacPath
|
|
$pInfo.Arguments = "-version"
|
|
$pInfo.RedirectStandardOutput = $true
|
|
$pInfo.RedirectStandardError = $true
|
|
$pInfo.UseShellExecute = $false
|
|
$pInfo.CreateNoWindow = $true
|
|
|
|
$proc = [System.Diagnostics.Process]::Start($pInfo)
|
|
$stdout = $proc.StandardOutput.ReadToEnd()
|
|
$stderr = $proc.StandardError.ReadToEnd()
|
|
$proc.WaitForExit()
|
|
|
|
if ($proc.ExitCode -eq 0) {
|
|
$verOutput = ("$stdout $stderr").Trim()
|
|
$majorVer = Get-JavaMajorVersion $verOutput
|
|
|
|
if ($majorVer -ge 11) {
|
|
return [PSCustomObject]@{
|
|
Home = $candHome
|
|
Javac = $javacPath
|
|
Jar = $jarPath
|
|
Java = $javaPath
|
|
Version = $verOutput
|
|
Major = $majorVer
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
# Process execution failed or access denied
|
|
}
|
|
|
|
return $null
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 3. Discover JDK 11+
|
|
# ------------------------------------------------------------------------------
|
|
Write-LogInfo "Searching for a compatible Java Development Kit (JDK 11+)..."
|
|
|
|
$detectedJdk = $null
|
|
|
|
# Strategy A: Check JAVA_HOME environment variable
|
|
if ($env:JAVA_HOME) {
|
|
$detectedJdk = Test-JdkCandidate $env:JAVA_HOME
|
|
if ($detectedJdk) {
|
|
Write-LogInfo "Found valid JDK in `$env:JAVA_HOME: $($detectedJdk.Home)"
|
|
} else {
|
|
Write-LogWarn "`$env:JAVA_HOME is set ($($env:JAVA_HOME)) but is not a valid JDK 11+."
|
|
}
|
|
}
|
|
|
|
# Strategy B: Check current system PATH
|
|
if (-not $detectedJdk) {
|
|
$pathJavac = Get-Command "javac$exeSuffix" -ErrorAction SilentlyContinue
|
|
if ($pathJavac) {
|
|
try {
|
|
$realPath = $pathJavac.Source
|
|
$candBin = Split-Path -Parent $realPath
|
|
$candHome = Split-Path -Parent $candBin
|
|
$detectedJdk = Test-JdkCandidate $candHome
|
|
if ($detectedJdk) {
|
|
Write-LogInfo "Found valid JDK on PATH: $($detectedJdk.Home)"
|
|
}
|
|
} catch {}
|
|
}
|
|
}
|
|
|
|
# Strategy C: Check Windows Registry (if running on Windows)
|
|
if (-not $detectedJdk -and $isWindows) {
|
|
$regPaths = @(
|
|
"HKLM:\SOFTWARE\JavaSoft\JDK",
|
|
"HKLM:\SOFTWARE\JavaSoft\Java Development Kit",
|
|
"HKLM:\SOFTWARE\Eclipse Adoptium\JDK",
|
|
"HKLM:\SOFTWARE\AdoptOpenJDK\JDK",
|
|
"HKLM:\SOFTWARE\Microsoft\JDK",
|
|
"HKLM:\SOFTWARE\BellSoft\Liberica JDK",
|
|
"HKLM:\SOFTWARE\Zulu\zulu-jdk",
|
|
"HKLM:\SOFTWARE\WOW6432Node\JavaSoft\JDK",
|
|
"HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Development Kit",
|
|
"HKLM:\SOFTWARE\WOW6432Node\Eclipse Adoptium\JDK",
|
|
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\JDK"
|
|
)
|
|
|
|
foreach ($regBase in $regPaths) {
|
|
if (Test-Path $regBase) {
|
|
$subKeys = Get-ChildItem -Path $regBase -ErrorAction SilentlyContinue
|
|
foreach ($key in $subKeys) {
|
|
$item = Get-ItemProperty -Path $key.PSPath -ErrorAction SilentlyContinue
|
|
if ($item.JavaHome) {
|
|
$detectedJdk = Test-JdkCandidate $item.JavaHome
|
|
if ($detectedJdk) { break }
|
|
}
|
|
if ($item.Path) {
|
|
$detectedJdk = Test-JdkCandidate $item.Path
|
|
if ($detectedJdk) { break }
|
|
}
|
|
# Check hotspot subkey used by Adoptium/Microsoft MSI installers
|
|
$hotspotKey = Join-Path $key.PSPath "hotspot\MSI"
|
|
if (Test-Path $hotspotKey) {
|
|
$hs = Get-ItemProperty -Path $hotspotKey -ErrorAction SilentlyContinue
|
|
if ($hs.Path) {
|
|
$detectedJdk = Test-JdkCandidate $hs.Path
|
|
if ($detectedJdk) { break }
|
|
}
|
|
}
|
|
}
|
|
if ($detectedJdk) {
|
|
Write-LogInfo "Found valid JDK via Windows Registry: $($detectedJdk.Home)"
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Strategy D: Check Standard Filesystem Locations
|
|
if (-not $detectedJdk) {
|
|
$fsCandidates = @()
|
|
|
|
if ($isWindows) {
|
|
$searchRoots = @(
|
|
"$env:ProgramFiles\Eclipse Adoptium\*",
|
|
"$env:ProgramFiles\Java\*",
|
|
"$env:ProgramFiles\Microsoft\*",
|
|
"$env:ProgramFiles\Amazon Corretto\*",
|
|
"$env:ProgramFiles\Zulu\*",
|
|
"$env:ProgramFiles\BellSoft\*",
|
|
"$env:ProgramFiles\Semeru\*",
|
|
"$env:ProgramFiles\RedHat\*",
|
|
"${env:ProgramFiles(x86)}\Java\*",
|
|
"$env:LOCALAPPDATA\Programs\Eclipse Adoptium\*",
|
|
"$env:LOCALAPPDATA\Programs\Common\Oracle\Java\*",
|
|
"$env:USERPROFILE\.jdks\*",
|
|
"$env:USERPROFILE\.sdkman\candidates\java\*",
|
|
"$env:USERPROFILE\scoop\apps\openjdk\current",
|
|
"$env:USERPROFILE\scoop\apps\oraclejdk\current",
|
|
"$env:USERPROFILE\scoop\apps\temurin\current",
|
|
"$env:USERPROFILE\scoop\apps\zulu\current",
|
|
"C:\tools\jdk*",
|
|
"C:\Java\*"
|
|
)
|
|
foreach ($pattern in $searchRoots) {
|
|
Resolve-Path -Path $pattern -ErrorAction SilentlyContinue | ForEach-Object {
|
|
$fsCandidates += $_.Path
|
|
}
|
|
}
|
|
} else {
|
|
# POSIX / macOS search roots for pwsh
|
|
$searchRoots = @(
|
|
"/opt/homebrew/opt/openjdk/libexec/openjdk.jdk/Contents/Home",
|
|
"/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home",
|
|
"/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home",
|
|
"/opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk/Contents/Home",
|
|
"/opt/homebrew/opt/openjdk*",
|
|
"/usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home",
|
|
"/Library/Java/JavaVirtualMachines/*/Contents/Home",
|
|
"/usr/lib/jvm/default-java",
|
|
"/usr/lib/jvm/java-21-openjdk*",
|
|
"/usr/lib/jvm/java-17-openjdk*",
|
|
"/usr/lib/jvm/java-11-openjdk*",
|
|
"/usr/lib/jvm/*",
|
|
"$env:HOME/.sdkman/candidates/java/current",
|
|
"$env:HOME/.sdkman/candidates/java/*",
|
|
"$env:HOME/.asdf/installs/java/*"
|
|
)
|
|
foreach ($pattern in $searchRoots) {
|
|
Resolve-Path -Path $pattern -ErrorAction SilentlyContinue | ForEach-Object {
|
|
$fsCandidates += $_.Path
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($cand in $fsCandidates) {
|
|
$detectedJdk = Test-JdkCandidate $cand
|
|
if ($detectedJdk) {
|
|
Write-LogInfo "Found valid JDK at: $($detectedJdk.Home)"
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
# If no compatible JDK is found, report error with helpful instructions
|
|
if (-not $detectedJdk) {
|
|
Write-LogError "No compatible Java Development Kit (JDK 11+) was found on your system."
|
|
Write-Host @"
|
|
|
|
j3270 requires a Java Development Kit (JDK) version 11 or higher (LTS 11, 17, or 21).
|
|
Note: A JRE (runtime only) is not sufficient; the compiler (javac) and archiver (jar) are required.
|
|
|
|
To install JDK 17 on Windows:
|
|
• Using Windows Package Manager (winget):
|
|
winget install EclipseAdoptium.Temurin.17.JDK
|
|
|
|
• Using Chocolatey:
|
|
choco install openjdk17
|
|
|
|
• Using Scoop:
|
|
scoop install openjdk17
|
|
|
|
• Or download Eclipse Temurin (Adoptium MSI installer):
|
|
https://adoptium.net
|
|
|
|
After installing, restart PowerShell and re-run .\setup.ps1
|
|
"@ -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
|
|
$env:JAVA_HOME = $detectedJdk.Home
|
|
Write-LogSuccess "JDK verified: $($detectedJdk.Version)"
|
|
Write-LogInfo "Java compiler: $($detectedJdk.Javac)"
|
|
Write-LogInfo "JAR packager: $($detectedJdk.Jar)"
|
|
Write-LogInfo "Java runtime: $($detectedJdk.Java)"
|
|
Write-LogInfo "JAVA_HOME: $($detectedJdk.Home)"
|
|
Write-Host ""
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 4. Preparation & Clean
|
|
# ------------------------------------------------------------------------------
|
|
$BuildDir = Join-Path $ScriptDir "build"
|
|
$LibBuildDir = Join-Path $BuildDir "lib3270j"
|
|
$AppBuildDir = Join-Path $BuildDir "j3270"
|
|
|
|
if ($Clean) {
|
|
Write-LogInfo "Cleaning build directory ($BuildDir)..."
|
|
Remove-Item -Path $LibBuildDir, $AppBuildDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
Remove-Item -Path (Join-Path $BuildDir "MANIFEST.MF") -Force -ErrorAction SilentlyContinue
|
|
Remove-Item -Path (Join-Path $BuildDir "j3270.jar") -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
$null = New-Item -ItemType Directory -Path $LibBuildDir -Force
|
|
$null = New-Item -ItemType Directory -Path $AppBuildDir -Force
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 5. Compile Core Protocol Engine (lib3270j)
|
|
# ------------------------------------------------------------------------------
|
|
Write-LogInfo "Compiling lib3270j core engine..."
|
|
$libSrcDir = Join-Path $ScriptDir "lib3270j\src\main\java"
|
|
$libSources = Get-ChildItem -Path $libSrcDir -Filter *.java -Recurse | Select-Object -ExpandProperty FullName
|
|
|
|
if (-not $libSources -or $libSources.Count -eq 0) {
|
|
Write-LogError "No source files found in $libSrcDir"
|
|
exit 1
|
|
}
|
|
|
|
$libSourcesFile = Join-Path $BuildDir "lib_sources.txt"
|
|
$libSources | ForEach-Object { "`"$_`"" } | Set-Content -Path $libSourcesFile -Encoding UTF8
|
|
|
|
& $detectedJdk.Javac -d $LibBuildDir "@$libSourcesFile"
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-LogError "Compilation of lib3270j failed with exit code $LASTEXITCODE."
|
|
exit $LASTEXITCODE
|
|
}
|
|
Remove-Item -Path $libSourcesFile -Force -ErrorAction SilentlyContinue
|
|
Write-LogSuccess "lib3270j compiled successfully."
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 6. Compile Desktop Application (j3270)
|
|
# ------------------------------------------------------------------------------
|
|
Write-LogInfo "Compiling j3270 terminal emulator..."
|
|
$appSrcDir = Join-Path $ScriptDir "j3270\src\main\java"
|
|
$appSources = Get-ChildItem -Path $appSrcDir -Filter *.java -Recurse | Select-Object -ExpandProperty FullName
|
|
|
|
if (-not $appSources -or $appSources.Count -eq 0) {
|
|
Write-LogError "No source files found in $appSrcDir"
|
|
exit 1
|
|
}
|
|
|
|
$appSourcesFile = Join-Path $BuildDir "app_sources.txt"
|
|
$appSources | ForEach-Object { "`"$_`"" } | Set-Content -Path $appSourcesFile -Encoding UTF8
|
|
|
|
& $detectedJdk.Javac -cp $LibBuildDir -d $AppBuildDir "@$appSourcesFile"
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-LogError "Compilation of j3270 failed with exit code $LASTEXITCODE."
|
|
exit $LASTEXITCODE
|
|
}
|
|
Remove-Item -Path $appSourcesFile -Force -ErrorAction SilentlyContinue
|
|
Write-LogSuccess "j3270 application compiled successfully."
|
|
|
|
# Copy any resources if present
|
|
$appResDir = Join-Path $ScriptDir "j3270\src\main\resources"
|
|
if (Test-Path $appResDir) {
|
|
Copy-Item -Path (Join-Path $appResDir "*") -Destination $AppBuildDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
$libResDir = Join-Path $ScriptDir "lib3270j\src\main\resources"
|
|
if (Test-Path $libResDir) {
|
|
Copy-Item -Path (Join-Path $libResDir "*") -Destination $LibBuildDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 7. Package Standalone Executable JAR
|
|
# ------------------------------------------------------------------------------
|
|
Write-LogInfo "Packaging standalone executable JAR..."
|
|
$manifestFile = Join-Path $BuildDir "MANIFEST.MF"
|
|
$manifestText = "Manifest-Version: 1.0`r`nMain-Class: haus.nightmare.j3270.J3270App`r`nImplementation-Title: j3270`r`nImplementation-Version: 0.1.0`r`nCreated-By: j3270 setup.ps1`r`n`r`n"
|
|
[System.IO.File]::WriteAllText($manifestFile, $manifestText)
|
|
|
|
$jarFile = Join-Path $BuildDir "j3270.jar"
|
|
& $detectedJdk.Jar cvfm $jarFile $manifestFile -C $LibBuildDir . -C $AppBuildDir . | Out-Null
|
|
|
|
if (-not (Test-Path $jarFile)) {
|
|
Write-LogError "Failed to create executable JAR at $jarFile"
|
|
exit 1
|
|
}
|
|
|
|
$jarItem = Get-Item $jarFile
|
|
$jarSizeKB = [math]::Round($jarItem.Length / 1KB, 1)
|
|
|
|
Write-Host "`n=== Build Successful ===`n" -ForegroundColor Green
|
|
Write-LogSuccess "Executable JAR created: $jarFile (${jarSizeKB} KB)"
|
|
|
|
Write-Host @"
|
|
|
|
To run j3270:
|
|
java -jar "$jarFile"
|
|
# Or with arguments:
|
|
java -jar "$jarFile" mainframe.example.com 23 4
|
|
"@ -ForegroundColor White
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 8. Run Tests (if requested)
|
|
# ------------------------------------------------------------------------------
|
|
if ($Test) {
|
|
Write-Host "`n=== Running Unit Tests ===`n" -ForegroundColor White
|
|
$testScript = Join-Path $ScriptDir "test_all.sh"
|
|
if (Test-Path $testScript) {
|
|
& sh $testScript
|
|
} else {
|
|
Write-LogWarn "No test runner script found at $testScript"
|
|
}
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 9. Launch Application (if requested)
|
|
# ------------------------------------------------------------------------------
|
|
if ($Run) {
|
|
Write-LogInfo "Launching j3270..."
|
|
if ($isWindows) {
|
|
Start-Process -FilePath $detectedJdk.Java -ArgumentList (@("-jar", "`"$jarFile`"") + $RunArgs)
|
|
} else {
|
|
& $detectedJdk.Java -jar $jarFile @RunArgs
|
|
}
|
|
}
|