pgspider / jdbc_fdw

JDBC Foreign Data Wrapper for PostgreSQL
Other
69 stars 23 forks source link

Re-use Java VM if it already exists #23

Open choplin opened 1 year ago

choplin commented 1 year ago

Context

JNI prohibits creating multiple Java VM within a single process. JNI_CreateJavaVM returns a JNI_EEXIST error if Java VM exists. In that case, we have to re-use the existing Java VM by calling JNI_GetCreatedJavaVMs.

What was changed?

Other considerations

jopoly commented 11 months ago

@choplin

Thanks for your contribution. Could you please share specific scenario that JVM is created multiple times in the single process? Is there any issues have you met? As my understanding, the current source code already handled re-using JVM well if it is created.

jdbc_jvm_init()

        if (FunctionCallCheck == false)
        {
           create JVM
        }
        else
        {
           re-use existing JVM
        }
choplin commented 11 months ago

@jopoly Thank you for your reply!

Could you please share specific scenario that JVM is created multiple times in the single process?

Sorry for the lack of explanation. This becomes problematic when users use jdbc_fdw together with another extension that uses JNI too. Since Postgres worker works in a single process as you know, all extensions that use JNI must share a single JVM due to the limitation of JNI.

The mechanism you explained to prevent a duplicate call of JNI_CreateJavaVM utilizes a static variable in this extension as an initialized flag. So, it cannot prevent jdbc_fdw from calling JNI_CreateJavaVM even if another extension has already created a JVM, and vice versa.

For this kind of situation, JNI provides JNI_GetCreatedJavaVMs to reuse the existing JVM.

I understand there are not many extensions that use JNI. We encountered this situation when we tried to use jdbc_fdw with our extension, scalardb_fdw, that uses JNI to call Java library from Postgres.

jopoly commented 11 months ago

@choplin

Thanks for your explanation. I understood that multiple JVMs are not supported in the single process.

I understand there are not many extensions that use JNI. We encountered this situation when we tried to use jdbc_fdw with our extension, scalardb_fdw...

I'd like to re-produce the issue to understand more about the limitation of the current source code. So, could you please share a test scenario including test model and test case? Is it possible with the following test model?

                                            PostgreSQL     
                                          /            \
                                      jdbc_fdw       jdbc_fdw
                                        |                |
                                     PostgreSQL1     PostgreSQL2