← Files Legacy JRXML ToolkitARCHIVED FILE
skills/jasper-jrxml/scripts/compile-jrxml.ps1
9.07 KB · Oct 5, 2026 · 18:30 UTC
<#
.SYNOPSIS
Compiles and validates a legacy JasperReports 2.x JRXML file into a .jasper file.
.DESCRIPTION
Uses JDK 8, the consuming project's dependency jars, and the legacy
JRJdk13Compiler. The Jasper compiler is the structural validator: invalid
fields, parameters, expressions, or DTD elements cause a non-zero exit.
.PARAMETER Jrxml
JRXML path, absolute or relative to ProjectRoot.
.PARAMETER ProjectRoot
Root of the consuming project. Defaults to the current directory.
.PARAMETER LibDirectory
Directory containing the project's JasperReports 2.x and transitive jars.
May be absolute or relative to ProjectRoot.
.PARAMETER DeployDirectory
Optional runtime report directory. The compiled .jasper is copied here
only after successful compilation.
.PARAMETER JdkHome
Optional JDK 8 home. When omitted, JAVA_HOME and common Windows JDK paths
are checked, but only a Java 8 installation is accepted.
.PARAMETER AdditionalClasspath
Optional jar files or directories containing additional required jars.
.EXAMPLE
pwsh -NoProfile -File scripts/compile-jrxml.ps1 `
-Jrxml reports/complex-form.jrxml `
-ProjectRoot . `
-LibDirectory target/app/WEB-INF/lib
.EXAMPLE
pwsh -NoProfile -File scripts/compile-jrxml.ps1 `
-Jrxml reports/complex-form.jrxml `
-ProjectRoot . `
-LibDirectory target/app/WEB-INF/lib `
-DeployDirectory src/main/webapp/WEB-INF/reports
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$Jrxml,
[string]$ProjectRoot = (Get-Location).Path,
[Parameter(Mandatory = $true)]
[string]$LibDirectory,
[string]$DeployDirectory,
[string]$JdkHome,
[string[]]$AdditionalClasspath = @()
)
$ErrorActionPreference = "Stop"
$workDirectory = $null
function Resolve-ProjectPath {
param(
[Parameter(Mandatory = $true)]
[string]$Path,
[Parameter(Mandatory = $true)]
[string]$Root
)
$candidate = if ([System.IO.Path]::IsPathRooted($Path)) {
$Path
} else {
Join-Path $Root $Path
}
return [System.IO.Path]::GetFullPath($candidate)
}
function Test-Java8Home {
param([string]$Candidate)
if ([string]::IsNullOrWhiteSpace($Candidate)) {
return $false
}
$javacCandidate = Join-Path $Candidate "bin/javac.exe"
$javaCandidate = Join-Path $Candidate "bin/java.exe"
if (-not (Test-Path $javacCandidate)) {
$javacCandidate = Join-Path $Candidate "bin/javac"
$javaCandidate = Join-Path $Candidate "bin/java"
}
if (-not (Test-Path $javacCandidate) -or -not (Test-Path $javaCandidate)) {
return $false
}
$versionOutput = (& $javaCandidate -version 2>&1 | Out-String)
return $versionOutput -match 'version "1\.8\.'
}
function Find-Jdk8Home {
param([string]$ExplicitHome)
$candidates = [System.Collections.Generic.List[string]]::new()
if (-not [string]::IsNullOrWhiteSpace($ExplicitHome)) {
$candidates.Add($ExplicitHome)
}
if (-not [string]::IsNullOrWhiteSpace($env:JAVA_HOME)) {
$candidates.Add($env:JAVA_HOME)
}
if ($IsWindows -or $env:OS -eq "Windows_NT") {
foreach ($baseDirectory in @("C:\Program Files\Java", "C:\Program Files\Eclipse Adoptium")) {
if (Test-Path $baseDirectory) {
Get-ChildItem $baseDirectory -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match 'jdk.*(1\.8|8)' } |
ForEach-Object { $candidates.Add($_.FullName) }
}
}
}
foreach ($candidate in $candidates | Select-Object -Unique) {
if (Test-Java8Home $candidate) {
return [System.IO.Path]::GetFullPath($candidate)
}
}
throw "JDK 8 not found. Install a JDK 8 or pass -JdkHome with its absolute path."
}
try {
$projectPath = [System.IO.Path]::GetFullPath($ProjectRoot)
if (-not (Test-Path $projectPath -PathType Container)) {
throw "Project root not found: $projectPath"
}
$jrxmlPath = Resolve-ProjectPath -Path $Jrxml -Root $projectPath
if (-not (Test-Path $jrxmlPath -PathType Leaf)) {
throw "JRXML not found: $jrxmlPath"
}
try {
[xml](Get-Content -Raw -LiteralPath $jrxmlPath) | Out-Null
Write-Host "[1/4] Well-formed XML: $jrxmlPath"
} catch {
throw "Malformed XML in '$jrxmlPath': $($_.Exception.Message)"
}
$jdkPath = Find-Jdk8Home -ExplicitHome $JdkHome
$javac = Join-Path $jdkPath "bin/javac.exe"
$java = Join-Path $jdkPath "bin/java.exe"
if (-not (Test-Path $javac)) {
$javac = Join-Path $jdkPath "bin/javac"
$java = Join-Path $jdkPath "bin/java"
}
$toolsJar = Join-Path $jdkPath "lib/tools.jar"
Write-Host "[2/4] JDK 8: $jdkPath"
$libPath = Resolve-ProjectPath -Path $LibDirectory -Root $projectPath
if (-not (Test-Path $libPath -PathType Container)) {
throw "Library directory not found: $libPath. Build the consuming project or pass -LibDirectory."
}
$classpathEntries = [System.Collections.Generic.List[string]]::new()
Get-ChildItem $libPath -Recurse -File -Filter "*.jar" |
ForEach-Object { $classpathEntries.Add($_.FullName) }
foreach ($entry in $AdditionalClasspath) {
$resolvedEntry = Resolve-ProjectPath -Path $entry -Root $projectPath
if (Test-Path $resolvedEntry -PathType Container) {
Get-ChildItem $resolvedEntry -Recurse -File -Filter "*.jar" |
ForEach-Object { $classpathEntries.Add($_.FullName) }
} elseif (Test-Path $resolvedEntry -PathType Leaf) {
$classpathEntries.Add($resolvedEntry)
} else {
throw "Additional classpath entry not found: $resolvedEntry"
}
}
if (-not ($classpathEntries | Where-Object { [System.IO.Path]::GetFileName($_) -match '^jasperreports-?2\.' })) {
throw "No JasperReports 2.x jar found in the configured classpath."
}
if (-not ($classpathEntries | Where-Object { [System.IO.Path]::GetFileName($_) -match '^commons-digester.*\.jar$' })) {
$mavenRepository = Join-Path ([Environment]::GetFolderPath("UserProfile")) ".m2/repository/commons-digester"
if (Test-Path $mavenRepository) {
$digesterJar = Get-ChildItem $mavenRepository -Recurse -File -Filter "commons-digester-*.jar" |
Select-Object -First 1 -ExpandProperty FullName
if ($digesterJar) {
$classpathEntries.Add($digesterJar)
}
}
}
if (Test-Path $toolsJar) {
$classpathEntries.Add($toolsJar)
}
$workRoot = Join-Path $projectPath "target"
New-Item -ItemType Directory -Force -Path $workRoot | Out-Null
$workDirectory = Join-Path $workRoot ("jaspercompile_" + [guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Force -Path $workDirectory | Out-Null
$classpathEntries.Add($workDirectory)
$classpath = ($classpathEntries | Select-Object -Unique) -join [System.IO.Path]::PathSeparator
$helperSource = @'
import net.sf.jasperreports.engine.JasperCompileManager;
public class CompileLegacyJasper {
public static void main(String[] args) throws Exception {
System.setProperty(
"net.sf.jasperreports.compiler.class",
"net.sf.jasperreports.engine.design.JRJdk13Compiler"
);
JasperCompileManager.compileReportToFile(args[0], args[1]);
System.out.println("COMPILED_OK");
}
}
'@
$helperPath = Join-Path $workDirectory "CompileLegacyJasper.java"
[System.IO.File]::WriteAllText($helperPath, $helperSource, [System.Text.UTF8Encoding]::new($false))
& $javac -cp $classpath -d $workDirectory $helperPath
if ($LASTEXITCODE -ne 0) {
throw "Failed to compile the Java helper. Check the legacy classpath."
}
$temporaryOutput = Join-Path $workDirectory "report.jasper"
$compilerOutput = & $java -cp $classpath CompileLegacyJasper $jrxmlPath $temporaryOutput 2>&1
$compilerOutput | ForEach-Object { Write-Host $_ }
if ($LASTEXITCODE -ne 0 -or -not ($compilerOutput | Select-String "COMPILED_OK")) {
throw "[3/4] JasperReports compilation failed. Review the compiler output above."
}
$outputPath = [System.IO.Path]::ChangeExtension($jrxmlPath, ".jasper")
Copy-Item -LiteralPath $temporaryOutput -Destination $outputPath -Force
Write-Host "[3/4] Compiled: $outputPath ($((Get-Item $outputPath).Length) bytes)"
if (-not [string]::IsNullOrWhiteSpace($DeployDirectory)) {
$deployPath = Resolve-ProjectPath -Path $DeployDirectory -Root $projectPath
New-Item -ItemType Directory -Force -Path $deployPath | Out-Null
$deployedPath = Join-Path $deployPath ([System.IO.Path]::GetFileName($outputPath))
Copy-Item -LiteralPath $outputPath -Destination $deployedPath -Force
Write-Host "[4/4] Deployed: $deployedPath"
} else {
Write-Host "[4/4] No deployment requested; .jasper remains beside the JRXML."
}
Write-Host "DONE"
} finally {
if ($workDirectory -and (Test-Path $workDirectory)) {
Remove-Item -LiteralPath $workDirectory -Recurse -Force -ErrorAction SilentlyContinue
}
}
SHA-256: edb163025f424e8da9ae136a8d4d0e618688b024b5b3eaf749a39dbd2585da87