This is the fourth minor update in the PL/Java 1.6 series. It is a minor bug-fix release with few other notable changes. Further information on the changes may be found below.
PL/Java follows certain administrative actions with an advisory message about upcoming Java changes that will affect policy enforcement. In 1.6.3, that message was always at WARNING
level. In 1.6.4, it is downgraded to NOTICE
level when running on Java versions before 17.
As before, updates on how PL/Java will adapt to the future Java changes can be watched by bookmarking the JEP 411 topic on the PL/Java wiki.
Starting in 1.6.3, PL/Java has made sure the thread context class loader on entry to a function reflects the initiating loader for the implementing class, but in 1.6.3, the loader could be set too many times when executing a set-returning function. That could lead to the wrong loader being restored on function exit, likely only noticeable in an application with jars in multiple schemas and with nested Java function invocations.
That is fixed in this release.
OUT
parameterPostgreSQL requires a different form of declaration for a function with one OUT
parameter than for a function with two or more. PL/Java was emitting the wrong form for the one-out-parameter case.
The documentation has been clarified and new examples added to illustrate how Java methods should be structured and annotated for both cases.
The intended treatment can be ambiguous for some Java methods, without explicit annotations. For example, a Java method that returns boolean
and has a trailing ResultSet
parameter could be a single-row composite-returning function, or an ordinary function with a row-typed input parameter and boolean
return. PL/Java has always silently chosen which interpretation to apply in such cases, and still does, but it now emits a comment into the generated deployment descriptor, explaining what annotation to use if a different meaning was intended.
BaseUDT
annotation now has constants for known type categoriesPostgreSQL user-defined types can be declared in categories, some of which are predefined. PL/Java’s BaseUDT
annotation now includes constants for those, which can be used in place of the single-letter codes for readability.
This is the third minor update in the PL/Java 1.6 series. It adds support for PostgreSQL 14, continues to improve the runtime behavior and the annotation-driven SQL generator, and fixes several bugs. Further information on the changes may be found below.
Current versions of PL/Java rely on Java security features that will be affected by JEP 411, beginning with Java 17. Java 17 itself will continue to provide the needed capabilities, with only deprecation marks and warnings added. Java 17 is also positioned as a long-term support release, so the option of continuing to run this PL/Java release will be available, with no loss of function, by continuing to run with Java versions up to and including 17.
For more on how PL/Java will adapt, please bookmark the JEP 411 topic on the PL/Java wiki.
For this release, PL/Java will suppress a JEP 411-related warning from the Java runtime itself that would otherwise be emitted for every PostgreSQL backend that starts Java, and instead will issue a more informative “migration advisory” warning only on certain administrative actions no more than once per session, with a goal of ensuring that responsible administrators are aware of the expected future developments. The advisory message includes the URL to the wiki topic above.
This release also adds code to detect if it is on a future, post-Java 17 runtime where the needed functionality is not available, and throw informative exceptions with suggested corrective actions.
The new SQLJ.ALIAS_JAVA_LANGUAGE
function introduced with 1.6 will now be present after an ALTER EXTENSION UPDATE
if it was not before.
The Java runtime can behave antisocially for some startup issues, such as a misspelled jar in pljava.module_path
, and silently terminate the backend process rather than reporting an error. (It writes a message, not to standard error, but to standard output, which from a PostgreSQL backend is not captured for logging, and may never be seen.) A message is now generated in that case, to provide at least some clue what has gone wrong.
PL/Java now supplies a known value for the current Java thread’s context class loader on entry to a PL/Java function. It is the class loader for the PostgreSQL schema where the function is declared. The context class loader is referred to by numerous Java libraries and by Java’s ServiceLoader
class, which may expect to find services and resources along the PL/Java class path that has been configured for the function. Neglecting to set the context class loader opened the door to unexpected loading failures like issue #361 that can require awkward or slow contortions to work around in user Java code.
This change is documented in more detail. An opt-out setting is available.
It has been possible to annotate a function parameter with @SQLType(defaultValue=...)
to give it any non-null default value, but because Java disallows null annotation values, that notation wasn’t usable to declare a parameter that defaults to null. The new notation @SQLType(optional=true)
means exactly that.
COMMUTATOR
/NEGATOR
operatorsIt is now possible to code one method in Java and declare a full complement of operators based on it by combining commutation and negation. A new example is provided.
ALTER EXTENSION UPDATE
does not create sqlj.alias_java_language
pg_config
outputpljava.module_path
is incorrectpg_upgrade
Lexicals.Identifier
serializationautovacuum
java.nio.charset.MalformedInputException: Input length = 1
MappedUDT
and types with typlen=-2
pg_type
OID symbolsErrorData.show_funcname
(it was a vestige of frontend/backend protocol v2, long obsolete)Thanks to Krzysztof Nienartowicz, ricdhen
, and JanaParthasarathy
, who among them reported five of the issues fixed in this release.
This is the second minor update in the PL/Java 1.6 series, with two bugs fixed (including one that was likely to be a blocker for many applications). It adds a ‘trial’ security policy, useful when migrating code from PL/Java 1.5 to identify permission grants that may be needed, and some minor but useful example functionality.
In 1.6.0 and 1.6.1, PL/Java could fail to start in a backend process if the effective PostgreSQL role was not a superuser or a member of pg_read_all_settings
. That is fixed in this release.
When migrating code from pre-1.6.0 PL/Java versions, it may be necessary to add permission grants to the PL/Java 1.6 security policy, which is distributed as a minimal starting point.
Configuring permissions in PL/Java covers the topic in general, and Migrating to policy-based permissions covers the new ‘trial’ policy introduced in 1.6.2 to simplify the process.
Although 1.0 is obsolete and very limited compared to current versions of XSLT, the implementation in Java has two attractive properties. First, it is provided in the Java runtime with no need of a separate download such as Saxon, and second, it allows use of any accessible Java methods or constructors from XPath expressions, which can often make it more useful than the limitations of strict XSLT 1.0 would suggest.
The example functions prepareXMLTransform
, prepareXMLTransformWithJava
, and transformXML
, which demonstrate how such functions can be coded, have also been given streamlined parameter lists with defaults to make them simple to use for real work.
One small but useful result is an easy way to indent XML for readability, simply by passing a null transform name and indent => true
to transformXML
.
Thanks to Francisco Biete for the report of #331.
Note: 1.6.1 was released with a bug likely to be a blocker for many applications. It was fixed in 1.6.2.
This is the first minor update in the PL/Java 1.6 series, with two bugs fixed. It also adds functionality in the SQL generator, allowing automated declaration of new PostgreSQL aggregates, casts, and operators, and functions with OUT
parameters.
PL/Java can now be built with any Java 9 or later (latest tested is 15 at time of writing), and the built artifact can use any Java 9 or later at run time (as selected by the pljava.libjvm_location
configuration variable).
That was previously true when built with Java 9 or with Java 12 or later, but not when built with 10 (would not run on 9) or with 11 (would not run on 9 or 10). Those limits have been removed.
OUT
parametersPL/Java has long been able to declare a function that returns a composite type (or a set of such), by returning a named composite PostgreSQL type, or by being declared to return RECORD
.
The former approach requires separately declaring a new composite type to PostgreSQL so it can be named as the function return. The RECORD
approach does not require pre-declaring a type, but requires every caller of the function to supply a column definition list at the call site.
Declaring the function with OUT
parameters offers a middle ground, where the function has a fixed composite return type with known member names and types, callers do not need to supply a column definition list, and no separate declaration of the type is needed.
There is no change to how such a function is coded at the Java source level; the new annotation element only changes the SQL generated to declare the function to PostgreSQL. Examples are provided.
The SQL generator now recognizes @Aggregate
, @Cast
, and @Operator
annotations, generating the corresponding SQL deploy/undeploy scripts. Some examples (for aggregates, casts, and operators) are provided. The reduction in boilerplate needed for a realistically-complete example can be seen in this comparison of Bear Giles’s pljava-udt-type-extension
example; the two branches compared here are (1) using only the annotations supported in PL/Java 1.6.0 and (2) using also the new support in 1.6.1.
Thanks to Bear Giles for the pljava-udt-type-extension
example, which not only illustrates the SQL generation improvements in this release, but also exposed both of the bugs fixed here.
Note: 1.6.0 was released with a bug likely to be a blocker for many applications. It was fixed in 1.6.2.
This is the first release of a significantly refactored PL/Java 1.6 branch with a number of new features and changes. It requires Java 9 or later at build and run time, but retains the ability to run PL/Java application code built for earlier versions. It should be used with PostgreSQL 9.5 or later. For applications requiring an older Java or PostgreSQL version, the latest release in the PL/Java 1.5 line remains an option.
Note to package maintainers: these release notes should be reviewed before an installation moves to 1.6.0 from a 1.5 or earlier version, so it is best packaged in a way that requires an affirmative choice to upgrade.
PL/Java 1.6.0 can be built against recent PostgreSQL versions including 13, 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 if built with Java 9 or with 12 or later (bugs in the Java 10 and 11 compilers prevent running on 9 if built with 10, or on 9 or 10 if built with 11). 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.
When used with GraalVM as the runtime VM, PL/Java functions can use Graal’s “polyglot” capabilities to execute code in any other language available on GraalVM. In this release, it is not yet possible to directly declare a function in a language other than Java.
If building with GraalVM, please add -Dpolyglot.js.nashorn-compat=true
on the mvn
command line.
Prior to 1.6.0, PL/Java hard-coded the permissions that were available to functions declared in the ‘trusted’ language java
or the ‘untrusted’ language javaU
. With 1.6.0, the exact permissions available for both cases can be configured in the pljava.policy
file (found in the directory reported by pg_config --sysconfdir
) as described in the new policy documentation.
Java’s policy language can conditionally grant permissions but not deny them if another clause grants them. Therefore, the default policy must be somewhat restrictive, so a desired policy can be built from it with grant clauses.
In the 1.6.0 default policy, ‘trusted’ (java
) code has minimal permissions, suitable for general computation and interacting with the database, and ‘untrusted’ (javaU
) code has only the additional permission to access the file system. Existing user functions that worked in PL/Java 1.5.x and performed other actions, such as making network connections, will need the appropriate permissions (such as java.net.URLPermission
or java.net.SocketPermission
) granted via the policy file.
The policy can grant permissions more selectively than just to java
or javaU
. The new documentation covers the details, and also how to log, for troubleshooting purposes, the permissions being requested.
Whatever the reason, all down the years, a favorite “is PL/Java working?” check found online has been to read a Java system property with System.getProperty
. Not all of those examples pick properties that can be read under the default policy. So, even some familiar habits like that may need revision, at least to use a property like java.version
that is readable by default.
The former hard-coded permissions were by turns too lax or too strict, depending on what was needed, and interfered in some cases with the operation of the Java runtime itself, breaking (at least) its XSLT implementation and the profiling functions of visualvm
. This release fixes those issues.
CREATE FUNCTION
time may force changes to deployment proceduresPL/Java can now detect problems with a function declaration, including missing dependencies, at the time of CREATE FUNCTION
, rather than allowing the function to be created and reporting failure later when it is called.
This change may have an impact on some established procedures. For example, when installing a jar that contains deployment commands, deployment may fail if another required jar has not been installed and added to the class path first; in the past, the order did not matter. For details, see this section in the documentation for the supplied examples, and the description of check_function_bodies
in the configuration variable reference.
pljava.classpath
-> pljava.module_path
Because PL/Java itself is now modular code conforming to the module system introduced with Java 9, one configuration variable has changed: pljava.classpath
is now pljava.module_path
.
As before, its default value will be correct when PL/Java is installed to the usual locations. It should be rare for any installation to have needed to think about the old one, or to need to think about the new one. For a rare installation that does, the details are in the documentation.
In this release, user code is not treated as modular; the SQLJ.INSTALL_JAR
routine still treats its jars as unnamed-module code on a class path, as before.
The SQL generator can now respect the implicit ordering constraints among user-defined types and functions that either use the types or are used in their definitions, which can eliminate many provides
/requires
annotation elements that had to be added by hand for PL/Java 1.5. The reduction in boilerplate needed for a realistic example can be seen by comparing the annotated version of Bear Giles’s pljava-udt-type-extension
example at this commit (pre-1.6) and this one (1.6.0).
PL/Java 1.6 can declare functions that can be called from SQL with varying numbers of arguments. Example code is provided.
SQL_ASCII
encodingPostgreSQL’s legacy SQL_ASCII
encoding is difficult to use in Java because 128 of its code points have no defined mapping to Unicode, which Java uses. The page on database character set encodings has a section suggesting workable approaches if PL/Java is used in a database with that encoding. A new addition among those options is a Java Charset
supporting the encoding names X-PGSQL_ASCII
or SQL_ASCII
, which maps the ASCII characters as expected, and reversibly encodes the others using Unicode permanently-undefined codepoints.
The nar-maven-plugin
formerly used in the build has been replaced with a newly-developed Maven plugin tailored to PostgreSQL extension building.
The new plugin respects the flags reported by pg_config
when building the native library.
Building with the same flags used for PostgreSQL has eliminated the flood of uninformative warnings that, in prior versions, made troubleshooting actual build problems difficult.
Travis-CI and AppVeyor now regularly build and test PL/Java for Linux (x86_64 and ppc64le), Mac OS, and Windows (using MSVC and MinGW-w64), with results visible at GitHub.
PL/Java’s self-installer jar now includes utilities to simplify integration testing, similar to the PostgresNode
Perl module provided with PostgreSQL. It is used in the Travis and AppVeyor builds to keep platform-specific code to a minimum, and may be useful for other purposes. Some documentation is included.
Having fixed the permission issues that were breaking the profiling functions of visualvm
, it will be easier to incorporate profiling into future development.
FuncCallContext.call_cntr
(ResultSetProvider
/ResultSetHandle
can now return more than INT_MAX
rows)There is a PL/Java 1.6.0 thanks in part to Christoph Berg, Chapman Flack, Kartik Ohri, original creator Thomas Hallgren, and the many contributors to earlier versions.
The work of Kartik Ohri in summer 2020 on the build system renovation and continuous integration was supported by Google Summer of Code.