diff --git a/.github/workflows/ci-runnerpg.yml b/.github/workflows/ci-runnerpg.yml
index fb456a7fa..641958e95 100644
--- a/.github/workflows/ci-runnerpg.yml
+++ b/.github/workflows/ci-runnerpg.yml
@@ -28,7 +28,7 @@ jobs:
# cc: msvc
# - os: windows-latest
# cc: mingw
- java: [9, 11, 12, 17, 18, 19]
+ java: [9, 11, 17, 19, 21]
steps:
diff --git a/appveyor.yml b/appveyor.yml
index ed964f202..d5edb9c53 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -12,56 +12,32 @@ environment:
APPVEYOR_RDP_PASSWORD: MrRobot@2020
VCVARSALL: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
matrix:
-# - SYS: MINGW
-# JDK: 9
-# PG: 12
-# - SYS: MINGW
-# JDK: 10
-# PG: 12
- SYS: MINGW
JDK: 11
- PG: 12
+ PG: pacman
- SYS: MINGW
- JDK: 12
- PG: 12
+ JDK: 17
+ PG: pacman
- SYS: MINGW
- JDK: 13
- PG: 12
+ JDK: 19
+ PG: pacman
- SYS: MINGW
- JDK: 14
- PG: 12
- - SYS: MINGW
- JDK: 15
- PG: 12
+ JDK: 21
+ PG: pacman
- SYS: MSVC
- JDK: 15
- PG: 12
+ JDK: 21
+ PG: 15
- SYS: MSVC
- JDK: 14
- PG: 12
+ JDK: 21
+ PG: 14
- SYS: MSVC
- JDK: 13
- PG: 12
+ JDK: 21
+ PG: 13
- SYS: MSVC
- JDK: 12
+ JDK: 21
PG: 12
- SYS: MSVC
JDK: 11
- PG: 12
-# - SYS: MSVC
-# JDK: 10
-# PG: 12
-# - SYS: MSVC
-# JDK: 9
-# PG: 12
- - SYS: MSVC
- JDK: 14
- PG: 11
- - SYS: MSVC
- JDK: 14
- PG: 10
- - SYS: MSVC
- JDK: 14
PG: 9.6
before_build:
- ps: .appveyor/appveyor_download_java.ps1
diff --git a/pljava-api/src/main/java/org/postgresql/pljava/Adjusting.java b/pljava-api/src/main/java/org/postgresql/pljava/Adjusting.java
index 3c8ce6398..341348ca8 100644
--- a/pljava-api/src/main/java/org/postgresql/pljava/Adjusting.java
+++ b/pljava-api/src/main/java/org/postgresql/pljava/Adjusting.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2023 Tada AB and other contributors, as listed below.
+ * Copyright (c) 2019-2024 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
@@ -147,16 +147,34 @@ private XML() { } // no instances
* {@link Exception#getSuppressed getSuppressed}. The return is
* immediate, without any remaining names being tried, if an exception
* is caught that is not assignable to a class in the
- * expected list. Such an exception will be passed to the
- * onUnexpected handler if that is non-null; otherwise,
- * it will be returned (or added to the suppressed list of the
- * exception to be returned) just as expected exceptions are.
+ * expected list. Such an exception is returned (or added to
+ * the suppressed list of an exception already to be returned) only if
+ * the onUnexpected handler is null; otherwise, it is passed
+ * to the handler and does not affect the method's return.
+ *
+ * For some purposes, a single call of this method may not suffice: if
+ * alternate means to establish a desired configuration have existed and
+ * are not simply alternate property names that will accept the same
+ * value. For such a case, this method may be called more than once. The
+ * caller abandons the sequence of calls after the first call that
+ * returns null (indicating that it either succeeded, or incurred an
+ * unexpected exception and passed it to the onUnexpected
+ * handler. Otherwise, the exception returned by the first call can be
+ * passed as caught to the next call, instead of passing the
+ * usual null. (When a non-null caught is passed, it will be
+ * returned on failure, even if an unexpected exception has been caught;
+ * therefore, should it ever be necessary to chain more than two of
+ * these calls, the caller should abandon the sequence as soon as a call
+ * returns null or returns its caught argument with
+ * no growth of its suppressed list.)
* @param setter typically a method reference for a method that
* takes a string key and some value.
* @param value the value to pass to the setter
* @param expected a list of exception classes that can be foreseen
* to indicate that a key was not recognized, and the operation
* should be retried with the next possible key.
+ * @param caught null, or an exception returned by a preceding call if
+ * an operation cannot be implemented with one call of this method
* @param onUnexpected invoked, if non-null, on an {@code Exception}
* that is caught and matches nothing in the expected list, instead
* of returning it. If this parameter is null, such an exception is
@@ -165,16 +183,19 @@ private XML() { } // no instances
* immediate, without trying remaining names, if any.
* @param names one or more String keys to be tried in order until
* the action succeeds.
- * @return null if any attempt succeeded, otherwise an exception,
- * which may have further exceptions in its suppressed list.
+ * @return null if any attempt succeeded, or if the first exception
+ * caught was passed to the onUnexpected handler; otherwise the first
+ * exception caught (if the caller supplied a non-null
+ * caught, then that exception), which may have further
+ * exceptions in its suppressed list.
*/
public static Exception setFirstSupported(
SetMethod super T> setter, V value,
List> expected,
+ Exception caught,
Consumer super Exception> onUnexpected, String... names)
{
requireNonNull(expected);
- Exception caught = null;
for ( String name : names )
{
try
@@ -204,6 +225,18 @@ public static Exception setFirstSupported(
return caught;
}
+ /**
+ * Calls the six-argument overload passing null for caught.
+ */
+ public static Exception setFirstSupported(
+ SetMethod super T> setter, V value,
+ List> expected,
+ Consumer super Exception> onUnexpected, String... names)
+ {
+ return setFirstSupported(
+ setter, value, expected, null, onUnexpected, names);
+ }
+
/**
* A functional interface fitting various {@code setFeature} or
* {@code setProperty} methods in Java XML APIs.
@@ -268,6 +301,17 @@ public interface Parsing>
/** Whether to allow a DTD at all. */
T allowDTD(boolean v);
+ /**
+ * Specifies that any DTD should be ignored (neither processed nor
+ * rejected as an error).
+ *
+ * This treatment is available in Java 22 and later.
+ * In earlier Java versions, this will not succeed. Where it is
+ * supported, the most recent call of this method or of
+ * {@link #allowDTD allowDTD} will be honored.
+ */
+ T ignoreDTD();
+
/**
* Whether to retrieve external "general" entities (those
* that can be used in the document body) declared in the DTD.
diff --git a/pljava-api/src/main/java/org/postgresql/pljava/annotation/processing/DDRProcessor.java b/pljava-api/src/main/java/org/postgresql/pljava/annotation/processing/DDRProcessor.java
index ccd2a8a7f..465f5ddf4 100644
--- a/pljava-api/src/main/java/org/postgresql/pljava/annotation/processing/DDRProcessor.java
+++ b/pljava-api/src/main/java/org/postgresql/pljava/annotation/processing/DDRProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2023 Tada AB and other contributors, as listed below.
+ * Copyright (c) 2004-2024 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
@@ -173,7 +173,7 @@ public SourceVersion getSupportedSourceVersion()
* Update latest_tested to be the latest Java release on which this
* annotation processor has been tested without problems.
*/
- int latest_tested = 21;
+ int latest_tested = 22;
int ordinal_9 = SourceVersion.RELEASE_9.ordinal();
int ordinal_latest = latest_tested - 9 + ordinal_9;
diff --git a/pljava-examples/src/main/java/org/postgresql/pljava/example/annotation/PassXML.java b/pljava-examples/src/main/java/org/postgresql/pljava/example/annotation/PassXML.java
index 37ad6eb8e..5f3886886 100644
--- a/pljava-examples/src/main/java/org/postgresql/pljava/example/annotation/PassXML.java
+++ b/pljava-examples/src/main/java/org/postgresql/pljava/example/annotation/PassXML.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2023 Tada AB and other contributors, as listed below.
+ * Copyright (c) 2018-2024 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
@@ -272,6 +272,43 @@
" WHERE extname = 'pljava'"
}
)
+
+@SQLAction(implementor="postgresql_xml",
+ provides="xml_java_ge_22", requires="javaSpecificationGE", install=
+ "SELECT CASE WHEN" +
+ " javatest.javaSpecificationGE('22')" +
+ " THEN set_config('pljava.implementors', 'xml_java_ge_22,' || " +
+ " current_setting('pljava.implementors'), true) " +
+ "END"
+)
+
+@SQLAction(implementor="xml_java_ge_22", requires="lowLevelXMLEcho", install=
+ "WITH" +
+ " s(how) AS (SELECT unnest('{5,6,7}'::int[]))," +
+ " r(isdoc) AS (" +
+ " SELECT" +
+ " javatest.lowlevelxmlecho(" +
+ /*
+ * A truly minimal DTD, , cannot be ignored by Java 22's SAX/DOM
+ * parser (though it can be, when using the StAX API). NullPointerException
+ * calling getActiveGrammar().isImmutable() is the result. Bug: JDK-8329295
+ * Including either an externalID or an internal subset (like the empty []
+ * here) avoids the issue.
+ */
+ " ''::xml, how, params) IS DOCUMENT" +
+ " FROM" +
+ " s," +
+ " (SELECT null::void AS ignoreDTD) AS params" +
+ " )" +
+ "SELECT" +
+ " CASE WHEN every(isdoc)" +
+ " THEN javatest.logmessage('INFO', 'jdk.xml.dtd.support=ignore OK')" +
+ " ELSE javatest.logmessage('WARNING', 'jdk.xml.dtd.support=ignore NG')" +
+ " END " +
+ "FROM" +
+ " r"
+)
+
@MappedUDT(schema="javatest", name="onexml", structure="c1 xml",
implementor="postgresql_xml",
comment="A composite type mapped by the PassXML example class")
@@ -783,8 +820,7 @@ public static SQLXML lowLevelXMLEcho(
*
* Column names in the adjust row are case-insensitive versions of
* the method names in {@link Adjusting.XML.Parsing}, and the value of each
- * column should be of the appropriate type (at present, boolean for all of
- * them).
+ * column should be of the appropriate type (if the method has a parameter).
* @param adjust A row type as described above, possibly of no columns if no
* adjustments are wanted
* @param axp An instance of Adjusting.XML.Parsing
@@ -804,6 +840,8 @@ T applyAdjustments(ResultSet adjust, T axp)
axp.lax(adjust.getBoolean(i));
else if ( "allowDTD".equalsIgnoreCase(k) )
axp.allowDTD(adjust.getBoolean(i));
+ else if ( "ignoreDTD".equalsIgnoreCase(k) )
+ axp.ignoreDTD();
else if ( "externalGeneralEntities".equalsIgnoreCase(k) )
axp.externalGeneralEntities(adjust.getBoolean(i));
else if ( "externalParameterEntities".equalsIgnoreCase(k) )
diff --git a/pljava-packaging/build.xml b/pljava-packaging/build.xml
index fb8555cc4..95e4dd33c 100644
--- a/pljava-packaging/build.xml
+++ b/pljava-packaging/build.xml
@@ -255,6 +255,10 @@ jos.close();
simple update is possible, just repeat the next entry, with
the from-version changed.
-->
+
* An
* introduction with examples
* is available.
*
- * Unlike the many capabilities of {@code PostgresNode.pm}, this only deals in
- * TCP sockets bound to {@code localhost} ({@code StandardProtocolFamily.UNIX}
+ * Unlike the many capabilities of {@code PostgreSQL::Test::Cluster}, this only
+ * deals in TCP sockets bound to {@code localhost}
+ * ({@code StandardProtocolFamily.UNIX}
* finally arrived in Java 16 but this class does not support it yet) and only
* a few of the most basic operations.
*
@@ -2623,9 +2625,9 @@ private static Object invoke(InvocationHandler h, int stateIdx, Object o)
* Waits for the {@code postmaster.pid} file to have the right contents
* (the right pid for process p, and ready status for PG 10+).
*
- * The {code PostgresNode.pm} version of this is also used when shutting
- * down, and waits for the file to go away; that could be implemented here,
- * but not today.
+ * The {@code PostgreSQL:Test:Cluster} version of this is also used when
+ * shutting down, and waits for the file to go away; that could be
+ * implemented here, but not today.
*/
private void wait_for_pid_file(Process p, ProcessHandle.Info info)
throws Exception
diff --git a/pljava-pgxs/pom.xml b/pljava-pgxs/pom.xml
index 19896dbde..685b50731 100644
--- a/pljava-pgxs/pom.xml
+++ b/pljava-pgxs/pom.xml
@@ -40,20 +40,15 @@
- nashorngone
+ nashornmod
[15,)
- org.graalvm.js
- js
- 20.1.0
-
-
- org.graalvm.js
- js-scriptengine
- 20.1.0
+ org.openjdk.nashorn
+ nashorn-core
+ 15.4
diff --git a/pljava-so/pom.xml b/pljava-so/pom.xml
index dbd52812e..1995c0264 100644
--- a/pljava-so/pom.xml
+++ b/pljava-so/pom.xml
@@ -120,6 +120,47 @@
}
},
+ {
+ name : "FreeBSD",
+
+ object_extension : ".o",
+
+ probe: function(os_name) {
+ return os_name.toLowerCase().contains("freebsd");
+ },
+
+ compile : function(cc, files, output_dir, includes, defines, flags) {
+ includes.add(java_include.resolve("freebsd").toString());
+ defines.put("FreeBSD", null);
+ flags.add("-c");
+ if(isDebugEnabled)
+ flags.add("-g");
+ var compileProcess = utils.processBuilder(function(l) {
+ l.add(cc);
+ l.addAll(pgxs.formatDefines(defines));
+ l.addAll(pgxs.formatIncludes(includes));
+ l.addAll(flags);
+ l.addAll(files);
+ });
+ compileProcess.directory(output_dir.toFile());
+ return runCommand(compileProcess);
+ },
+
+ link : function(cc, flags, files, target_path) {
+ if(isDebugEnabled)
+ flags.add("-g");
+ flags.add("-shared-libgcc");
+ var linkingProcess = utils.processBuilder(function(l) {
+ l.add(cc);
+ l.addAll(flags);
+ l.addAll(of("-shared", "-o", "lib" + library_name + ".so"));
+ l.addAll(files);
+ });
+ linkingProcess.directory(target_path.toFile());
+ return runCommand(linkingProcess);
+ }
+ },
+
{
name : "Mac OS X",
diff --git a/pljava-so/src/main/c/Backend.c b/pljava-so/src/main/c/Backend.c
index 9b70c28c1..30569c2e0 100644
--- a/pljava-so/src/main/c/Backend.c
+++ b/pljava-so/src/main/c/Backend.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2023 Tada AB and other contributors, as listed below.
+ * Copyright (c) 2004-2024 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
@@ -1941,10 +1941,10 @@ void Backend_warnJEP411(bool isCommit)
"Java features that will be phased out in future Java versions. "
"Those changes will come in releases after Java 17."),
errhint(
- "For migration planning, Java versions up to and including 17 "
- "remain fully usable with this version of PL/Java, and Java 17 "
- "is positioned as a long-term support release. For details on "
- "how PL/Java will adapt, please bookmark "
+ "For migration planning, this version of PL/Java can still "
+ "enforce policy in Java versions up to and including 22, "
+ "and Java 17 and 21 are positioned as long-term support releases. "
+ "For details on how PL/Java will adapt, please bookmark "
"https://github.com/tada/pljava/wiki/JEP-411")
));
}
diff --git a/pljava/src/main/java/org/postgresql/pljava/internal/InstallHelper.java b/pljava/src/main/java/org/postgresql/pljava/internal/InstallHelper.java
index 55e1f76c7..9bf94232d 100644
--- a/pljava/src/main/java/org/postgresql/pljava/internal/InstallHelper.java
+++ b/pljava/src/main/java/org/postgresql/pljava/internal/InstallHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2023 Tada AB and other contributors, as listed below.
+ * Copyright (c) 2015-2024 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
@@ -991,6 +991,7 @@ void migrateFrom( SchemaVariant sv, Connection c, Statement s)
UNREL20040120 ("5e4131738cd095b7ff6367d64f809f6cec6a7ba7"),
EMPTY (null);
+ static final SchemaVariant REL_1_6_7 = REL_1_6_0;
static final SchemaVariant REL_1_6_6 = REL_1_6_0;
static final SchemaVariant REL_1_6_5 = REL_1_6_0;
static final SchemaVariant REL_1_6_4 = REL_1_6_0;
diff --git a/pljava/src/main/java/org/postgresql/pljava/internal/Portal.java b/pljava/src/main/java/org/postgresql/pljava/internal/Portal.java
index 790581382..363f2bb1b 100644
--- a/pljava/src/main/java/org/postgresql/pljava/internal/Portal.java
+++ b/pljava/src/main/java/org/postgresql/pljava/internal/Portal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2019 Tada AB and other contributors, as listed below.
+ * Copyright (c) 2004-2023 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
@@ -25,28 +25,29 @@
*/
public class Portal
{
- /*
- * Hold a reference to the Java ExecutionPlan object as long as we might be
- * using it, just to make sure Java unreachability doesn't cause it to
- * mop up its native plan state while the portal might still be using it.
- */
- private ExecutionPlan m_plan;
-
private final State m_state;
Portal(DualState.Key cookie, long ro, long pointer, ExecutionPlan plan)
{
- m_state = new State(cookie, this, ro, pointer);
- m_plan = plan;
+ m_state = new State(cookie, this, ro, pointer, plan);
}
private static class State
extends DualState.SingleSPIcursorClose
{
+ /*
+ * Hold a reference to the Java ExecutionPlan object as long as we might
+ * be using it, just to make sure Java unreachability doesn't cause it
+ * to mop up its native plan state while the portal might still want it.
+ */
+ private ExecutionPlan m_plan;
+
private State(
- DualState.Key cookie, Portal referent, long ro, long portal)
+ DualState.Key cookie, Portal referent, long ro, long portal,
+ ExecutionPlan plan)
{
super(cookie, referent, ro, portal);
+ m_plan = plan;
}
/**
@@ -76,6 +77,13 @@ private long getPortalPtr() throws SQLException
unpin();
}
}
+
+ @Override
+ protected void javaStateReleased(boolean nativeStateLive)
+ {
+ super.javaStateReleased(nativeStateLive);
+ m_plan = null;
+ }
}
/**
@@ -84,11 +92,7 @@ private long getPortalPtr() throws SQLException
*/
public void close()
{
- doInPG(() ->
- {
- m_state.releaseFromJava();
- m_plan = null;
- });
+ m_state.releaseFromJava();
}
/**
diff --git a/pljava/src/main/java/org/postgresql/pljava/jdbc/SQLXMLImpl.java b/pljava/src/main/java/org/postgresql/pljava/jdbc/SQLXMLImpl.java
index bd8c8b64c..87f6e60b4 100644
--- a/pljava/src/main/java/org/postgresql/pljava/jdbc/SQLXMLImpl.java
+++ b/pljava/src/main/java/org/postgresql/pljava/jdbc/SQLXMLImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2023 Tada AB and other contributors, as listed below.
+ * Copyright (c) 2018-2024 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
@@ -3933,6 +3933,10 @@ static void saxCopy(SAXSource sxs, SAXResult sxr) throws SQLException
SAX2PROPERTY.LEXICAL_HANDLER.propertyUri(), lh);
xr.parse(sxs.getInputSource());
}
+ /*
+ * If changing these wrapping conventions, change them also in
+ * AdjustingDOMSource.get()
+ */
catch ( SAXException e )
{
throw new SQLDataException(e.getMessage(), "22000", e);
@@ -4154,6 +4158,10 @@ Writable finish() throws IOException, SQLException
private static final String JDK17 = "jdk.xml.";
private static final String LIMIT =
"http://www.oracle.com/xml/jaxp/properties/"; // "legacy" since 17
+ protected static final String DTDSUPPORT = "jdk.xml.dtd.support";
+ protected static final String ALLOW = "allow";
+ protected static final String IGNORE = "ignore";
+ protected static final String DENY = "deny";
private Exception m_signaling;
private Exception m_quiet;
@@ -4227,6 +4235,12 @@ public T defaults()
.xIncludeAware(false).expandEntityReferences(false);
}
+ @Override
+ public T ignoreDTD()
+ {
+ return setFirstSupportedProperty(IGNORE, DTDSUPPORT);
+ }
+
@Override
public T elementAttributeLimit(int limit)
{
@@ -4328,12 +4342,29 @@ public T schema(Schema schema)
abstract static class SAXDOMCommon>
extends AdjustingJAXPParser
{
+ protected abstract Exception tryFirstSupportedFeature(
+ Exception caught, boolean value, String... names);
+
+ protected abstract Exception tryFirstSupportedProperty(
+ Exception caught, Object value, String... names);
+
+ protected abstract T self();
+
@Override
public T allowDTD(boolean v) {
- return setFirstSupportedFeature( !v,
+ Exception caught =
+ tryFirstSupportedProperty(null, v ? ALLOW : DENY, DTDSUPPORT);
+
+ if ( null == caught )
+ return self();
+
+ caught = tryFirstSupportedFeature(caught, !v,
"http://apache.org/xml/features/disallow-doctype-decl",
"http://xerces.apache.org/xerces2-j/features.html" +
"#disallow-doctype-decl");
+
+ addQuiet(caught);
+ return self();
}
@Override
@@ -4967,17 +4998,17 @@ static class Dummy extends AdjustingSAXSource
private Dummy() { }
@Override
- public AdjustingSAXSource setFirstSupportedFeature(
- boolean value, String... names)
+ protected Exception tryFirstSupportedFeature(
+ Exception caught, boolean value, String... names)
{
- return this;
+ return caught;
}
@Override
- public AdjustingSAXSource setFirstSupportedProperty(
- Object value, String... names)
+ protected Exception tryFirstSupportedProperty(
+ Exception caught, Object value, String... names)
{
- return this;
+ return caught;
}
@Override
@@ -5127,34 +5158,52 @@ public AdjustingSAXSource expandEntityReferences(boolean v)
}
@Override
- public AdjustingSAXSource setFirstSupportedFeature(
- boolean value, String... names)
+ protected Exception tryFirstSupportedFeature(
+ Exception caught, boolean value, String... names)
{
XMLReader r = theReader();
if ( null == r ) // pending exception, nothing to be done
- return this;
+ return caught;
- addQuiet(setFirstSupported(r::setFeature, value,
+ return setFirstSupported(r::setFeature, value,
List.of(SAXNotRecognizedException.class,
SAXNotSupportedException.class),
- this::addSignaling, names));
-
- return this;
+ caught, this::addSignaling, names);
}
@Override
- public AdjustingSAXSource setFirstSupportedProperty(
- Object value, String... names)
+ protected Exception tryFirstSupportedProperty(
+ Exception caught, Object value, String... names)
{
XMLReader r = theReader();
if ( null == r ) // pending exception, nothing to be done
- return this;
+ return caught;
- addQuiet(setFirstSupported(r::setProperty, value,
+ return setFirstSupported(r::setProperty, value,
List.of(SAXNotRecognizedException.class,
SAXNotSupportedException.class),
- this::addSignaling, names));
+ caught, this::addSignaling, names);
+ }
+ @Override
+ protected AdjustingSAXSource self()
+ {
+ return this;
+ }
+
+ @Override
+ public AdjustingSAXSource setFirstSupportedFeature(
+ boolean value, String... names)
+ {
+ addQuiet(tryFirstSupportedFeature(null, value, names));
+ return this;
+ }
+
+ @Override
+ public AdjustingSAXSource setFirstSupportedProperty(
+ Object value, String... names)
+ {
+ addQuiet(tryFirstSupportedProperty(null, value, names));
return this;
}
@@ -5245,6 +5294,28 @@ public AdjustingSAXResult expandEntityReferences(boolean v)
return checkedNoOp();
}
+ @Override
+ protected Exception tryFirstSupportedFeature(
+ Exception caught, boolean value, String... names)
+ {
+ checkedNoOp();
+ return null;
+ }
+
+ @Override
+ protected Exception tryFirstSupportedProperty(
+ Exception caught, Object value, String... names)
+ {
+ checkedNoOp();
+ return null;
+ }
+
+ @Override
+ protected AdjustingSAXResult self()
+ {
+ return this;
+ }
+
@Override
public AdjustingSAXResult setFirstSupportedFeature(
boolean value, String... names)
@@ -5351,7 +5422,16 @@ public AdjustingStAXSource lax(boolean discard)
@Override
public AdjustingStAXSource allowDTD(boolean v) {
- return setFirstSupportedFeature( v, XMLInputFactory.SUPPORT_DTD);
+ Exception caught =
+ tryFirstSupported(null, v ? ALLOW : DENY, DTDSUPPORT);
+
+ if ( null == caught )
+ return this;
+
+ caught = tryFirstSupported(caught, v, XMLInputFactory.SUPPORT_DTD);
+
+ addQuiet(caught);
+ return this;
}
@Override
@@ -5388,14 +5468,20 @@ public AdjustingStAXSource expandEntityReferences(boolean v)
XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES);
}
+ private Exception tryFirstSupported(
+ Exception caught, Object value, String... names)
+ {
+ XMLInputFactory xif = theFactory();
+ return setFirstSupported(xif::setProperty, value,
+ List.of(IllegalArgumentException.class),
+ caught, this::addSignaling, names);
+ }
+
@Override
public AdjustingStAXSource setFirstSupportedFeature(
boolean value, String... names)
{
- XMLInputFactory xif = theFactory();
- addQuiet(setFirstSupported(xif::setProperty, value,
- List.of(IllegalArgumentException.class),
- this::addSignaling, names));
+ addQuiet(tryFirstSupported(null, value, names));
return this;
}
@@ -5403,10 +5489,7 @@ public AdjustingStAXSource setFirstSupportedFeature(
public AdjustingStAXSource setFirstSupportedProperty(
Object value, String... names)
{
- XMLInputFactory xif = theFactory();
- addQuiet(setFirstSupported(xif::setProperty, value,
- List.of(IllegalArgumentException.class),
- this::addSignaling, names));
+ addQuiet(tryFirstSupported(null, value, names));
return this;
}
}
@@ -5476,10 +5559,21 @@ public DOMSource get() throws SQLException
}
Exception e = exceptions();
- if ( null != e )
- throw normalizedException(e);
- return ds;
+ if ( null == e )
+ return ds;
+
+ /*
+ * If changing these wrapping conventions, change them also in
+ * XMLCopier.saxCopy()
+ */
+ if ( e instanceof SAXException )
+ throw new SQLDataException(e.getMessage(), "22000", e);
+
+ if ( e instanceof IOException )
+ throw new SQLException(e.getMessage(), "58030", e);
+
+ throw normalizedException(e);
}
@Override
@@ -5504,13 +5598,36 @@ public AdjustingDOMSource expandEntityReferences(boolean v)
}
@Override
- public AdjustingDOMSource setFirstSupportedFeature(
- boolean value, String... names)
+ protected Exception tryFirstSupportedFeature(
+ Exception caught, boolean value, String... names)
{
DocumentBuilderFactory dbf = theFactory();
- addQuiet(setFirstSupported(dbf::setFeature, value,
+ return setFirstSupported(dbf::setFeature, value,
List.of(ParserConfigurationException.class),
- this::addSignaling, names));
+ caught, this::addSignaling, names);
+ }
+
+ @Override
+ protected Exception tryFirstSupportedProperty(
+ Exception caught, Object value, String... names)
+ {
+ DocumentBuilderFactory dbf = theFactory();
+ return setFirstSupported(dbf::setAttribute, value,
+ List.of(IllegalArgumentException.class),
+ caught, this::addSignaling, names);
+ }
+
+ @Override
+ protected AdjustingDOMSource self()
+ {
+ return this;
+ }
+
+ @Override
+ public AdjustingDOMSource setFirstSupportedFeature(
+ boolean value, String... names)
+ {
+ addQuiet(tryFirstSupportedFeature(null, value, names));
return this;
}
@@ -5518,10 +5635,7 @@ public AdjustingDOMSource setFirstSupportedFeature(
public AdjustingDOMSource setFirstSupportedProperty(
Object value, String... names)
{
- DocumentBuilderFactory dbf = theFactory();
- addQuiet(setFirstSupported(dbf::setAttribute, value,
- List.of(IllegalArgumentException.class),
- this::addSignaling, names));
+ addQuiet(tryFirstSupportedProperty(null, value, names));
return this;
}
diff --git a/pom.xml b/pom.xml
index 5a883ab72..1063d27db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,7 +39,7 @@
https://www.postgresql.org/list/pljava-dev/
https://web.archive.org/web/*/http://lists.pgfoundry.org/pipermail/pljava-dev/
- gmane.comp.db.postgresql.pljava on news.gmane.io
+ news://news.gmane.io/gmane.comp.db.postgresql.pljava
@@ -70,45 +70,20 @@
- nashorngone
+ nashornmod
[15,)
-
- org.codehaus.mojo
- properties-maven-plugin
- 1.0.0
-
-
- initialize
-
- set-system-properties
-
-
-
-
- true
-
-
-
-
-
-
org.apache.maven.plugins
maven-antrun-plugin
- org.graalvm.js
- js
- 20.1.0
-
-
- org.graalvm.js
- js-scriptengine
- 20.1.0
+ org.openjdk.nashorn
+ nashorn-core
+ 15.4
@@ -132,17 +107,17 @@
org.apache.maven.plugins
maven-install-plugin
- 2.5.2
+ 3.1.0
org.apache.maven.plugins
maven-resources-plugin
- 3.0.1
+ 3.3.0
org.apache.maven.plugins
maven-compiler-plugin
- 3.8.1
+ 3.10.1
@@ -152,7 +127,7 @@
maven-compiler-plugin
${project.build.sourceEncoding}
- 9
+ 9
true
true
@@ -160,24 +135,17 @@
org.apache.maven.plugins
maven-jar-plugin
- 3.0.2
+ 3.3.0
org.apache.maven.plugins
maven-surefire-plugin
- 3.0.0-M4
+ 3.0.0-M7
org.apache.maven.plugins
maven-site-plugin
- 3.9.1
-
-
- net.trajano.wagon
- wagon-git
- 2.0.4
-
-
+ 3.12.1
false
@@ -197,7 +165,7 @@
org.apache.maven.plugins
maven-project-info-reports-plugin
- 3.1.0
+ 3.4.5
diff --git a/src/site/markdown/build/freebsd.md b/src/site/markdown/build/freebsd.md
index 7995f7d19..613650e05 100644
--- a/src/site/markdown/build/freebsd.md
+++ b/src/site/markdown/build/freebsd.md
@@ -1,23 +1,7 @@
# Building on FreeBSD
-At one time, [FreeBSD][]'s threading library would malfunction if it was
-dynamically loaded after the start of a program that did not use threads
-itself. That was a problem for PL/Java on FreeBSD, because PostgreSQL
-itself does not use threads, but Java does. The only known workaround was
-to build PostgreSQL itself from source, with the thread library included
-in linking.
-
-The same problem was [reported to affect other PostgreSQL extensions][rep]
-such as `plv8` and `imcs` also.
-
-The [manual page for FreeBSD's libthr][manthr] was edited
-[in February 2015][thrdif] to remove the statement of that limitation,
-and the updated manual page appears first in [FreeBSD 10.2][rel102],
-so in FreeBSD 10.2 or later, PL/Java (and other affected extensions)
-may work without the need to build PostgreSQL from source.
+Building on [FreeBSD][] should proceed just as it does on Linux,
+as of late 2023, according to Achilleos Mantzios, who provided the patch
+adding the necessary build rules.
[FreeBSD]: https://www.freebsd.org/
-[rep]: https://lists.freebsd.org/pipermail/freebsd-hackers/2014-April/044961.html
-[manthr]: https://www.freebsd.org/cgi/man.cgi?query=libthr&apropos=0&sektion=3&manpath=FreeBSD+10.2-RELEASE&arch=default&format=html
-[thrdif]: https://svnweb.freebsd.org/base/head/lib/libthr/libthr.3?r1=272153&r2=278627
-[rel102]: https://www.freebsd.org/releases/10.2R/announce.html
diff --git a/src/site/markdown/build/versions.md b/src/site/markdown/build/versions.md
index 75a10ef16..c6dc83c2f 100644
--- a/src/site/markdown/build/versions.md
+++ b/src/site/markdown/build/versions.md
@@ -1,6 +1,6 @@
# Versions of external packages needed to build and use PL/Java
-As of mid-2023, the following version constraints are known.
+As of spring 2024, the following version constraints are known.
## Java
@@ -67,6 +67,6 @@ The PL/Java 1.6 series does not support PostgreSQL earlier than 9.5.
More current PostgreSQL versions, naturally, are the focus of development
and receive more attention in testing.
-PL/Java 1.6.6 has been successfully built and run on at least one platform
+PL/Java 1.6.7 has been successfully built and run on at least one platform
with PostgreSQL versions from 16 to 9.5, the latest maintenance
release for each.
diff --git a/src/site/markdown/develop/node.md b/src/site/markdown/develop/node.md
index ae647da14..aaf13e9d4 100644
--- a/src/site/markdown/develop/node.md
+++ b/src/site/markdown/develop/node.md
@@ -20,12 +20,18 @@ project's repository, as a way to keep as much as possible of the testing code
common across platforms.
The overall flavor, and even some of the method names, follow the `PostgresNode`
-Perl module that has been part of PostgreSQL's "PGXS" extension-building tools
-since 2015, so a quick review of that follows.
+Perl module that became part of PostgreSQL's "PGXS" extension-building tools
+in 2015, so a quick review of that follows.
-## Similarities to PostgreSQL's `PostgresNode` Perl module
+For PostgreSQL 15, the module distributed with PostgreSQL was renamed from
+`PostgresNode` to `PostgreSQL::Test::Cluster`, with no essential change in
+functionality (though `get_new_node` did become, simply, `new`). To avoid
+needless churn, this Java class still has the historical name and methods.
-When used from a testing script written in Perl, the methods of `PostgresNode`
+## Similarities to the upstream `PostgreSQL::Test::Cluster` Perl module
+
+When used from a testing script written in Perl, the methods of
+`PostgreSQL::Test::Cluster`
make it easy to spin up and tear down one or more PostgreSQL instances, running
in temporary directories, listening on temporary ports, non-interfering with
each other or with production instances using the standard locations and ports,
@@ -41,7 +47,7 @@ $n1->stop(); # stop the server
$n1->clean_node(); # recursively delete the temporary location
```
-`PostgresNode.pm` illustrates the immense utility of making just a few
+`PostgreSQL::Test::Cluster` illustrates the immense utility of making just a few
well-chosen methods available, when there is already an expressive scripting
language at hand (Perl) for putting those methods to use.
@@ -65,9 +71,10 @@ n1.clean_node()
```
`jshell` has to be run with a rather lengthy command line to get to this point;
-more on that later. But once started, it presents a familiar `PostgresNode`-like
+more on that later. But once started, it presents a familiar
+`PostgreSQL::Test::Cluster`-like
environment. As the example shows, `jshell` is lenient about statement-ending
-semicolons. (It is still advisable to use them, though; that leniency has fiddly
+semicolons. (Using them is still advisable, though; that leniency has fiddly
exceptions, such as not applying to pasted text.)
## `Node.class` in detail
diff --git a/src/site/markdown/releasenotes.md.vm b/src/site/markdown/releasenotes.md.vm
index a8a1c46c6..74dddd8c5 100644
--- a/src/site/markdown/releasenotes.md.vm
+++ b/src/site/markdown/releasenotes.md.vm
@@ -10,6 +10,89 @@
#set($ghbug = 'https://github.com/tada/pljava/issues/')
#set($ghpull = 'https://github.com/tada/pljava/pull/')
+$h2 PL/Java 1.6.7
+
+This is the seventh minor update in the PL/Java 1.6 series. It adds support
+for FreeBSD and for building and running with Java 22, and fixes some bugs,
+with few other notable changes. Further information on the changes may be found
+below.
+
+$h3 Version compatibility
+
+PL/Java 1.6.7 can be built against recent PostgreSQL versions including 16, and
+older ones back to 9.5, using Java SE 9 or later. The Java version used at
+runtime does not have to be the same version used for building. PL/Java itself
+can run on any Java version 9 or later. PL/Java functions can be
+written for, and use features of, whatever Java version will be loaded at run
+time. See [version compatibility][versions] for more detail.
+
+Some builds of Java 20 are affected by a bug, [JDK-8309515][]. PL/Java will
+report an error if detects it is affected by that bug, and the solution can be
+to use a Java version earlier than 20, or one recent enough to have the bug
+fixed. The bug has been fixed in Java 21.
+
+$h3 Changes
+
+$h4 Changes in XML support
+
+$h5 Java 22's new XML property to control DTD processing is supported
+
+Java 22 introduces a new property, `jdk.xml.dtd.support`, which can take values
+`allow`, `deny`, and `ignore`.
+
+The values `allow` and `deny` provide a new way to specify behavior that could
+already be requested by other means, and the `allowDTD(boolean)` method of
+PL/Java's `Adjusting.XML` API now tries this property first, falling back to the
+older means on Java releases that do not support it.
+
+The value `ignore` offers a previously-unavailable behavior where an XML
+document with a DTD can be successfully parsed but with its DTD ignored. A new
+method `ignoreDTD()` is added to the `Adjusting.XML` API to request this
+treatment, and will only succeed on Java 22 or later. The last-invoked of this
+method and `allowDTD(boolean)` will govern.
+
+In Java 22, bug [JDK-8329295][] can cause parsing to fail when `ignoreDTD` is in
+effect, if the document has only a minimal DTD and the SAX or DOM API is used.
+
+$h4 Build system
+
+The build logic that is implemented in JavaScript is now executed using the
+Nashorn engine, either included with Java through release 14, or downloaded
+by Maven for Java 15 and later. The build system was formerly downloading the
+JavaScript engine from GraalVM to build on Java 15 and later, but a new version
+of that engine needed for Java 22 would have complicated version management.
+
+Versions of some Maven plugins used at build time
+[have been updated](${ghpull}468) where critical vulnerabilities were reported.
+
+$h3 Enhancement requests addressed
+
+* [Build on FreeBSD](${ghpull}478)
+* [Vulnerable Maven plugins used at build time](${ghbug}449)
+
+$h3 Bugs fixed
+
+* ["PostgreSQL backend function after an elog(ERROR)" in class loading](${ghbug}471)
+* [XML parsing errors reported as XX000 when DOM API is used](${ghbug}481)
+
+$h3 Credits
+
+Thanks in release 1.6.7 to Francisco Miguel Biete Banon, Bear Giles, Achilleas
+Mantzios, `hunterpayne`, `kamillo`.
+
+[JDK-8329295]: https://bugs.openjdk.org/browse/JDK-8329295
+
+$h2 Earlier releases
+
+## A nice thing about using Velocity is that each release can be entered at
+## birth using h2 as its main heading, h3 and below within ... and then, when
+## it is moved under 'earlier releases', just define those variables to be
+## one heading level finer. Here goes:
+#set($h2 = '###')
+#set($h3 = '####')
+#set($h4 = '#####')
+#set($h5 = '######')
+
$h2 PL/Java 1.6.6
This is the sixth minor update in the PL/Java 1.6 series. It adds support
@@ -95,17 +178,6 @@ $h3 Bugs fixed
[adjsfs]: pljava-api/apidocs/org.postgresql.pljava/org/postgresql/pljava/Adjusting.XML.html#method.detail
[egsfs]: https://github.com/tada/pljava/blob/V1_6_6/pljava-examples/src/main/java/org/postgresql/pljava/example/annotation/PassXML.java#L528
-$h2 Earlier releases
-
-## A nice thing about using Velocity is that each release can be entered at
-## birth using h2 as its main heading, h3 and below within ... and then, when
-## it is moved under 'earlier releases', just define those variables to be
-## one heading level finer. Here goes:
-#set($h2 = '###')
-#set($h3 = '####')
-#set($h4 = '#####')
-#set($h5 = '######')
-
$h2 PL/Java 1.6.5
This is the fifth minor update in the PL/Java 1.6 series. It adds support
diff --git a/src/site/markdown/use/policy.md b/src/site/markdown/use/policy.md
index 566743c49..9d0e3f800 100644
--- a/src/site/markdown/use/policy.md
+++ b/src/site/markdown/use/policy.md
@@ -372,11 +372,16 @@ release, so relying on it is not recommended.
The developers of Java have elected to phase out important language features
used by PL/Java to enforce policy. The changes will come in releases after
-Java 17. For migration planning, Java versions up to and including 17
-remain fully usable with this version of PL/Java, and Java 17
-is positioned as a long-term support release. For details on
-how PL/Java will adapt, please bookmark [the JEP 411 topic][jep411]
-on the PL/Java wiki.
+Java 17. For migration planning, this version of PL/Java can still enable
+policy enforcement in Java versions up to and including 22, and Java 17 and 21
+are positioned as long-term support releases. (There is a likelihood,
+increasing with later Java versions, even before policy stops being enforceable,
+that some internal privileged operations by Java itself, or other libraries,
+will cease to work transparently, and may have to be manually added to a site's
+PL/Java policy.)
+
+For details on how PL/Java will adapt, please bookmark
+[the JEP 411 topic][jep411] on the PL/Java wiki.
[pfsyn]: https://docs.oracle.com/en/java/javase/14/security/permissions-jdk1.html#GUID-7942E6F8-8AAB-4404-9FE9-E08DD6FFCFFA
diff --git a/src/site/markdown/use/sqlxml.md b/src/site/markdown/use/sqlxml.md
index c766cfd6d..1c4f5de34 100644
--- a/src/site/markdown/use/sqlxml.md
+++ b/src/site/markdown/use/sqlxml.md
@@ -419,6 +419,12 @@ only existing methods for setting features/properties, as described
`setFirstSupportedFeature` and `setFirstSupportedProperty` methods
in PL/Java's `Adjusting` API.
+When running on Java 22 or later, there is also a fallback catalog that can
+satisfy requests for a small number of DTDs that are defined by the Java
+platform. The behavior when this fallback resolver cannot satisfy a request
+can be configured by setting the `jdk.xml.jdkcatalog.resolve` property, for
+which, again, the `setFirstSupportedProperty` method can be used.
+
### Extended API to set the content of a PL/Java `SQLXML` instance
When a `SQLXML` instance is returned from a PL/Java function, or passed in to