mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
- Make the JVM lib dynamically loaded
This makes the CONNECT storage engine usable when Java JDK is not installed. modified: storage/connect/ha_connect.cc modified: storage/connect/jdbconn.cpp modified: storage/connect/jdbconn.h - Typo modified: storage/connect/reldef.cpp
This commit is contained in:
@@ -129,6 +129,7 @@
|
||||
#endif // ODBC_SUPPORT
|
||||
#if defined(JDBC_SUPPORT)
|
||||
#include "jdbccat.h"
|
||||
#include "jdbconn.h"
|
||||
#endif // JDBC_SUPPORT
|
||||
#include "xtable.h"
|
||||
#include "tabmysql.h"
|
||||
@@ -169,7 +170,7 @@
|
||||
#define JSONMAX 10 // JSON Default max grp size
|
||||
|
||||
extern "C" {
|
||||
char version[]= "Version 1.04.0006 March 12, 2016";
|
||||
char version[]= "Version 1.04.0006 May 08, 2016";
|
||||
#if defined(__WIN__)
|
||||
char compver[]= "Version 1.04.0006 " __DATE__ " " __TIME__;
|
||||
char slash= '\\';
|
||||
@@ -190,6 +191,10 @@ extern "C" {
|
||||
} // extern "C"
|
||||
#endif // XMSG
|
||||
|
||||
#if defined(JDBC_SUPPORT)
|
||||
char *JvmPath;
|
||||
#endif // JDBC_SUPPORT
|
||||
|
||||
#if defined(__WIN__)
|
||||
CRITICAL_SECTION parsec; // Used calling the Flex parser
|
||||
#else // !__WIN__
|
||||
@@ -667,6 +672,9 @@ static int connect_init_func(void *p)
|
||||
|
||||
DTVAL::SetTimeShift(); // Initialize time zone shift once for all
|
||||
BINCOL::SetEndian(); // Initialize host endian setting
|
||||
#if defined(JDBC_SUPPORT)
|
||||
JDBConn::SetJVM();
|
||||
#endif // JDBC_SUPPORT
|
||||
DBUG_RETURN(0);
|
||||
} // end of connect_init_func
|
||||
|
||||
@@ -683,13 +691,17 @@ static int connect_done_func(void *)
|
||||
|
||||
#ifdef LIBXML2_SUPPORT
|
||||
XmlCleanupParserLib();
|
||||
#endif // LIBXML2_SUPPORT
|
||||
#endif // LIBXML2_SUPPORT
|
||||
|
||||
#if defined(__WIN__)
|
||||
#ifdef JDBC_SUPPORT
|
||||
JDBConn::ResetJVM();
|
||||
#endif // JDBC_SUPPORT
|
||||
|
||||
#if defined(__WIN__)
|
||||
DeleteCriticalSection((LPCRITICAL_SECTION)&parsec);
|
||||
#else // !__WIN__
|
||||
#else // !__WIN__
|
||||
PROFILE_End();
|
||||
#endif // !__WIN__
|
||||
#endif // !__WIN__
|
||||
|
||||
for (pc= user_connect::to_users; pc; pc= pn) {
|
||||
if (pc->g)
|
||||
@@ -6835,6 +6847,15 @@ static MYSQL_SYSVAR_STR(errmsg_dir_path, msg_path,
|
||||
"../../../../storage/connect/"); // for testing
|
||||
#endif // XMSG
|
||||
|
||||
#if defined(JDBC_SUPPORT)
|
||||
static MYSQL_SYSVAR_STR(jvm_path, JvmPath,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
|
||||
"Path to the directory where is the JVM lib",
|
||||
// check_jvm_path, update_jvm_path,
|
||||
NULL, NULL, NULL);
|
||||
#endif // JDBC_SUPPORT
|
||||
|
||||
|
||||
static struct st_mysql_sys_var* connect_system_variables[]= {
|
||||
MYSQL_SYSVAR(xtrace),
|
||||
MYSQL_SYSVAR(conv_size),
|
||||
@@ -6852,7 +6873,8 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
|
||||
MYSQL_SYSVAR(errmsg_dir_path),
|
||||
#endif // XMSG
|
||||
MYSQL_SYSVAR(json_grp_size),
|
||||
NULL
|
||||
MYSQL_SYSVAR(jvm_path),
|
||||
NULL
|
||||
};
|
||||
|
||||
maria_declare_plugin(connect)
|
||||
|
||||
@@ -17,17 +17,19 @@
|
||||
#include <direct.h> // for getcwd
|
||||
#if defined(__BORLANDC__)
|
||||
#define __MFC_COMPAT__ // To define min/max as macro
|
||||
#endif
|
||||
#endif // __BORLANDC__
|
||||
//#include <windows.h>
|
||||
#else
|
||||
#else // !__WIN__
|
||||
#if defined(UNIX)
|
||||
#include <errno.h>
|
||||
#else
|
||||
#else // !UNIX
|
||||
//nclude <io.h>
|
||||
#endif
|
||||
#endif // !UNIX
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // for getenv
|
||||
//nclude <fcntl.h>
|
||||
#define NODW
|
||||
#endif
|
||||
#endif // !__WIN__
|
||||
|
||||
/***********************************************************************/
|
||||
/* Required objects includes. */
|
||||
@@ -52,6 +54,14 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
|
||||
#endif // !__WIN__
|
||||
|
||||
int GetConvSize();
|
||||
extern char *JvmPath; // The connect_jvm_path global variable value
|
||||
|
||||
/***********************************************************************/
|
||||
/* Static JDBConn objects. */
|
||||
/***********************************************************************/
|
||||
void *JDBConn::LibJvm = NULL;
|
||||
CRTJVM JDBConn::CreateJavaVM = NULL;
|
||||
GETJVM JDBConn::GetCreatedJavaVMs = NULL;
|
||||
|
||||
/***********************************************************************/
|
||||
/* Some macro's (should be defined elsewhere to be more accessible) */
|
||||
@@ -618,90 +628,6 @@ PQRYRES JDBCPrimaryKeys(PGLOBAL g, JDBConn *op, char *dsn, char *table)
|
||||
/************************************************************************/
|
||||
return qrp;
|
||||
} // end of JDBCPrimaryKeys
|
||||
|
||||
/**************************************************************************/
|
||||
/* Statistics: constructs the result blocks containing statistics */
|
||||
/* about one or several tables to be retrieved by GetData commands. */
|
||||
/**************************************************************************/
|
||||
PQRYRES JDBCStatistics(PGLOBAL g, JDBConn *op, char *dsn, char *pat,
|
||||
int un, int acc)
|
||||
{
|
||||
static int buftyp[] ={ TYPE_STRING,
|
||||
TYPE_STRING, TYPE_STRING, TYPE_SHORT, TYPE_STRING,
|
||||
TYPE_STRING, TYPE_SHORT, TYPE_SHORT, TYPE_STRING,
|
||||
TYPE_STRING, TYPE_INT, TYPE_INT, TYPE_STRING };
|
||||
static unsigned int length[] ={ 0, 0, 0, 6, 0, 0, 6, 6, 0, 2, 10, 10, 128 };
|
||||
int n, ncol = 13;
|
||||
int maxres;
|
||||
PQRYRES qrp;
|
||||
JCATPARM *cap;
|
||||
JDBConn *jcp = op;
|
||||
|
||||
if (!op) {
|
||||
/**********************************************************************/
|
||||
/* Open the connection with the JDBC data source. */
|
||||
/**********************************************************************/
|
||||
jcp = new(g)JDBConn(g, NULL);
|
||||
|
||||
if (jcp->Open(dsn, 2) < 1) // 2 is openReadOnly
|
||||
return NULL;
|
||||
|
||||
} // endif op
|
||||
|
||||
/************************************************************************/
|
||||
/* Do an evaluation of the result size. */
|
||||
/************************************************************************/
|
||||
n = 1 + jcp->GetMaxValue(SQL_MAX_COLUMNS_IN_INDEX);
|
||||
maxres = (n) ? (int)n : 32;
|
||||
n = jcp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN);
|
||||
length[1] = (n) ? (n + 1) : 128;
|
||||
n = jcp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN);
|
||||
length[2] = length[5] = (n) ? (n + 1) : 128;
|
||||
n = jcp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN);
|
||||
length[0] = length[4] = (n) ? (n + 1) : length[2];
|
||||
n = jcp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN);
|
||||
length[7] = (n) ? (n + 1) : 128;
|
||||
|
||||
if (trace)
|
||||
htrc("SemStatistics: max=%d pat=%s\n", maxres, SVP(pat));
|
||||
|
||||
/************************************************************************/
|
||||
/* Allocate the structure used to refer to the result set. */
|
||||
/************************************************************************/
|
||||
qrp = PlgAllocResult(g, ncol, maxres, IDS_STAT,
|
||||
buftyp, NULL, length, false, true);
|
||||
|
||||
if (trace)
|
||||
htrc("Getting stat results ncol=%d\n", qrp->Nbcol);
|
||||
|
||||
cap = AllocCatInfo(g, CAT_STAT, NULL, pat, qrp);
|
||||
cap->Unique = (un < 0) ? SQL_INDEX_UNIQUE : (UWORD)un;
|
||||
cap->Accuracy = (acc < 0) ? SQL_QUICK : (UWORD)acc;
|
||||
|
||||
/************************************************************************/
|
||||
/* Now get the results into blocks. */
|
||||
/************************************************************************/
|
||||
if ((n = jcp->GetCatInfo(cap)) >= 0) {
|
||||
qrp->Nblin = n;
|
||||
// ResetNullValues(cap);
|
||||
|
||||
if (trace)
|
||||
htrc("Statistics: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin);
|
||||
|
||||
} else
|
||||
qrp = NULL;
|
||||
|
||||
/************************************************************************/
|
||||
/* Close any local connection. */
|
||||
/************************************************************************/
|
||||
if (!op)
|
||||
jcp->Close();
|
||||
|
||||
/************************************************************************/
|
||||
/* Return the result pointer for use by GetData routines. */
|
||||
/************************************************************************/
|
||||
return qrp;
|
||||
} // end of Statistics
|
||||
#endif // 0
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -842,13 +768,98 @@ int JDBConn::GetMaxValue(int n)
|
||||
return (int)env->CallIntMethod(job, maxid, n);
|
||||
} // end of GetMaxValue
|
||||
|
||||
/***********************************************************************/
|
||||
/* Reset the JVM library. */
|
||||
/***********************************************************************/
|
||||
void JDBConn::ResetJVM(void)
|
||||
{
|
||||
if (!LibJvm) {
|
||||
#if defined(__WIN__)
|
||||
FreeLibrary((HMODULE)LibJvm);
|
||||
#else // !__WIN__
|
||||
dlclose(LibJvm);
|
||||
#endif // !__WIN__
|
||||
LibJvm = NULL;
|
||||
CreateJavaVM = NULL;
|
||||
GetCreatedJavaVMs = NULL;
|
||||
} // endif LibJvm
|
||||
|
||||
} // end of ResetJVM
|
||||
|
||||
/***********************************************************************/
|
||||
/* Dynamically link the JVM library. */
|
||||
/* The purpose of this function is to allow using the CONNECT plugin */
|
||||
/* for other table types when the Java JDK is not installed. */
|
||||
/***********************************************************************/
|
||||
bool JDBConn::GetJVM(PGLOBAL g)
|
||||
{
|
||||
if (!LibJvm) {
|
||||
char soname[512];
|
||||
|
||||
if (JvmPath)
|
||||
strcat(strcpy(soname, JvmPath), "\\jvm.dll");
|
||||
else
|
||||
strcpy(soname, "jvm.dll");
|
||||
|
||||
#if defined(__WIN__)
|
||||
// Load the desired shared library
|
||||
if (!(LibJvm = LoadLibrary(soname))) {
|
||||
char buf[256];
|
||||
DWORD rc = GetLastError();
|
||||
|
||||
sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
|
||||
(LPTSTR)buf, sizeof(buf), NULL);
|
||||
strcat(strcat(g->Message, ": "), buf);
|
||||
} else if (!(CreateJavaVM = (CRTJVM)GetProcAddress((HINSTANCE)LibJvm,
|
||||
"JNI_CreateJavaVM"))) {
|
||||
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_CreateJavaVM");
|
||||
FreeLibrary((HMODULE)LibJvm);
|
||||
LibJvm = NULL;
|
||||
} else if (!(GetCreatedJavaVMs = (GETJVM)GetProcAddress((HINSTANCE)LibJvm,
|
||||
"JNI_GetCreatedJavaVMs"))) {
|
||||
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_GetCreatedJavaVMs");
|
||||
FreeLibrary((HMODULE)LibJvm);
|
||||
LibJvm = NULL;
|
||||
} // endif LibJvm
|
||||
#else // !__WIN__
|
||||
const char *error = NULL;
|
||||
|
||||
// Load the desired shared library
|
||||
if (!(LibJvm = dlopen(soname, RTLD_LAZY))) {
|
||||
error = dlerror();
|
||||
sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
|
||||
} else if (!(CreateJavaVM = (CRTJVM)dlsym(LibJvm, "JNI_CreateJavaVM"))) {
|
||||
error = dlerror();
|
||||
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_CreateJavaVM", SVP(error));
|
||||
dlclose(LibJvm);
|
||||
LibJvm = NULL;
|
||||
} else if (!(GetCreatedJavaVMs = (CRTJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) {
|
||||
error = dlerror();
|
||||
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error));
|
||||
dlclose(LibJvm);
|
||||
LibJvm = NULL;
|
||||
} // endif LibJvm
|
||||
#endif // !__WIN__
|
||||
|
||||
} // endif LibJvm
|
||||
|
||||
return LibJvm == NULL;
|
||||
} // end of GetJVM
|
||||
|
||||
/***********************************************************************/
|
||||
/* Open: connect to a data source. */
|
||||
/***********************************************************************/
|
||||
int JDBConn::Open(PSZ jpath, PJPARM sop)
|
||||
{
|
||||
PGLOBAL& g = m_G;
|
||||
|
||||
if (GetJVM(g))
|
||||
return true;
|
||||
|
||||
PSTRG jpop = new(g) STRING(g, 512, "-Djava.class.path=");
|
||||
char *cp = NULL;
|
||||
char sep;
|
||||
|
||||
#if defined(__WIN__)
|
||||
@@ -872,15 +883,26 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
|
||||
//================== prepare loading of Java VM ============================
|
||||
JavaVMInitArgs vm_args; // Initialization arguments
|
||||
JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options
|
||||
|
||||
|
||||
// where to find java .class
|
||||
jpop->Append(getenv("CLASSPATH"));
|
||||
if ((cp = PlugDup(m_G, getenv("CLASSPATH"))))
|
||||
jpop->Append(cp);
|
||||
|
||||
if (trace) {
|
||||
htrc("CLASSPATH=%s\n", cp);
|
||||
htrc("jpath=%s\n", jpath);
|
||||
} // endif trace
|
||||
|
||||
if (jpath && *jpath) {
|
||||
if (cp)
|
||||
jpop->Append(sep);
|
||||
|
||||
if (jpath) {
|
||||
jpop->Append(sep);
|
||||
jpop->Append(jpath);
|
||||
} // endif jpath
|
||||
|
||||
if (trace)
|
||||
htrc("%s\n", jpop->GetStr());
|
||||
|
||||
options[0].optionString = jpop->GetStr();
|
||||
//options[1].optionString = "-verbose:jni";
|
||||
vm_args.version = JNI_VERSION_1_6; // minimum Java version
|
||||
@@ -889,7 +911,7 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
|
||||
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
|
||||
|
||||
//=============== load and initialize Java VM and JNI interface =============
|
||||
jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
|
||||
jint rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
|
||||
delete options; // we then no longer need the initialisation options.
|
||||
|
||||
switch (rc) {
|
||||
@@ -914,7 +936,7 @@ int JDBConn::Open(PSZ jpath, PJPARM sop)
|
||||
JavaVM* jvms[1];
|
||||
jsize jsz;
|
||||
|
||||
rc = JNI_GetCreatedJavaVMs(jvms, 1, &jsz);
|
||||
rc = GetCreatedJavaVMs(jvms, 1, &jsz);
|
||||
|
||||
if (rc == JNI_OK && jsz == 1) {
|
||||
jvm = jvms[0];
|
||||
@@ -1952,6 +1974,9 @@ bool JDBConn::SetParam(JDBCCOL *colp)
|
||||
// Not used anymore
|
||||
env->DeleteLocalRef(parms);
|
||||
|
||||
if (trace)
|
||||
htrc("Method %s returned %d columns\n", fnc, ncol);
|
||||
|
||||
// n because we no more ignore the first column
|
||||
if ((n = qrp->Nbcol) > (uint)ncol) {
|
||||
strcpy(g->Message, MSG(COL_NUM_MISM));
|
||||
@@ -1989,9 +2014,12 @@ bool JDBConn::SetParam(JDBCCOL *colp)
|
||||
|
||||
// Now fetch the result
|
||||
for (i = 0; i < qrp->Maxres; i++) {
|
||||
if ((rc = Fetch(0)) == 0)
|
||||
if ((rc = Fetch(0)) == 0) {
|
||||
if (trace)
|
||||
htrc("End of fetches i=%d\n", i);
|
||||
|
||||
break;
|
||||
else if (rc < 0)
|
||||
} else if (rc < 0)
|
||||
return -1;
|
||||
|
||||
for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) {
|
||||
|
||||
@@ -60,6 +60,9 @@ typedef struct tagJCATPARM {
|
||||
PUCHAR Pat; // Table type or column pattern
|
||||
} JCATPARM;
|
||||
|
||||
typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *);
|
||||
typedef jint(JNICALL *GETJVM) (JavaVM **, jsize, jsize *);
|
||||
|
||||
// JDBC connection to a data source
|
||||
class TDBJDBC;
|
||||
class JDBCCOL;
|
||||
@@ -114,8 +117,11 @@ public:
|
||||
PQRYRES GetMetaData(PGLOBAL g, char *src);
|
||||
|
||||
public:
|
||||
// Set special options
|
||||
//void OnSetOptions(HSTMT hstmt);
|
||||
// Set static variables
|
||||
static void SetJVM(void)
|
||||
{ LibJvm = NULL; CreateJavaVM = NULL; GetCreatedJavaVMs = NULL; }
|
||||
static void ResetJVM(void);
|
||||
static bool GetJVM(PGLOBAL g);
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
@@ -126,15 +132,17 @@ protected:
|
||||
char *Check(void);
|
||||
//void ThrowDJX(int rc, PSZ msg/*, HSTMT hstmt = SQL_NULL_HSTMT*/);
|
||||
//void ThrowDJX(PSZ msg);
|
||||
//void AllocConnect(DWORD dwOptions);
|
||||
//void Connect(void);
|
||||
//bool DriverConnect(DWORD Options);
|
||||
//void VerifyConnect(void);
|
||||
//void GetConnectInfo(void);
|
||||
//void Free(void);
|
||||
|
||||
protected:
|
||||
// Members
|
||||
#if defined(__WIN__)
|
||||
static HANDLE LibJvm; // Handle to the jvm DLL
|
||||
#else // !__WIN__
|
||||
static void *LibJvm; // Handle for the jvm shared library
|
||||
#endif // !__WIN__
|
||||
static CRTJVM CreateJavaVM;
|
||||
static GETJVM GetCreatedJavaVMs;
|
||||
PGLOBAL m_G;
|
||||
TDBJDBC *m_Tdb;
|
||||
JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
|
||||
|
||||
@@ -514,10 +514,11 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
|
||||
} // endif getdef
|
||||
#else // !__WIN__
|
||||
const char *error = NULL;
|
||||
Dl_info dl_info;
|
||||
|
||||
#if 0 // Don't know what all this stuff does
|
||||
// The OEM lib must retrieve exported CONNECT variables
|
||||
Dl_info dl_info;
|
||||
|
||||
// The OEM lib must retrieve exported CONNECT variables
|
||||
if (dladdr(&connect_hton, &dl_info)) {
|
||||
if (dlopen(dl_info.dli_fname, RTLD_NOLOAD | RTLD_NOW | RTLD_GLOBAL) == 0) {
|
||||
error = dlerror();
|
||||
|
||||
Reference in New Issue
Block a user