Skip to content

Commit 158877e

Browse files
joewizclaude
andcommitted
[bugfix] repo:install-and-deploy: use the resolved version for the classpath too
The previous commit deployed the explicitly-requested version but still drove ClasspathHelper.updateClasspath() (and the install status/action reporting) from installPackage()'s return value, which can be packages.latest() -- a higher already-installed version. So repo:install-and-deploy(name, "<older>", url) deployed the older version's XQuery resources while loading the newer version's Java JARs onto the classpath, a silent version mismatch. Resolve the deploy target once (resolveInstalledVersion) before the classpath update and use it for BOTH the classpath update and the deploy, so they always act on the same package version. Also treat an empty @Version (the DOM getAttribute returns "" not null for a versionless descriptor) as "no specific version requested", and drop a redundant Packages import already covered by the package wildcard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ThoADnh6VvDt5w8kz7d2d3
1 parent 202cec4 commit 158877e

1 file changed

Lines changed: 20 additions & 16 deletions

File tree

exist-core/src/main/java/org/exist/repo/Deployment.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import org.exist.xquery.value.SequenceIterator;
4747
import org.exist.xquery.value.Type;
4848
import org.expath.pkg.repo.Package;
49-
import org.expath.pkg.repo.Packages;
5049
import org.expath.pkg.repo.*;
5150
import org.expath.pkg.repo.deps.DependencyVersion;
5251
import org.expath.pkg.repo.tui.BatchUserInteraction;
@@ -246,24 +245,26 @@ public Optional<String> installAndDeploy(final DBBroker broker, final Txn transa
246245
LOG.info("Installing package {}", xar.getURI());
247246
final UserInteractionStrategy interact = new BatchUserInteraction();
248247
final org.expath.pkg.repo.Package pkg = repo.get().getParentRepo().installPackage(xar, true, interact);
249-
final ExistPkgInfo info = (ExistPkgInfo) pkg.getInfo("exist");
248+
249+
// installPackage may return packages.latest() (the highest-version entry by semver)
250+
// rather than the just-installed package when the registry already had a higher version
251+
// with the same name. Resolve the freshly-installed package specifically (looked up by
252+
// the version we extracted from the XAR descriptor above) and use it for BOTH the
253+
// classpath update and the deploy below, so an explicit
254+
// repo:install-and-deploy(name, "<older>", url) is not silently upgraded to
255+
// packages.latest() -- and its Java module JARs are not loaded from the wrong (higher)
256+
// version's package.
257+
final Package deployTarget = resolveInstalledVersion(repo.get(), pkg, pkgVersion);
258+
final ExistPkgInfo info = (ExistPkgInfo) deployTarget.getInfo("exist");
250259
if (info != null && !info.getJars().isEmpty()) {
251-
ClasspathHelper.updateClasspath(broker.getBrokerPool(), pkg);
260+
ClasspathHelper.updateClasspath(broker.getBrokerPool(), deployTarget);
252261
}
253262
broker.getBrokerPool().getXQueryPool().clear();
254-
final String pkgName = pkg.getName();
263+
final String pkgName = deployTarget.getName();
255264
// signal status
256-
broker.getBrokerPool().reportStatus("Installing app: " + pkg.getAbbrev());
257-
repo.get().reportAction(ExistRepository.Action.INSTALL, pkg.getName());
258-
259-
// installPackage may return packages.latest() (the highest-version
260-
// entry by semver) rather than the just-installed package when the
261-
// registry already had a higher version with the same name. Deploy
262-
// the freshly-installed package specifically (looked up by the
263-
// version we extracted from the XAR descriptor above) so an explicit
264-
// repo:install-and-deploy(name, "<older>", url) is not silently
265-
// upgraded to packages.latest().
266-
final Package deployTarget = resolveInstalledVersion(repo.get(), pkg, pkgVersion);
265+
broker.getBrokerPool().reportStatus("Installing app: " + deployTarget.getAbbrev());
266+
repo.get().reportAction(ExistRepository.Action.INSTALL, deployTarget.getName());
267+
267268
LOG.info("Deploying package {} (version {})", pkgName, deployTarget.getVersion());
268269
return deploy(broker, transaction, deployTarget, null);
269270
}
@@ -283,7 +284,10 @@ private void checkProcessorVersion(final PackageLoader.Version version) throws P
283284
}
284285

285286
private Package resolveInstalledVersion(final ExistRepository repo, final Package installed, final String requestedVersion) {
286-
if (requestedVersion == null) {
287+
// requestedVersion comes from the XAR descriptor's @version, which is "" (not null) when the
288+
// descriptor declares no version -- in that case there is no specific version to honor, so
289+
// fall back to the freshly-installed package.
290+
if (requestedVersion == null || requestedVersion.isEmpty()) {
287291
return installed;
288292
}
289293
final Packages allVersions = repo.getParentRepo().getPackages(installed.getName());

0 commit comments

Comments
 (0)