From 87105447624e226db84504d950ea5479d765588f Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Fri, 26 Jun 2026 20:37:29 +0300 Subject: [PATCH 1/9] Add CI job to install-test the Windows MSI The opendj-msi package was built and uploaded but never installed or exercised in CI. Add a test-msi job (needs: build-maven) that, on a windows-latest runner, installs the built .msi silently (msiexec /i), runs setup, registers and starts/stops the OpenDJ Windows service with an ldapsearch liveness check, then uninstalls (msiexec /x). --- .github/workflows/build.yml | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58927fe9e8..29cf33ada0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -441,3 +441,53 @@ jobs: timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test_custom | grep -q \"healthy\"; do sleep 10; done' docker exec test_custom 'sh' '-c' '/opt/opendj/bin/ldapsearch --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword custom_password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1' docker kill test_custom + + test-msi: + needs: build-maven + runs-on: 'windows-latest' + steps: + - name: Download artifacts + uses: actions/download-artifact@v8 + with: + name: windows-latest-11 + - name: Set up Java + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'zulu' + - name: Install MSI (silent) + shell: pwsh + run: | + $msi = (Get-ChildItem -Recurse -Filter *.msi -Path opendj-packages/opendj-msi | Select-Object -First 1).FullName + if (-not $msi) { throw "MSI not found in the windows-latest-11 artifact" } + Write-Host "MSI: $msi" + $p = Start-Process msiexec -Wait -PassThru -ArgumentList "/i `"$msi`" /quiet /qn /norestart OPENDJ=C:\opendj /l*v install.log" + if ($p.ExitCode -ne 0) { Get-Content install.log -Tail 80; throw "msiexec /i failed: $($p.ExitCode)" } + $root = @("C:\opendj","C:\Program Files (x86)\OpenDJ","C:\Program Files\OpenDJ") | Where-Object { Test-Path "$_\setup.bat" } | Select-Object -First 1 + if (-not $root) { Get-Content install.log -Tail 80; throw "OpenDJ install root with setup.bat not found" } + Write-Host "Installed to $root" + "OPENDJ_ROOT=$root" | Out-File -FilePath $env:GITHUB_ENV -Append + - name: Setup and start/stop the Windows service + shell: pwsh + run: | + $root = $env:OPENDJ_ROOT + $env:OPENDJ_JAVA_ARGS = "-server -Xmx512m" + & "$root\setup.bat" -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --addBaseEntry --cli --acceptLicense --no-prompt + if ($LASTEXITCODE -ne 0) { throw "setup.bat failed: $LASTEXITCODE" } + & "$root\bat\windows-service.bat" --enableService + if ($LASTEXITCODE -ne 0) { throw "windows-service --enableService failed: $LASTEXITCODE" } + net start "OpenDJ Server" + if ($LASTEXITCODE -ne 0) { throw "net start failed: $LASTEXITCODE" } + for ($i=0; $i -lt 12; $i++) { try { $c = New-Object System.Net.Sockets.TcpClient('localhost', 1636); $c.Close(); break } catch { Start-Sleep -Seconds 5 } } + & "$root\bat\ldapsearch.bat" --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example,dc=com" --searchScope base "(objectClass=*)" 1.1 + if ($LASTEXITCODE -ne 0) { throw "ldapsearch failed: $LASTEXITCODE" } + net stop "OpenDJ Server" + if ($LASTEXITCODE -ne 0) { throw "net stop failed: $LASTEXITCODE" } + & "$root\bat\windows-service.bat" --disableService + - name: Uninstall MSI + shell: pwsh + run: | + $msi = (Get-ChildItem -Recurse -Filter *.msi -Path opendj-packages/opendj-msi | Select-Object -First 1).FullName + $p = Start-Process msiexec -Wait -PassThru -ArgumentList "/x `"$msi`" /quiet /qn /norestart /l*v uninstall.log" + if ($p.ExitCode -ne 0) { Get-Content uninstall.log -Tail 80; throw "msiexec /x failed: $($p.ExitCode)" } + Write-Host "Uninstalled OK" From 830629c6b44711338863b3d1a54146f6f55c9ab0 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Sun, 28 Jun 2026 11:45:42 +0300 Subject: [PATCH 2/9] Require Java via MSI launch condition; fix test-msi (--doNotStart, JRE 25) The MSI ships no JRE, so add a WiX launch condition that fails the install early with a clear message when Java is not detected (it does not install Java). JAVA_HOME is captured from the environment before LaunchConditions; `Installed` keeps uninstall/repair working regardless of Java. Fix the test-msi CI job (it failed with `net start` exit 2 "service already started"): - setup.bat is now invoked with --doNotStart, so the server is started only by `net start "OpenDJ Server"` (setup.bat no longer starts a standalone instance first). - Bump actions/setup-java from 21 to 25 (latest LTS; smoke-tests the MSI under a fresh JRE). The runner has JAVA_HOME from setup-java, so the new launch condition is satisfied and the install proceeds. --- .github/workflows/build.yml | 4 ++-- .../opendj-msi-standard/resources/msi/package.wxs | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 29cf33ada0..9384c3ad51 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -453,7 +453,7 @@ jobs: - name: Set up Java uses: actions/setup-java@v5 with: - java-version: '21' + java-version: '25' distribution: 'zulu' - name: Install MSI (silent) shell: pwsh @@ -472,7 +472,7 @@ jobs: run: | $root = $env:OPENDJ_ROOT $env:OPENDJ_JAVA_ARGS = "-server -Xmx512m" - & "$root\setup.bat" -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --addBaseEntry --cli --acceptLicense --no-prompt + & "$root\setup.bat" -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --addBaseEntry --cli --acceptLicense --no-prompt --doNotStart if ($LASTEXITCODE -ne 0) { throw "setup.bat failed: $LASTEXITCODE" } & "$root\bat\windows-service.bat" --enableService if ($LASTEXITCODE -ne 0) { throw "windows-service --enableService failed: $LASTEXITCODE" } diff --git a/opendj-packages/opendj-msi/opendj-msi-standard/resources/msi/package.wxs b/opendj-packages/opendj-msi/opendj-msi-standard/resources/msi/package.wxs index 23f4dd4471..9835892c2b 100644 --- a/opendj-packages/opendj-msi/opendj-msi-standard/resources/msi/package.wxs +++ b/opendj-packages/opendj-msi/opendj-msi-standard/resources/msi/package.wxs @@ -13,7 +13,7 @@ ! information: "Portions Copyright [year] [name of copyright owner]". ! ! Copyright 2013-2016 ForgeRock AS. - ! Portion Copyright 2018 Open Identity Platform Community + ! Portions Copyright 2018-2026 3A Systems, LLC ! --> + + + + + + + From 2b2d25d31d520faa51a63b7372a7a6ab44fb069a Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Sun, 28 Jun 2026 23:22:01 +0300 Subject: [PATCH 3/9] remove MSI JAVA_HOME launch condition The launch condition (Installed OR JAVA_HOME_ENV) false-blocked valid installs: a JRE does not always set JAVA_HOME (it may be only on PATH). Drop it - the MSI again only copies files and Java availability stays the admin's responsibility. The test-msi fix (--doNotStart, JRE 25) is unaffected. --- .../opendj-msi-standard/resources/msi/package.wxs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/opendj-packages/opendj-msi/opendj-msi-standard/resources/msi/package.wxs b/opendj-packages/opendj-msi/opendj-msi-standard/resources/msi/package.wxs index 9835892c2b..f77dda7a14 100644 --- a/opendj-packages/opendj-msi/opendj-msi-standard/resources/msi/package.wxs +++ b/opendj-packages/opendj-msi/opendj-msi-standard/resources/msi/package.wxs @@ -35,15 +35,6 @@ - - - - - - - From 3edfa16347ed34e2ce4c3b448cd848be6a607475 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Sun, 28 Jun 2026 23:22:01 +0300 Subject: [PATCH 4/9] document MSI install/upgrade/uninstall The install guide covered only the .zip and native .deb/.rpm. Add Windows MSI sections to chap-install/chap-upgrade/chap-uninstall: GUI and silent msiexec install, Java as a runtime prerequisite the installer does not enforce, configure via setup.bat, optional Windows service registration via windows-service.bat, MSI upgrade (disable service, back up, install newer .msi, upgrade.bat, re-enable), and uninstall via Apps & features / msiexec /x. --- .../asciidoc/install-guide/chap-install.adoc | 44 +++++++++++++++++ .../install-guide/chap-uninstall.adoc | 29 +++++++++++- .../asciidoc/install-guide/chap-upgrade.adoc | 47 +++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) diff --git a/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-install.adoc b/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-install.adoc index 92be08f08a..f976103528 100644 --- a/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-install.adoc +++ b/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-install.adoc @@ -40,6 +40,8 @@ This chapter covers installation of OpenDJ server software and includes the foll * xref:#install-rpm["To Install From the RPM Package"] +* xref:#install-msi["To Install With the Windows Installer (MSI)"] + * xref:#install-properties-file["To Install OpenDJ Directory Server With a Properties File"] * xref:#pdb-to-je["To Move Data from a PDB Backend to a JE Backend"] @@ -635,6 +637,48 @@ opendj 0:off 1:off 2:on 3:on 4:on 5:on 6:off ==== +[#install-msi] +.To Install With the Windows Installer (MSI) +==== +On Windows you can install OpenDJ directory server from the `.msi` package. The installer only copies the server files to disk: it does not configure or start a server, it does not register a Windows service, and it does not install a Java runtime. + +. Make sure a supported Java runtime is available, as described in xref:#before-you-install["To Prepare For Installation"]. ++ +The installer does not check for Java. If your default Java environment is not appropriate, set `OPENDJ_JAVA_HOME` to the correct Java installation (or `OPENDJ_JAVA_BIN` to the absolute path of the `java` command), or make sure `java` is on the `PATH`, before you run `setup` or start the server. + +. Install the package, either with the GUI or silently: ++ +* GUI: double-click `opendj-{opendj-version}.msi` and follow the wizard. ++ +* Silent: run the following command (optionally set the installation directory with the `OPENDJ` property): ++ + +[source, console, subs="attributes"] +---- +C:\> msiexec /i opendj-{opendj-version}.msi /quiet OPENDJ="C:\opendj" +---- ++ +By default the package installs under `C:\Program Files\OpenDJ` (the 32-bit installer uses `C:\Program Files (x86)\OpenDJ` on 64-bit Windows). + +. Configure OpenDJ directory server by running the `setup` command, described in xref:../reference/admin-tools-ref.adoc#setup-1[setup(1)] in the __Reference__, from the installation directory. Use `setup.bat` for the GUI wizard or `setup.bat --cli` for the command-line: ++ + +[source, console] +---- +C:\path\to\opendj> setup.bat --cli +---- + +. (Optional) Register OpenDJ as a Windows service and start it. The MSI does not register the service; use the `windows-service` command: ++ + +[source, console] +---- +C:\path\to\opendj\bat> windows-service.bat --enableService +C:\> net start "OpenDJ Server" +---- + +==== + [#install-properties-file] .To Install OpenDJ Directory Server With a Properties File ==== diff --git a/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-uninstall.adoc b/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-uninstall.adoc index 19cc3a3875..17e0413635 100644 --- a/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-uninstall.adoc +++ b/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-uninstall.adoc @@ -12,7 +12,7 @@ information: "Portions copyright [year] [name of copyright owner]". Copyright 2017 ForgeRock AS. - Portions Copyright 2024 3A Systems LLC. + Portions Copyright 2024-2026 3A Systems LLC. //// :figure-caption!: @@ -33,6 +33,8 @@ This chapter includes the following procedures: * xref:#uninstall-rpm["To Uninstall the RPM Package"] +* xref:#uninstall-msi["To Uninstall the Windows MSI Package"] + [#uninstall-gui] .To Remove OpenDJ With the GUI Uninstaller @@ -157,3 +159,28 @@ Removing the package does not remove your data or configuration. You must remove ==== +[#uninstall-msi] +.To Uninstall the Windows MSI Package +==== +Remove OpenDJ directory server installed from the `.msi` package like any other Windows program. + +. If OpenDJ is registered as a Windows service, remove the service first: ++ + +[source, console] +---- +C:\path\to\opendj\bat> windows-service.bat --disableService +---- + +. Uninstall the package, either through __Settings > Apps__ (or __Control Panel > Programs and Features__) by selecting OpenDJ and choosing Uninstall, or from the command-line: ++ + +[source, console, subs="attributes"] +---- +C:\> msiexec /x opendj-{opendj-version}.msi /quiet +---- ++ +Uninstalling removes the files installed by the package. Your configured instance data under the installation directory (for example `config`, `db`, and `logs`) is not removed; delete the installation directory manually to remove all files. + +==== + diff --git a/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-upgrade.adoc b/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-upgrade.adoc index cf0268dec0..c514e71c82 100644 --- a/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-upgrade.adoc +++ b/opendj-doc-generated-ref/src/main/asciidoc/install-guide/chap-upgrade.adoc @@ -45,6 +45,8 @@ This chapter includes the following procedures and examples: * xref:#upgrade-zip-example["Upgrading to OpenDJ {opendj-version-short}"] +* xref:#upgrade-msi["To Upgrade the Windows MSI Installation"] + * xref:#upgrade-repl["To Upgrade Replicated Servers"] * xref:#new-repl-mixed-topology["To Add a New Replica to an Existing Topology"] @@ -243,6 +245,51 @@ $ ---- ==== +[#upgrade-msi] +.To Upgrade the Windows MSI Installation +==== +Before starting this procedure, follow the steps in xref:#before-you-upgrade["Before You Upgrade"]. Installing the newer `.msi` performs a major upgrade that replaces the installed program files, so make a full file-system backup of the current installation first. + +. Stop the current OpenDJ server. + +. If OpenDJ is registered as a Windows service, disable the service: ++ + +[source, console] +---- +C:\path\to\opendj\bat> windows-service.bat --disableService +---- + +. Back up the file-system directory where OpenDJ is installed. + +. Install the newer package (GUI or silent), using the same installation directory as the current server. Your configured instance data (`config`, `db`, `logs`) is kept; only the program files are replaced: ++ + +[source, console, subs="attributes"] +---- +C:\> msiexec /i opendj-{opendj-version}.msi /quiet OPENDJ="C:\path\to\opendj" +---- + +. Run the `upgrade` command, described in xref:../reference/admin-tools-ref.adoc#upgrade-1[upgrade(1)] in the __Reference__, to bring the configuration and application data up to date with the new binary and script files: ++ + +[source, console] +---- +C:\path\to\opendj> upgrade.bat --no-prompt --acceptLicense +---- + +. Start the upgraded OpenDJ server. + +. If you disabled the Windows service, enable it again: ++ + +[source, console] +---- +C:\path\to\opendj\bat> windows-service.bat --enableService +---- + +==== + [#upgrade-repl] .To Upgrade Replicated Servers ==== From 23b355af8302cbc99826b80844cfe5a12901fc22 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Thu, 2 Jul 2026 21:34:55 +0300 Subject: [PATCH 5/9] Fix unquoted java.io.tmpdir in Windows scripts (install paths with spaces) _script-util.bat appends -Djava.io.tmpdir=%OPENDJ_TMP_DIR% to OPENDJ_JAVA_ARGS without quotes, so in any install directory containing spaces (for example C:\Program Files (x86)\OpenDJ) the CheckJVMVersion probe - and with it setup and every other command-line tool - fails with "The detected Java version could not be used with the set of Java arguments". Quote the value: -Djava.io.tmpdir="%OPENDJ_TMP_DIR%". --- opendj-server-legacy/resource/bin/_script-util.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opendj-server-legacy/resource/bin/_script-util.bat b/opendj-server-legacy/resource/bin/_script-util.bat index f6bacbb9d1..30ef80d811 100644 --- a/opendj-server-legacy/resource/bin/_script-util.bat +++ b/opendj-server-legacy/resource/bin/_script-util.bat @@ -13,7 +13,7 @@ rem information: "Portions Copyright [year] [name of copyright owner]". rem rem Copyright 2008-2010 Sun Microsystems, Inc. rem Portions Copyright 2011-2016 ForgeRock AS. -rem Portions Copyright 2020-2025 3A Systems, LLC. +rem Portions Copyright 2020-2026 3A Systems, LLC. set SET_JAVA_HOME_AND_ARGS_DONE=false set SET_ENVIRONMENT_VARS_DONE=false @@ -186,7 +186,7 @@ goto scriptBegin if %SET_TEMP_DIR_DONE% == "true" goto end set OPENDJ_TMP_DIR=%INSTANCE_ROOT%\tmp if not exist "%OPENDJ_TMP_DIR%" mkdir "%OPENDJ_TMP_DIR%" -set OPENDJ_JAVA_ARGS=%OPENDJ_JAVA_ARGS% -Djava.io.tmpdir=%OPENDJ_TMP_DIR% +set OPENDJ_JAVA_ARGS=%OPENDJ_JAVA_ARGS% -Djava.io.tmpdir="%OPENDJ_TMP_DIR%" set SET_TEMP_DIR_DONE=true goto scriptBegin From 2b422467101609bde23ea40eb76fb73f8b90cad6 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Thu, 2 Jul 2026 21:48:13 +0300 Subject: [PATCH 6/9] test-msi: install into the default directory (path with spaces) Drop the OPENDJ=C:\opendj override so the MSI test exercises the default install directory (C:\Program Files (x86)\OpenDJ), which contains spaces - covering the java.io.tmpdir quoting fix merged from PR #671. --- .github/workflows/build.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9384c3ad51..86bf1884c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -461,9 +461,11 @@ jobs: $msi = (Get-ChildItem -Recurse -Filter *.msi -Path opendj-packages/opendj-msi | Select-Object -First 1).FullName if (-not $msi) { throw "MSI not found in the windows-latest-11 artifact" } Write-Host "MSI: $msi" - $p = Start-Process msiexec -Wait -PassThru -ArgumentList "/i `"$msi`" /quiet /qn /norestart OPENDJ=C:\opendj /l*v install.log" + # No OPENDJ property: use the default install directory (a path with spaces), + # which the server scripts must handle. + $p = Start-Process msiexec -Wait -PassThru -ArgumentList "/i `"$msi`" /quiet /qn /norestart /l*v install.log" if ($p.ExitCode -ne 0) { Get-Content install.log -Tail 80; throw "msiexec /i failed: $($p.ExitCode)" } - $root = @("C:\opendj","C:\Program Files (x86)\OpenDJ","C:\Program Files\OpenDJ") | Where-Object { Test-Path "$_\setup.bat" } | Select-Object -First 1 + $root = @("C:\Program Files (x86)\OpenDJ","C:\Program Files\OpenDJ") | Where-Object { Test-Path "$_\setup.bat" } | Select-Object -First 1 if (-not $root) { Get-Content install.log -Tail 80; throw "OpenDJ install root with setup.bat not found" } Write-Host "Installed to $root" "OPENDJ_ROOT=$root" | Out-File -FilePath $env:GITHUB_ENV -Append From a80fcdbd24be809b04684c86760719074263c0b1 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Fri, 3 Jul 2026 12:53:59 +0300 Subject: [PATCH 7/9] Fix classpath building for install paths with spaces/parentheses (setcp.bat) _script-util.bat passed unquoted paths to setcp.bat, and setcp.bat compared arguments with if ""%1""=="""". The argument-joining hack survived spaces, but a parenthesis in the path (C:\Program Files (x86)\OpenDJ - the default MSI directory) breaks the cmd parser with "... was unexpected at this time", so setup.bat and every tool exit with 255. Quote the setcp.bat arguments at the three call sites and switch setcp.bat to %~1 with quoted comparisons. --- opendj-server-legacy/resource/bin/_script-util.bat | 6 +++--- opendj-server-legacy/resource/bin/setcp.bat | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/opendj-server-legacy/resource/bin/_script-util.bat b/opendj-server-legacy/resource/bin/_script-util.bat index 30ef80d811..37538a75b3 100644 --- a/opendj-server-legacy/resource/bin/_script-util.bat +++ b/opendj-server-legacy/resource/bin/_script-util.bat @@ -56,10 +56,10 @@ rem get the absolute paths before building the classpath rem it also helps comparing the two paths FOR /F "delims=" %%i IN ("%INSTALL_ROOT%") DO set INSTALL_ROOT=%%~dpnxi FOR /F "delims=" %%i IN ("%INSTANCE_ROOT%") DO set INSTANCE_ROOT=%%~dpnxi -call "%INSTALL_ROOT%\lib\setcp.bat" %INSTALL_ROOT%\lib\bootstrap-client.jar +call "%INSTALL_ROOT%\lib\setcp.bat" "%INSTALL_ROOT%\lib\bootstrap-client.jar" set CLASSPATH=%INSTANCE_ROOT%\classes;%CLASSPATH% if "%INSTALL_ROOT%" == "%INSTANCE_ROOT%" goto setClassPathDone -FOR %%x in ("%INSTANCE_ROOT%\lib\*.jar") DO call "%INSTANCE_ROOT%\lib\setcp.bat" %%x +FOR %%x in ("%INSTANCE_ROOT%\lib\*.jar") DO call "%INSTANCE_ROOT%\lib\setcp.bat" "%%x" :setClassPathDone set SET_CLASSPATH_DONE=true goto scriptBegin @@ -71,7 +71,7 @@ rem get the absolute paths before building the classpath rem it also helps comparing the two paths FOR /F "delims=" %%i IN ("%INSTALL_ROOT%") DO set INSTALL_ROOT=%%~dpnxi FOR /F "delims=" %%i IN ("%INSTANCE_ROOT%") DO set INSTANCE_ROOT=%%~dpnxi -call "%INSTALL_ROOT%\lib\setcp.bat" %INSTALL_ROOT%\lib\* +call "%INSTALL_ROOT%\lib\setcp.bat" "%INSTALL_ROOT%\lib\*" set CLASSPATH=%INSTANCE_ROOT%\classes;%CLASSPATH% set SET_CLASSPATH_DONE=true goto scriptBegin diff --git a/opendj-server-legacy/resource/bin/setcp.bat b/opendj-server-legacy/resource/bin/setcp.bat index a47d4e6ac5..eca179c082 100644 --- a/opendj-server-legacy/resource/bin/setcp.bat +++ b/opendj-server-legacy/resource/bin/setcp.bat @@ -12,14 +12,17 @@ rem Header, with the fields enclosed by brackets [] replaced by your own identif rem information: "Portions Copyright [year] [name of copyright owner]". rem rem Copyright 2006-2008 Sun Microsystems, Inc. +rem Portions Copyright 2026 3A Systems, LLC -set CLASSPATHCOMPONENT=%1 -if ""%1""=="""" goto gotAllArgs +rem Use %~1 and quoted comparisons so paths containing spaces and parentheses +rem (for example C:\Program Files (x86)\OpenDJ) do not break the parser. +set CLASSPATHCOMPONENT=%~1 +if "%~1"=="" goto gotAllArgs shift :argCheck -if ""%1""=="""" goto gotAllArgs -set CLASSPATHCOMPONENT=%CLASSPATHCOMPONENT% %1 +if "%~1"=="" goto gotAllArgs +set CLASSPATHCOMPONENT=%CLASSPATHCOMPONENT% %~1 shift goto argCheck From dc97ea4420824267509f3f060893ef8d201a8fae Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Fri, 3 Jul 2026 16:33:26 +0300 Subject: [PATCH 8/9] Use "if defined" for JAVA_ARGS checks: the quoted java.io.tmpdir broke "%VAR%" == "" comparisons After -Djava.io.tmpdir="%OPENDJ_TMP_DIR%" is appended, OPENDJ_JAVA_ARGS contains embedded quotes, and the subsequent if "%OPENDJ_JAVA_ARGS%" == "" checks blow up the cmd parser ('...\tmp"" was unexpected at this time', every tool exits 255) regardless of whether the install path has spaces. Compare with "if defined", which does not expand the value. --- opendj-server-legacy/resource/bin/_script-util.bat | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/opendj-server-legacy/resource/bin/_script-util.bat b/opendj-server-legacy/resource/bin/_script-util.bat index 37538a75b3..bea162b7cd 100644 --- a/opendj-server-legacy/resource/bin/_script-util.bat +++ b/opendj-server-legacy/resource/bin/_script-util.bat @@ -100,7 +100,8 @@ rem if not "%OPENDJ_JAVA_ARGS%" == "" goto checkEnvJavaHome set SCRIPT_JAVA_ARGS_PROPERTY=%SCRIPT_NAME%.java-args call:readProperty %SCRIPT_JAVA_ARGS_PROPERTY% set OPENDJ_JAVA_ARGS=%OPENDJ_JAVA_ARGS% %PROPERTY_VALUE% -if not "%OPENDJ_JAVA_ARGS%" == "" goto checkEnvJavaHome +rem "if defined" comparisons: the value may contain quotes (java.io.tmpdir), which break "%VAR%" == "" checks. +if defined OPENDJ_JAVA_ARGS goto checkEnvJavaHome call:readProperty default.java-args set OPENDJ_JAVA_ARGS=%OPENDJ_JAVA_ARGS% %PROPERTY_VALUE if "%OPENDJ_JAVA_BIN%" == "" goto checkEnvJavaHome @@ -191,7 +192,7 @@ set SET_TEMP_DIR_DONE=true goto scriptBegin :testJava -if "%OPENDJ_JAVA_ARGS%" == "" goto checkLegacyArgs +if not defined OPENDJ_JAVA_ARGS goto checkLegacyArgs :continueTestJava "%OPENDJ_JAVA_BIN%" %OPENDJ_JAVA_ARGS% org.opends.server.tools.CheckJVMVersion > NUL 2>&1 set RESULT_CODE=%errorlevel% @@ -200,12 +201,12 @@ if not %RESULT_CODE% == 0 goto noValidJavaHome goto end :checkLegacyArgs -if "%OPENDS_JAVA_ARGS%" == "" goto continueTestJava +if not defined OPENDS_JAVA_ARGS goto continueTestJava set OPENDJ_JAVA_ARGS=%OPENDS_JAVA_ARGS% goto continueTestJava :noValidJavaHome -if NOT "%OPENDJ_JAVA_ARGS%" == "" goto noValidHomeWithArgs +if defined OPENDJ_JAVA_ARGS goto noValidHomeWithArgs echo ERROR: The detected Java version could not be used. The detected echo Java binary is: echo %OPENDJ_JAVA_BIN% From a5f8748a2dfac3cea0dedbb9cc891bba66747ddc Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Sat, 4 Jul 2026 18:28:14 +0300 Subject: [PATCH 9/9] start-ds.bat: quote the tmp-cleanup paths (parentheses break the block) The tmp-cleanup block expands %OPENDJ_TMP_DIR% unquoted inside a ( ) compound statement, so a parenthesis in the install path - C:\Program Files (x86)\OpenDJ - terminates the block at parse time and start-ds fails; the Windows service then dies with a service-specific error -1 while setup (which never runs this block) succeeds. Quote the three path expansions. --- opendj-server-legacy/resource/bin/start-ds.bat | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/opendj-server-legacy/resource/bin/start-ds.bat b/opendj-server-legacy/resource/bin/start-ds.bat index 7f7be60d89..f591502ba2 100644 --- a/opendj-server-legacy/resource/bin/start-ds.bat +++ b/opendj-server-legacy/resource/bin/start-ds.bat @@ -14,7 +14,7 @@ rem information: "Portions Copyright [year] [name of copyright owner]". rem rem Copyright 2006-2010 Sun Microsystems, Inc. rem Portions Copyright 2011-2014 ForgeRock AS. -rem Portions Copyright 2025 3A Systems LLC. +rem Portions Copyright 2025-2026 3A Systems LLC. setlocal set DIR_HOME=%~dp0.. @@ -61,10 +61,12 @@ echo %SCRIPT%: PATH=%PATH% >> %LOG% rem cleanup the tmp directory set CUR_DIR=%CD% set OPENDJ_TMP_DIR=%INSTANCE_ROOT%\tmp -dir /b /s /a %OPENDJ_TMP_DIR% | findstr .>nul && ( - cd /d %OPENDJ_TMP_DIR% +rem The paths must be quoted: an unquoted parenthesis (e.g. from +rem "C:\Program Files (x86)") terminates the ( ) block at parse time. +dir /b /s /a "%OPENDJ_TMP_DIR%" | findstr .>nul && ( + cd /d "%OPENDJ_TMP_DIR%" for /F "delims=" %%i in ('dir /b') do (rmdir "%%i" /s/q>NUL 2>&1 || del "%%i" /s/q>NUL 2>&1) - cd /d %CUR_DIR% + cd /d "%CUR_DIR%" ) "%OPENDJ_JAVA_BIN%" -client %SCRIPT_NAME_ARG% org.opends.server.core.DirectoryServer --configFile "%INSTANCE_ROOT%\config\config.ldif" --checkStartability %*