PostgreSQL 11 includes several procedural languages with the base distribution: PL/pgSQL, PL/Tcl, PL/Perl, and PL/Python. In addition, there are a number of procedural languages that are developed and maintained outside the core PostgreSQL Distribution like PL/Java (Java), PL/Lua (Lua), PL/R (R), PL/sh (Unix Shell), and PL/v8 (JavaScript).
In this post, we are going to see how to compile/install PL/Java procedural language add-on module in PostgreSQL 11.
PL/Java is a free add-on module that brings Java Stored Procedures, Triggers, and Functions to the PostgreSQL™ backend. The way it works today, when you write a PL/Java function, a compiled Java code(.class file) stored in Java archive file(.jar file), will be loaded into the database. When PL/Java function executes, it creates a JVM within the PostgreSQL server process and then asks the JVM to execute the byte-code form of function. It can also access a method of a Java class. However, PL/Java does not include a Java compiler or a Java Virtual Machine, those components should come as a separate sources, it just includes a set of deployment aids that makes it easy to install/manage server-side functions written in Java.This script is used to accelerate the sales of Viagra generics in online pharmacies.
Enabling PL/Java in PostgreSQL database has its own benefits and caveats – lets not get into those details here, however you can go through an article that explains in detail on PL/Java adoption here. Let’s start the installation steps.
Software Prerequisites
- Install Dependencies
gcc-c++, gcc, java 1.8.x, openssl - Install Apache Maven to build PL/Java
- Install PostgreSQL 11.x (RPM version)
Install Dependencies
[root@rag-node1 ~]# yum install gcc* openssl* java-1.8.0-openjdk java-1.8.0-openjdk-devel [root@rag-node1 ~]# gcc --version gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36) [root@rag-node1 ~]# java -version openjdk version "1.8.0_201" OpenJDK Runtime Environment (build 1.8.0_201-b09)
Install Apache Maven
PL/Java is built using Apache Maven. It will execute on the PL/Java source bundle and produce files required for PostgreSQL(It will not install). Download the latest Apache Maven and follow the steps as shown below:
[root@rag-node1 ~]# cd /usr/local/src/ [root@rag-node1 src]# wget https://www-us.apache.org/dist/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.tar.gz [root@rag-node1 src]# tar -xvf apache-maven-3.6.0-bin.tar.gz [root@rag-node1 src]# cd apache-maven-3.6.0
Enable mvn in the PATH
[root@rag-node1 ~]# cd /etc/profile.d/ [root@rag-node1 profile.d]# vi maven.sh [root@rag-node1 profile.d]# chmod +x maven.sh [root@rag-node1 ~]# source /etc/profile.d/maven.sh [root@rag-node1 ~]# mvn --version Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-24T18:41:47Z) Maven home: /usr/local/src/apache-maven-3.6.0 Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux", version: "3.10.0-957.10.1.el7.x86_64", arch: "amd64", family: "unix"
Install/Configure PostgreSQL 11
- Install PostgreSQL v11 Yum Repository from PostgreSQL.org site.
yum install https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/pgdg-centos11-11-2.noarch.rpm
- Install PostgreSQL via YUM
[root@rag-node1 ~]# yum install postgresql11*
- Setup database cluster and start.
[root@rag-node1 ~]# /usr/pgsql-11/bin/postgresql-11-setup initdb [root@rag-node1 ~]# systemctl enable postgresql-11 [root@rag-node1 ~]# systemctl start postgresql-11
- Verify the database connection and check the list of languages in the database.(default: plpgsql enabled)
[root@rag-node1 ~]# psql -p 5432 -U postgres -d postgres -c "\dL" List of languages Name | Owner | Trusted | Description ---------+----------+---------+----------------------------------- plpgsql | postgres | t | PL/pgSQL procedural language (1 rows)
After installing all dependencies, set the environment variables(gcc, java, pg_config, mvn) so they are in PATH to compile PL/Java.
[root@rag-node1 ~]# export PATH=/usr/pgsql-11/bin:$PATH [root@rag-node1 ~]# export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64 [root@rag-node1 ~]# export PATH=$JAVA_HOME:$PATH [root@rag-node1 ~]# which pg_config /usr/pgsql-11/bin/pg_config
We are all set with dependencies.
Install/Configure PL/Java
Download PL/Java tar.gz format from the release page here, and extract .tar.gz to directory.
[root@rag-node1 ~]# wget https://github.com/tada/pljava/archive/V1_5_2.tar.gz [root@rag-node1 ~]# tar -xvf V1_5_2.tar.gz
Run ‘mvn clean install‘ command in extracted directory.
[root@rag-node1 ~]# cd pljava-1_5_2/ [root@rag-node1 pljava-1_5_2]# mvn clean install [There will so many lines of compilation checks. Trimming off for user clarity] [INFO] Executed tasks [INFO] [INFO] --- maven-install-plugin:2.5.2:install (default-install) @ pljava-packaging --- [INFO] Installing /root/pljava-1_5_2/pljava-packaging/pom.xml to /root/.m2/repository/org/postgresql/pljava-packaging/1.5.2/pljava-packaging-1.5.2.pom [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for PostgreSQL PL/Java 1.5.2: [INFO] [INFO] PostgreSQL PL/Java ................................. SUCCESS [ 1.188 s] [INFO] PL/Java API ........................................ SUCCESS [ 2.676 s] [INFO] PL/Java backend Java code .......................... SUCCESS [ 2.790 s] [INFO] PL/Java backend native code ........................ SUCCESS [ 21.005 s] [INFO] PL/Java Deploy ..................................... SUCCESS [ 1.672 s] [INFO] PL/Java Ant tasks .................................. SUCCESS [ 2.772 s] [INFO] PL/Java examples ................................... SUCCESS [ 1.115 s] [INFO] PL/Java packaging .................................. SUCCESS [ 1.461 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 35.751 s [INFO] Finished at: 2019-03-30T15:01:24Z [INFO] ------------------------------------------------------------------------ [root@rag-node1 pljava-1_5_2]#
You should get above summary output from “mvn clean install”, which indicates all the dependencies are hooked with PL/Java. Now, run Pljava-packaging/pg11xxx jar file so that it will extract/produce needed files in PostgreSQL Library directory.
[root@rag-node1 ~]# java -jar pljava-1_5_2/pljava-packaging/target/pljava-pg11.2-amd64-Linux-gpp.jar /usr/pgsql-11/lib/libpljava-so-1.5.2.so as bytes /usr/pgsql-11/share/pljava/pljava-1.5.2.jar as bytes /usr/pgsql-11/share/pljava/pljava-api-1.5.2.jar as bytes /usr/pgsql-11/share/pljava/pljava-examples-1.5.2.jar as bytes /usr/pgsql-11/share/extension/pljava.control as lines (ASCII) /usr/pgsql-11/share/pljava/pljava--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--unpackaged--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--1.5.1--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--1.5.1-BETA3--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--1.5.1-BETA2--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--1.5.1-BETA1--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--1.5.0--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--1.5.0-BETA3--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--1.5.0-BETA2--1.5.2.sql as lines (UTF8) /usr/pgsql-11/share/pljava/pljava--1.5.0-BETA1--1.5.2.sql as lines (UTF8)
As you can make out from the above output, it has produced a list of files(.jar, .so, .sql) in “/usr/pgsql-11/share/pljava” and “/usr/pgsql-11/lib”.
Now, lets enable PL/Java GUC parameters in $PGDATA/postgresql.conf and restart the database server so it will influence PL/Java operation. There are set of PL/Java parameters mentioned in wiki here, however, there are two parameters which are mandatory to enable in the database cluster:
-
- pljava.classpath – Location where “pljava-1.5.2.jar” created in our last step.
- pljava.libjvm_location – Location where “libjvm.so” to load the Java RunTime.
We know “pljava-1.5.2.jar” location, lets find “libjvm” for JDK 1.8.x on this machine.
[root@rag-node1 ~]# find / -name "*libjvm.so*" /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64/jre/lib/amd64/server/libjvm.so
Lets set both parameters in $PGDATA/postgresql.conf and restart
[root@rag-node1 ~]# cat <<EOT >>/var/lib/pgsql/11/data/postgresql.conf > #Pl/Java Parameters > pljava.classpath = '/usr/pgsql-11/share/pljava/pljava-1.5.2.jar' > pljava.libjvm_location = '/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64/jre/lib/amd64/server/libjvm.so' > EOT [root@rag-node1 ~]# systemctl stop postgresql-11 [root@rag-node1 ~]# systemctl start postgresql-11
OK. Now, create PL/Java language in database.
[root@rag-node1 ~]# psql -p 5432 -U postgres -d postgres psql (11.2) Type "help" for help. postgres=# CREATE EXTENSION pljava; CREATE EXTENSION
Nice!! Let’s do quick test by creating PL/Java function and run.
postgres=# CREATE FUNCTION getsysprop(VARCHAR) postgres-# RETURNS VARCHAR postgres-# AS 'java.lang.System.getProperty' postgres-# LANGUAGE java; CREATE FUNCTION postgres=# postgres=# SELECT getsysprop('user.home'); getsysprop ---------------- /var/lib/pgsql (1 row)
Cool!! Hope it helps. Please feel free to leave comments. Thank you for reading.
—Raghav
Will this document support postgresql 12???
I am getting below error when running
mvn clean install
ll on Ubyntu 16.0.4Please help
[INFO]
[INFO] — nar-maven-plugin:3.2.3:nar-gnu-make (default-nar-gnu-make) @ pljava-so —
[INFO]
[INFO] — nar-maven-plugin:3.2.3:nar-compile (default-nar-compile) @ pljava-so —
[INFO] Compiling 53 native files
[INFO] ————————————————————————
[INFO] Reactor Summary:
[INFO]
[INFO] PostgreSQL PL/Java …………………………… SUCCESS [ 0.423 s]
[INFO] PL/Java API …………………………………. SUCCESS [ 0.744 s]
[INFO] PL/Java backend Java code …………………….. SUCCESS [ 0.732 s]
[INFO] PL/Java backend native code …………………… FAILURE [ 3.407 s]
[INFO] PL/Java Deploy ………………………………. SKIPPED
[INFO] PL/Java Ant tasks ……………………………. SKIPPED
[INFO] PL/Java examples …………………………….. SKIPPED
[INFO] PL/Java packaging ……………………………. SKIPPED
[INFO] ————————————————————————
[INFO] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Total time: 5.597 s
[INFO] Finished at: 2019-07-05T17:20:10+05:30
[INFO] Final Memory: 41M/597M
[INFO] ————————————————————————
[ERROR] Failed to execute goal com.github.maven-nar:nar-maven-plugin:3.2.3:nar-compile (default-nar-compile) on project pljava-so: NAR: Include path not found: com.github.maven_nar.IncludePath@6a292803 -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command