Release notes

PL/Java 1.6.2

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.


Bug blocking use from an unprivileged PostgreSQL role fixed

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.

Trial security policy for migrating code from PL/Java pre-1.6.0

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.

Example functions using XSLT 1.0 polished for simpler use

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.

Bugs fixed


Thanks to Francisco Biete for the report of #331.

Earlier releases

PL/Java 1.6.1 (16 November 2020)

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.


Limitations when built with Java 10 or 11 removed

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.

Functions with OUT parameters

PL/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.

Generation of aggregate, cast, and operator declarations

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.

Bugs fixed


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.

PL/Java 1.6.0 (18 October 2020)

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.

Version compatibility

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.


New configurable permissions may require configuration

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 or 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.

Validation at CREATE FUNCTION time may force changes to deployment procedures

PL/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.

Java 9 module system; 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.

Improvements to the annotation-driven SQL generator
Infers additional implicit ordering dependencies

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).

Generates variadic function declarations

PL/Java 1.6 can declare functions that can be called from SQL with varying numbers of arguments. Example code is provided.

Better support for PostgreSQL’s SQL_ASCII encoding

PostgreSQL’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.

Build system, continuous integration, quality assurance
  • 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.

Enhancement requests addressed

Bugs fixed

Updated PostgreSQL APIs tracked

  • 64-bit 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.

Releases prior to PL/Java 1.6.0