pljava

PL/Java procedural language

Overview

PackageVersionCategoryLicenseLanguage
pljava1.6.10LANGBSD 3-ClauseJava
IDExtensionBinLibLoadCreateTrustRelocSchema
3090pljavaNoYesNoYesNoNosqlj
Relatedplpgsql plv8 plperl plpython3u pg_tle pllua plluau pltclu

missing debian/ubuntu pg18

Version

TypeRepoVersionPG VerPackageDeps
EXTPGDG1.6.101817161514pljava-
RPMPGDG1.6.101817161514pljava_$v-
DEBPGDG1.6.91817161514postgresql-$v-pljava-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64PGDG MISS
d12.aarch64PGDG MISS
PGDG 1.6.9
PGDG 1.6.9
PGDG 1.6.9
PGDG 1.6.9
d13.x86_64PGDG MISS
d13.aarch64PGDG MISS
PGDG 1.6.9
PGDG 1.6.9
PGDG 1.6.9
PGDG 1.6.9
u22.x86_64PGDG MISS
u22.aarch64PGDG MISS
u24.x86_64PGDG MISS
u24.aarch64PGDG MISS

Install

You can install pljava directly. First, make sure the PGDG repository is added and enabled:

pig repo add pgdg -u          # Add PGDG repo and update cache

Install the extension using pig or apt/yum/dnf:

pig install pljava;          # Install for current active PG version
pig ext install -y pljava -v 18  # PG 18
pig ext install -y pljava -v 17  # PG 17
pig ext install -y pljava -v 16  # PG 16
pig ext install -y pljava -v 15  # PG 15
pig ext install -y pljava -v 14  # PG 14
dnf install -y pljava_18       # PG 18
dnf install -y pljava_17       # PG 17
dnf install -y pljava_16       # PG 16
dnf install -y pljava_15       # PG 15
dnf install -y pljava_14       # PG 14
apt install -y postgresql-18-pljava   # PG 18
apt install -y postgresql-17-pljava   # PG 17
apt install -y postgresql-16-pljava   # PG 16
apt install -y postgresql-15-pljava   # PG 15
apt install -y postgresql-14-pljava   # PG 14

Create Extension:

CREATE EXTENSION pljava;

Usage

pljava: PL/Java procedural language

pljava enables writing PostgreSQL functions, triggers, and types in Java using the standard JDBC API.

CREATE EXTENSION pljava;

Deploy Java Code

Package your Java classes in a JAR file with an SQLJ deployment descriptor, then install it:

SELECT sqlj.install_jar('file:///path/to/my_functions.jar', 'myjar', true);
SELECT sqlj.set_classpath('public', 'myjar');

Create Functions

Write a Java class with static methods:

package com.example;

import org.postgresql.pljava.annotation.Function;

public class MyFunctions {
    @Function
    public static int add(int a, int b) {
        return a + b;
    }

    @Function
    public static String hello(String name) {
        return "Hello, " + name + "!";
    }
}

Declare the SQL function mapping:

CREATE FUNCTION add(int, int) RETURNS int
  AS 'com.example.MyFunctions.add'
  LANGUAGE java;

CREATE FUNCTION hello(varchar) RETURNS varchar
  AS 'com.example.MyFunctions.hello'
  LANGUAGE java;

Set-Returning Functions

Implement ResultSetProvider for set-returning functions:

import org.postgresql.pljava.ResultSetProvider;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MySetFunction implements ResultSetProvider {
    public boolean assignRowValues(ResultSet receiver, int currentRow)
            throws SQLException {
        if (currentRow < 10) {
            receiver.updateInt(1, currentRow);
            receiver.updateString(2, "row " + currentRow);
            return true;
        }
        return false;
    }

    public void close() {}

    public static ResultSetProvider generate()
            throws SQLException {
        return new MySetFunction();
    }
}

Trigger Functions

import org.postgresql.pljava.TriggerData;
import org.postgresql.pljava.annotation.Trigger;

public class MyTrigger {
    @Trigger(called = Trigger.Called.BEFORE, table = "my_table",
             events = {Trigger.Event.INSERT, Trigger.Event.UPDATE})
    public static void auditTrigger(TriggerData td) throws SQLException {
        ResultSet newRow = td.getNew();
        newRow.updateTimestamp("modified_at",
            new java.sql.Timestamp(System.currentTimeMillis()));
    }
}

Database Access via JDBC

import java.sql.*;

public static int countUsers() throws SQLException {
    Connection conn = DriverManager.getConnection("jdbc:default:connection");
    PreparedStatement stmt = conn.prepareStatement("SELECT count(*) FROM users");
    ResultSet rs = stmt.executeQuery();
    rs.next();
    return rs.getInt(1);
}

JAR Management

SELECT sqlj.install_jar('file:///path/to/jar', 'jarname', true);
SELECT sqlj.replace_jar('file:///path/to/new.jar', 'jarname', true);
SELECT sqlj.remove_jar('jarname', true);
SELECT sqlj.set_classpath('schemaname', 'jar1:jar2');
SELECT sqlj.get_classpath('schemaname');

Last Modified 2026-03-12: add pg extension catalog (95749bf)