Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  javaconn.cpp   Sprache: C

 

/************ Javaconn C++ Functions Source Code File (.CPP) ***********/
/*  Name: JAVAConn.CPP  Version 1.1                                    */
/*                                                                     */
/*  (C) Copyright to the author Olivier BERTRAND          2017 - 2021  */
/*                                                                     */
/*  This file contains the JAVA connection classes functions.          */
/***********************************************************************/

#if defined(_WIN32)
// This is needed for RegGetValue
#define _WINVER 0x0601
#undef  _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif   // _WIN32

/***********************************************************************/
/*  Include relevant MariaDB header file.                              */
/***********************************************************************/
#include <my_global.h>
//#include <m_string.h>
#if defined(_WIN32)
#include <direct.h>                      // for getcwd
#if defined(__BORLANDC__)
#define __MFC_COMPAT__                   // To define min/max as macro
#endif   // __BORLANDC__
#else   // !_WIN32
#if defined(UNIX)
#include <errno.h>
#else   // !UNIX
#endif  // !UNIX
#include <stdio.h>
#include <stdlib.h>                      // for getenv
#define NODW
#endif  // !_WIN32

#include <m_string.h>

/***********************************************************************/
/*  Required objects includes.                                         */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "colblk.h"
#include "xobject.h"
#include "xtable.h"
#include "tabext.h"
#include "javaconn.h"
#include "resource.h"
#include "valblk.h"
#include "osutil.h"

#if defined(_WIN32)
extern "C" HINSTANCE s_hModule;           // Saved module handle
#endif   // _WIN32
#define nullptr 0

//TYPCONV GetTypeConv();
//int GetConvSize();
extern char *JvmPath;   // The connect_jvm_path global variable value
extern char *ClassPath; // The connect_class_path global variable value

char *GetPluginDir(void);
char *GetMessageDir(void);
char *GetJavaWrapper(void);  // The connect_java_wrapper variable value
extern MYSQL_PLUGIN_IMPORT char lc_messages_dir[FN_REFLEN];

/***********************************************************************/
/*  Static JAVAConn objects.                                           */
/***********************************************************************/
void  *JAVAConn::LibJvm = NULL;
CRTJVM JAVAConn::CreateJavaVM = NULL;
GETJVM JAVAConn::GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GETDEF JAVAConn::GetDefaultJavaVMInitArgs = NULL;
#endif   // _DEBUG

/***********************************************************************/
/*  Some macro's (should be defined elsewhere to be more accessible)   */
/***********************************************************************/
#if defined(_DEBUG)
#define ASSERT(f)          assert(f)
#define DEBUG_ONLY(f)      (f)
#else   // !_DEBUG
#define ASSERT(f)          ((void)0)
#define DEBUG_ONLY(f)      ((void)0)
#endif  // !_DEBUG

/***********************************************************************/
/*  JAVAConn construction/destruction.                                 */
/***********************************************************************/
JAVAConn::JAVAConn(PGLOBAL g, PCSZ wrapper)
{
 m_G = g;
 jvm = nullptr;            // Pointer to the JVM (Java Virtual Machine)
 env = nullptr;            // Pointer to native interface
 jdi = nullptr;      // Pointer to the java wrapper class
 job = nullptr;      // The java wrapper class object
 errid = nullptr;
 DiscFunc = "Disconnect";
 Msg = NULL;
 m_Wrap = (wrapper) ? wrapper : GetJavaWrapper();

 if (!strchr(m_Wrap, '/')) {
  // Add the wrapper package name
  char *wn = (char*)PlugSubAlloc(g, NULL, strlen(m_Wrap) + 10);
  m_Wrap = strcat(strcpy(wn, "wrappers/"), m_Wrap);
 } // endif m_Wrap

 fp = NULL;
 m_Opened = false;
 m_Connected = false;
 m_Rows = 0;
//*m_ErrMsg = '\0';
} // end of JAVAConn

//JAVAConn::~JAVAConn()
//  {
//if (Connected())
//  EndCom();

//  } // end of ~JAVAConn
char *JAVAConn::GetUTFString(jstring s)
{
 char *str;
 const char *utf = env->GetStringUTFChars(s, nullptr);

 str = PlugDup(m_G, utf);
 env->ReleaseStringUTFChars(s, utf);
 env->DeleteLocalRef(s);
 return str;
} // end of GetUTFString

/***********************************************************************/
/*  Screen for errors.                                                 */
/***********************************************************************/
bool JAVAConn::Check(jint rc)
{
 jstring s;

 if (env->ExceptionCheck()) {
  jthrowable exc = env->ExceptionOccurred();
  jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"),
   "toString", "()Ljava/lang/String;");

  if (exc != nullptr && tid != nullptr) {
   s = (jstring)env->CallObjectMethod(exc, tid);
   Msg = GetUTFString(s);
  } else
   Msg = "Exception occurred";

  env->ExceptionClear();
 } else if (rc < 0) {
  s = (jstring)env->CallObjectMethod(job, errid);
  Msg = GetUTFString(s);
 } else
  Msg = NULL;

 return (Msg != NULL);
} // end of Check

/***********************************************************************/
/*  Get MethodID if not exists yet.                                    */
/***********************************************************************/
bool JAVAConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig)
{
 if (mid == nullptr) {
  mid = env->GetMethodID(jdi, name, sig);

  if (Check()) {
   snprintf(g->Message, sizeof(g->Message), "%s", Msg);
   return true;
  } else
   return false;

 } else
  return false;

} // end of gmID

#if 0
/***********************************************************************/
/*  Utility routine.                                                   */
/***********************************************************************/
int JAVAConn::GetMaxValue(int n)
{
 jint      m;
 jmethodID maxid = nullptr;

 if (gmID(m_G, maxid, "GetMaxValue", "(I)I"))
  return -1;

 // call method
 if (Check(m = env->CallIntMethod(job, maxid, n)))
  htrc("GetMaxValue: %s", Msg);

 return (int)m;
} // end of GetMaxValue
#endif // 0

/***********************************************************************/
/*  Reset the JVM library.                                             */
/***********************************************************************/
void JAVAConn::ResetJVM(void)
{
 if (LibJvm) {
#if defined(_WIN32)
  FreeLibrary((HMODULE)LibJvm);
#else   // !_WIN32
  dlclose(LibJvm);
#endif  // !_WIN32
  LibJvm = NULL;
  CreateJavaVM = NULL;
  GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
  GetDefaultJavaVMInitArgs = NULL;
#endif   // _DEBUG
 } // 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 JAVAConn::GetJVM(PGLOBAL g)
{
 int ntry;

 if (!LibJvm) {
  char soname[512];

#if defined(_WIN32)
  for (ntry = 0; !LibJvm && ntry < 3; ntry++) {
   if (!ntry && JvmPath) {
    snprintf(soname, sizeof(soname), "%s\\jvm.dll", JvmPath);

    ntry = 3;   // No other try
   } else if (ntry < 2 && getenv("JAVA_HOME")) {
    safe_strcpy(soname, sizeof(soname), getenv("JAVA_HOME"));

    if (ntry == 1)
     safe_strcat(soname, sizeof(soname), "\\jre");

    safe_strcat(soname, sizeof(soname), "\\bin\\client\\jvm.dll");
   } else {
    // Try to find it through the registry
    char version[16];
    char javaKey[64] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
    LONG  rc;
    DWORD BufferSize = 16;

    safe_strcpy(soname, sizeof(soname), "jvm.dll");  // In case it fails

    if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "CurrentVersion",
     RRF_RT_ANY, NULL, (PVOID)&version, &BufferSize)) == ERROR_SUCCESS) {
     safe_strcat(javaKey, sizeof(javaKey), "\\");
     safe_strcat(javaKey, sizeof(javaKey), version);
     BufferSize = sizeof(soname);

     if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "RuntimeLib",
      RRF_RT_ANY, NULL, (PVOID)&soname, &BufferSize)) != ERROR_SUCCESS)
      printf("RegGetValue: rc=%ld\n", rc);

    } // endif rc

    ntry = 3;   // Try this only once
   } // endelse

   // Load the desired shared library
   LibJvm = LoadLibrary(soname);
  } // endfor ntry

  // Get the needed entries
  if (!LibJvm) {
   char  buf[256];
   DWORD rc = GetLastError();

   FormatMessage(FORMAT_MESSAGE_FLAGS, NULL, rc, 0,
                (LPTSTR)buf, sizeof(buf), NULL);
   snprintf(g->Message, sizeof(g->Message), MSG(DLL_LOAD_ERROR)": %s", rc,
        soname, buf);
  } else if (!(CreateJavaVM = (CRTJVM)GetProcAddress((HINSTANCE)LibJvm,
                                          "JNI_CreateJavaVM"))) {
   snprintf(g->Message, sizeof(g->Message), MSG(PROCADD_ERROR), GetLastError(), "JNI_CreateJavaVM");
   FreeLibrary((HMODULE)LibJvm);
   LibJvm = NULL;
  } else if (!(GetCreatedJavaVMs = (GETJVM)GetProcAddress((HINSTANCE)LibJvm,
                                          "JNI_GetCreatedJavaVMs"))) {
   snprintf(g->Message, sizeof(g->Message), MSG(PROCADD_ERROR), GetLastError(), "JNI_GetCreatedJavaVMs");
   FreeLibrary((HMODULE)LibJvm);
   LibJvm = NULL;
#if defined(_DEBUG)
  } else if (!(GetDefaultJavaVMInitArgs = (GETDEF)GetProcAddress((HINSTANCE)LibJvm,
                                          "JNI_GetDefaultJavaVMInitArgs"))) {
   snprintf(g->Message, sizeof(g->Message), MSG(PROCADD_ERROR), GetLastError(),
    "JNI_GetDefaultJavaVMInitArgs");
   FreeLibrary((HMODULE)LibJvm);
   LibJvm = NULL;
#endif   // _DEBUG
  } // endif LibJvm
#else   // !_WIN32
  const char *error = NULL;

  for (ntry = 0; !LibJvm && ntry < 2; ntry++) {
   if (!ntry && JvmPath) {
    snprintf(soname, sizeof(soname), "%s/libjvm.so", JvmPath);
    ntry = 2;
   } else if (!ntry && getenv("JAVA_HOME")) {
    // TODO: Replace i386 by a better guess
    snprintf(soname, sizeof(soname), "%s/jre/lib/i386/client/libjvm.so",
         getenv("JAVA_HOME"));
   } else {  // Will need LD_LIBRARY_PATH to be set
    safe_strcpy(soname, sizeof(soname), "libjvm.so");
    ntry = 2;
   } // endelse

   LibJvm = dlopen(soname, RTLD_LAZY);
  } // endfor ntry

   // Load the desired shared library
  if (!LibJvm) {
   error = dlerror();
   snprintf(g->Message, sizeof(g->Message), MSG(SHARED_LIB_ERR), soname, SVP(error));
  } else if (!(CreateJavaVM = (CRTJVM)dlsym(LibJvm, "JNI_CreateJavaVM"))) {
   error = dlerror();
   snprintf(g->Message, sizeof(g->Message), MSG(GET_FUNC_ERR), "JNI_CreateJavaVM", SVP(error));
   dlclose(LibJvm);
   LibJvm = NULL;
  } else if (!(GetCreatedJavaVMs = (GETJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) {
   error = dlerror();
   snprintf(g->Message, sizeof(g->Message), MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error));
   dlclose(LibJvm);
   LibJvm = NULL;
#if defined(_DEBUG)
  } else if (!(GetDefaultJavaVMInitArgs = (GETDEF)dlsym(LibJvm,
   "JNI_GetDefaultJavaVMInitArgs"))) {
   error = dlerror();
   snprintf(g->Message, sizeof(g->Message), MSG(GET_FUNC_ERR), "JNI_GetDefaultJavaVMInitArgs", SVP(error));
   dlclose(LibJvm);
   LibJvm = NULL;
#endif   // _DEBUG
  } // endif LibJvm
#endif  // !_WIN32

 } // endif LibJvm

 return LibJvm == NULL;
} // end of GetJVM

/***********************************************************************/
/*  Open: connect to a data source.                                    */
/***********************************************************************/
bool JAVAConn::Open(PGLOBAL g)
{
         bool   brc = true;
 jboolean jt = (trace(1));

 // Link or check whether jvm library was linked
 if (GetJVM(g))
  return true;

 // Firstly check whether the jvm was already created
 JavaVM* jvms[1];
 jsize   jsz;
 jint    rc = GetCreatedJavaVMs(jvms, 1, &jsz);

 if (rc == JNI_OK && jsz == 1) {
  // jvm already existing
  jvm = jvms[0];
  rc = jvm->AttachCurrentThread((void**)&env, nullptr);

  if (rc != JNI_OK) {
   snprintf(g->Message, sizeof(g->Message), "Cannot attach jvm to the current thread");
   return true;
  } // endif rc

 } else {
  /*******************************************************************/
  /*  Create a new jvm  */
  /*******************************************************************/
  PSTRG    jpop = new(g)STRING(g, 512, "-Djava.class.path=.");
  char    *cp = NULL;
  char     sep;

#if defined(_WIN32)
  sep = ';';
#define N 1
  //#define N 2
  //#define N 3
#else
  sep = ':';
#define N 1
#endif

  // Add wrappers jar files 
  AddJars(jpop, sep);

  //================== prepare loading of Java VM ============================
  JavaVMInitArgs vm_args;                        // Initialization arguments
  JavaVMOption* options = new JavaVMOption[N];   // JVM invocation options

  // where to find java .class
  if (ClassPath && *ClassPath) {
   jpop->Append(sep);
   jpop->Append(ClassPath);
  } // endif ClassPath

  jpop->Append(sep);
  jpop->Append(GetMessageDir());
  jpop->Append("JdbcInterface.jar");

#if defined(MONGO_SUPPORT)
  jpop->Append(sep);
  jpop->Append(GetMessageDir());
  jpop->Append("Mongo3.jar");
  jpop->Append(sep);
  jpop->Append(GetMessageDir());
  jpop->Append("Mongo2.jar");
#endif   // MONGO_SUPPORT

  if ((cp = getenv("CLASSPATH"))) {
   jpop->Append(sep);
   jpop->Append(cp);
  } // endif cp

  if (trace(1)) {
   htrc("ClassPath=%s\n", ClassPath ? ClassPath : "null");
   htrc("CLASSPATH=%s\n", cp ? cp : "null");
   htrc("%s\n", jpop->GetStr());
  } // endif trace

  options[0].optionString = jpop->GetStr();
#if N == 2
  options[1].optionString = "-Xcheck:jni";
#endif
#if N == 3
  options[1].optionString = "-Xms256M";
  options[2].optionString = "-Xmx512M";
#endif
#if defined(_DEBUG)
  vm_args.version = JNI_VERSION_1_2;             // minimum Java version
  rc = GetDefaultJavaVMInitArgs(&vm_args);
#else
  vm_args.version = JNI_VERSION_1_6;             // minimum Java version
#endif   // _DEBUG
  vm_args.nOptions = N;                          // number of options
  vm_args.options = options;
  vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail

  //=============== load and initialize Java VM and JNI interface =============
  rc = CreateJavaVM(&jvm, (void**)&env, &vm_args);  // YES !!
  delete[] options;    // we then no longer need the initialisation options.

  switch (rc) {
   case JNI_OK:
    snprintf(g->Message, sizeof(g->Message), "VM successfully created");
    brc = false;
    break;
   case JNI_ERR:
    snprintf(g->Message, sizeof(g->Message), "Initialising JVM failed: unknown error");
    break;
   case JNI_EDETACHED:
    snprintf(g->Message, sizeof(g->Message), "Thread detached from the VM");
    break;
   case JNI_EVERSION:
    snprintf(g->Message, sizeof(g->Message), "JNI version error");
    break;
   case JNI_ENOMEM:
    snprintf(g->Message, sizeof(g->Message), "Not enough memory");
    break;
   case JNI_EEXIST:
    snprintf(g->Message, sizeof(g->Message), "VM already created");
    break;
   case JNI_EINVAL:
    snprintf(g->Message, sizeof(g->Message), "Invalid arguments");
    break;
   default:
    snprintf(g->Message, sizeof(g->Message), "Unknown return code %d", (int)rc);
    break;
  } // endswitch rc

  if (trace(1))
   htrc("%s\n", g->Message);

  if (brc)
   return true;

  //=============== Display JVM version ===============
  jint ver = env->GetVersion();
  printf("JVM Version %d.%d\n", ((ver >> 16) & 0x0f), (ver & 0x0f));
 } // endif rc

 // try to find the java wrapper class
 jdi = env->FindClass(m_Wrap);

 if (jdi == nullptr) {
  snprintf(g->Message, sizeof(g->Message), "ERROR: class %s not found!", m_Wrap);
  return true;
 } // endif jdi

#if 0  // Suppressed because it does not make any usable change
 if (b && jpath && *jpath) {
  // Try to add that path the the jvm class path
  jmethodID alp = env->GetStaticMethodID(jdi, "addLibraryPath",
   "(Ljava/lang/String;)I");

  if (alp == nullptr) {
   env->ExceptionDescribe();
   env->ExceptionClear();
  } else {
   char *msg;
   jstring path = env->NewStringUTF(jpath);
   rc = env->CallStaticIntMethod(jdi, alp, path);

   if ((msg = Check(rc))) {
    snprintf(g->Message, sizeof(g->Message), msg);
    env->DeleteLocalRef(path);
    return RC_FX;
   } else switch (rc) {
    case JNI_OK:
     printf("jpath added\n");
     break;
    case JNI_EEXIST:
     printf("jpath already exist\n");
     break;
    case JNI_ERR:
    default:
     snprintf(g->Message, sizeof(g->Message), "Error adding jpath");
     env->DeleteLocalRef(path);
     return RC_FX;
   } // endswitch rc

   env->DeleteLocalRef(path);
  } // endif alp

 } // endif jpath
#endif // 0

 // if class found, continue
 jmethodID ctor = env->GetMethodID(jdi, "<init>", "(Z)V");

 if (ctor == nullptr) {
  snprintf(g->Message, sizeof(g->Message), "ERROR: %s constructor not found!", m_Wrap);
  return true;
 } else
  job = env->NewObject(jdi, ctor, jt);

 if (job == nullptr) {
  snprintf(g->Message, sizeof(g->Message), "%s class object not constructed!", m_Wrap);
  return true;
 } // endif job

 // If the object is successfully constructed, 
 // we can then search for the method we want to call, 
 // and invoke it for the object:
 errid = env->GetMethodID(jdi, "GetErrmsg", "()Ljava/lang/String;");

 if (env->ExceptionCheck()) {
  snprintf(g->Message, sizeof(g->Message), "ERROR: method GetErrmsg() not found!");
  env->ExceptionDescribe();
  env->ExceptionClear();
  return true;
 } // endif Check

 /*********************************************************************/
 /*  Link a Fblock. This make possible to automatically close it      */
 /*  in case of error (throw).                                        */
 /*********************************************************************/
 PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;

 fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
 fp->Type = TYPE_FB_JAVA;
 fp->Fname = NULL;
 fp->Next = dbuserp->Openlist;
 dbuserp->Openlist = fp;
 fp->Count = 1;
 fp->Length = 0;
 fp->Memory = NULL;
 fp->Mode = MODE_ANY;
 fp->File = this;
 fp->Handle = 0;

 m_Opened = true;
 return false;
} // end of Open

/***********************************************************************/
/*  Disconnect connection                                              */
/***********************************************************************/
void JAVAConn::Close()
{
 jint rc;

 if (m_Connected) {
  jmethodID did = nullptr;

  // Could have been detached in case of join
  rc = jvm->AttachCurrentThread((void**)&env, nullptr);

  if (gmID(m_G, did, DiscFunc, "()I"))
   printf("%s\n", Msg);
  else if (Check(env->CallIntMethod(job, did)))
   printf("%s: %s\n", DiscFunc, Msg);

  m_Connected = false;
 } // endif m_Connected

 if ((rc = jvm->DetachCurrentThread()) != JNI_OK)
  printf("DetachCurrentThread: rc=%d\n", (int)rc);

 if (fp)
  fp->Count = 0;

 m_Opened = false;
} // end of Close

Messung V0.5 in Prozent
C=74 H=99 G=87

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.16Angebot  (Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-08) ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

letze Version des Elbe Quellennavigators


Jenseits des Üblichen ....
    

Besucher

Besucher

Statistik
#Sources=1126864
#Domains=1897691