# Some problems and their solution.

When writing the PlJava, mapping the JVM into the same process-space as the PostgreSQL backend code, some concerns have been raised regarding multiple threads, exception handling, and memory management. Here is a brief text explaining how these issues where resolved.

## Multi threading.

### Problem

Java is inherently multi threaded. The PostgreSQL backend is not. There’s nothing stopping a developer from utilizing multiple Threads class in the Java code. Finalizers that call out to the backend might have been spawned from a background Garbage Collection thread. Several third party Java-packages that are likely to be used make use of multiple threads. How can this model coexist with the PostgreSQL backend in the same process without creating havoc?

### Solution

The solution consists of two mechanisms which together form a waterproof protection against multiple threads in the backend code.

1. All calls from Java and out to the backend functions are synchronized on one and the same object. All native calls are private to ensure that the synchronization cannot be bypassed. The result is that only one thread at a time can make a call from the JVM and out to the backend functions.
2. A control flag, managed outside of the JVM, keeps track of when the call handler waits for the return of a call into the JVM. If this flag is set, the JVM is allowed to make synchronized calls to the backend. If not set, the JVM will be denied all access. Any attempt to call the backend will result in an exception. This prevents a stray thread from the JVM to enter the backend at a time when it’s not expecting it.

The analogy would be to see the JVM as a monster swinging multiple swords at the backend. The backend can cope as long as the monster swings one sword at a time. The synchronization mechanism ensures this. The backend needs to turn its back to the monster and do other things such as attending to client requests every now and then. The control flag ensures that the monster doesn’t stab the backend from behind.

## Exception handling

### Problem

Java makes frequent use of try/catch/finally blocks. PostgreSQL sometimes use an exception mechanism that calls longjmp to transfer control to a known state. Such a jump would normally effectively bypass the JVM. Prior to PostgreSQL version 8.0, the error was propagated before the actual jump and then discarded, thus there was no way to catch and handle the error.

### Solution

When using PostgreSQL 7.4.x, the current state of the jump buffer (Warn_restart for hackers) is saved by the call handler prior to all calls into the JVM. All calls from the JVM into the backend that might result in a longjmp, will setup its own local jump buffer. If a longjmp occurs, the jump is caught, remembered by raising a flag, and replaced with a Java exception that is thrown. From that point on, and until the JVM returns, the JVM is blocked from all access to the PostgreSQL backend code. Once the JVM returns (typically immediately due to the exception), the flag state is examined and the jump “continues” to its intended destination (the original state of the Warn_restart buffer). This allows the JVM to trap all exceptions and to do normal catch/finally processing. The database can of course not be accessed but other housekeeping can be made.

Starting with PostgreSQL 8.0, this is changed. The backend now allows errors to be cougth using the macros PG_TRY/PG_CATCH/PG_END_TRY and in the catch block, the error can be examined using the ErrorData structure. PLJava implements a java.sql.SQLException subclass called org.postgresql.pljava.ServerException. The ErrorData can be retrieved and examined from that exception. A catch handler is allowed to issue a rollback to a savepoint. After a succesful rollback, execution can continue.

## Java Garbage Collector versus palloc() and stack allocation.

### Problem

Primitive types will be passed by value always. This includes the String type (this is a must since Java uses double byte characters). Complex types are however often wrapped in Java objects and passed by reference. I.e, a Java object will contain a pointer to a palloc’ed or stack allocated memory and use native JNI calls to extract and manipulate data. Such data will become “stale” once a call has ended. Further attempts to access such data will at best give very unpredictable results but more likely cause a memory fault and a crash.

### Solution

The PLJava contains code that ensures that stale pointers are cleared when the MemoryContext or stack where they where allocated goes out of scope. The Java wrapper objects might live on but any attempt to use them will result in a “stale native handle” exception.