diff --git a/pljava/src/main/java/org/postgresql/pljava/management/Commands.java b/pljava/src/main/java/org/postgresql/pljava/management/Commands.java index df3884388..60c4dc39a 100644 --- a/pljava/src/main/java/org/postgresql/pljava/management/Commands.java +++ b/pljava/src/main/java/org/postgresql/pljava/management/Commands.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2023 Tada AB and other contributors, as listed below. + * Copyright (c) 2004-2025 Tada AB and other contributors, as listed below. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the The BSD 3-Clause License @@ -43,6 +43,7 @@ import java.text.ParseException; import java.util.ArrayList; import static java.util.Arrays.fill; +import static java.util.Objects.requireNonNullElse; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; @@ -68,6 +69,7 @@ import static org.postgresql.pljava.internal.Privilege.doPrivileged; import static org.postgresql.pljava.jdbc.SQLUtils.getDefaultConnection; import org.postgresql.pljava.sqlj.Loader; +import static org.postgresql.pljava.sqlj.Loader.PUBLIC_SCHEMA; import org.postgresql.pljava.annotation.Function; import org.postgresql.pljava.annotation.SQLAction; @@ -934,7 +936,8 @@ public static void replaceJar(String urlString, String jarName, * * @param schemaName Name of the schema for which this path is valid. * @param path Colon separated list of names. Each name must denote the name - * of a jar that is present in the jar repository. + * of a jar that is present in the jar repository. An empty + * string or null equivalently set no class path for the schema. * @throws SQLException If no schema can be found with the givene name, or * if one or several names of the path denotes a nonexistant jar * file. @@ -1022,7 +1025,6 @@ public static void setClassPath(Identifier.Simple schema, String path) { // Insert the new path. // - ; try(PreparedStatement stmt = getDefaultConnection() .prepareStatement( "INSERT INTO sqlj.classpath_entry("+ @@ -1042,41 +1044,60 @@ public static void setClassPath(Identifier.Simple schema, String path) Loader.clearSchemaLoaders(); } + /** + * Run runnable while a temporary class path including + * jarName, if needed, is imposed on the current + * (head-of-{@code search_path}) schema. + *
+ * The temporary class path is imposed if jarName is not already
+ * included in the current schema's class path, and also not in the public
+ * schema's class path if the current schema is not the public one.
+ *
+ * @param jarName Caller must have checked (as with {@code assertJarName})
+ * that this is a sensible jar name, in particular without the colons that
+ * separate a PL/Java class path.
+ * @param schemaMayVanish Caller passes true if this is a {@code remove_jar}
+ * action, when it should not be surprising if undoing the temporary class
+ * path fails because the schema is gone after the undeploy steps.
+ * @param runnable The deploy/undeploy actions to take while the temporary
+ * class path is possibly imposed.
+ */
private static void withJarInPath(String jarName, boolean schemaMayVanish,
Checked.Runnable