1
0
mirror of https://github.com/MinimaJack/JVM-plugin.git synced 2024-11-21 13:15:56 +02:00

Fix crash while log while resive null message

Display class name and message from exception, while call java method.
Add support type parameter "date"
Modify main class: related to #2
This commit is contained in:
Evgeniy 2019-12-11 11:16:28 +03:00
parent 3bc7e8ad26
commit d1a0a08af0
4 changed files with 153 additions and 58 deletions

View File

@ -18,29 +18,50 @@
static jobject s_threadLock;
static IAddInDefBase *gAsyncEvent = NULL;
IAddInDefBase *gAsyncEvent = nullptr;
static wchar_t *g_PropNames[] = { L"IsEnabled", L"javaHome", L"libraryDir" };
static wchar_t *g_MethodNames[] = { L"LaunchInJVM",L"LaunchInJVMP",L"LaunchInJVMPP", L"CallFInJVMB", L"CallFInJVMBP", L"CallFInJVMBPP", L"CallFInJVM", L"CallFInJVMP", L"CallFInJVMPP", L"CallFInJVMPPP", L"CallFInJVMPPPP", L"Disable", L"AddJar" };
static void JNICALL Java_Runner_log(JNIEnv *env, jobject thisObj, jstring info) {
wchar_t *who = JVM_LAUNCHER;
jclass classClass = env->GetObjectClass(thisObj);
jmethodID mid = env->GetMethodID(classClass, "getClass", "()Ljava/lang/Class;");
jobject clsObj = env->CallObjectMethod(thisObj, mid);
classClass = env->GetObjectClass(clsObj);
auto getNameMethod = env->GetMethodID(classClass, "getName", "()Ljava/lang/String;");
auto callingClassName = (jstring)env->CallObjectMethod(clsObj, getNameMethod);
auto wsMessage = JStringToWString(env, info);
auto wsCallClassName = JStringToWString(env, callingClassName);
if (gAsyncEvent ==nullptr) {
return;
}
WCHAR_T *message = 0;
WCHAR_T *className = 0;
::convToShortWchar(&message, wsMessage.c_str());
jstring callingClassName;
jobject classObject;
jclass classOfClass;
jclass cls = env->FindClass("java/lang/Class");
if (env->IsInstanceOf(thisObj, cls)) {
classObject = thisObj;
classOfClass = env->GetObjectClass(thisObj);
}
else {
jclass classClass = env->GetObjectClass(thisObj);
jmethodID mid = env->GetMethodID(classClass, "getClass", "()Ljava/lang/Class;");
jobject clsObj = env->CallObjectMethod(thisObj, mid);
classObject = clsObj;
classOfClass = env->GetObjectClass(clsObj);
}
jmethodID getNameMethod = env->GetMethodID(classOfClass, "getName", "()Ljava/lang/String;");
callingClassName = (jstring)env->CallObjectMethod(classObject, getNameMethod);
auto wsCallClassName = JStringToWString(env, callingClassName);
::convToShortWchar(&className, wsCallClassName.c_str());
gAsyncEvent->ExternalEvent(who, className, message);
if (env->IsSameObject(info, NULL)) {
gAsyncEvent->ExternalEvent(JVM_LAUNCHER, className, L"NULL");
}
else {
auto wsMessage = JStringToWString(env, info);
::convToShortWchar(&message, wsMessage.c_str());
gAsyncEvent->ExternalEvent(JVM_LAUNCHER, className, message);
}
delete[]message;
delete[]className;
@ -53,18 +74,20 @@ bool JVMLauncher::endCall(JNIEnv* env)
jobject exh = m_JVMEnv->ExceptionOccurred();
if (exh) {
jclass classClass = this->m_JVMEnv->GetObjectClass(exh);
auto getClassLoaderMethod = this->m_JVMEnv->GetMethodID(classClass, "getLocalizedMessage", "()Ljava/lang/String;");
auto info = (jstring)this->m_JVMEnv->CallObjectMethod(exh, getClassLoaderMethod);
if (m_JVMEnv->IsSameObject(info, NULL)) {
jmethodID mid = env->GetMethodID(classClass, "getClass", "()Ljava/lang/Class;");
jobject clsObj = env->CallObjectMethod(exh, mid);
jclass classClass = env->GetObjectClass(clsObj);
auto getMessageMethod = this->m_JVMEnv->GetMethodID(classClass, "getMessage", "()Ljava/lang/String;");
auto info = (jstring)this->m_JVMEnv->CallObjectMethod(exh, getMessageMethod);
auto mid = env->GetMethodID(classClass, "getClass", "()Ljava/lang/Class;");
jobject clsObj = env->CallObjectMethod(exh, mid);
jclass classOfClass = env->GetObjectClass(clsObj);
mid = this->m_JVMEnv->GetMethodID(classOfClass, "getName", "()Ljava/lang/String;");
auto exeptionName = (jstring)this->m_JVMEnv->CallObjectMethod(clsObj, mid);
auto wstring = JStringToWString(env, exeptionName);
auto getNameMethod = this->m_JVMEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;");
info = (jstring)this->m_JVMEnv->CallObjectMethod(clsObj, getNameMethod);
}
auto wstring = JStringToWString(env, info);
if (!m_JVMEnv->IsSameObject(info, NULL)) {
wstring = wstring.append(L":").append(JStringToWString(env, info));
};
WCHAR_T *err = 0;
::convToShortWchar(&err, wstring.c_str());
@ -216,7 +239,7 @@ void JVMLauncher::LaunchJVM() {
int n;
jint retval = m_GetCreatedJavaVMs(&m_RunningJVMInstance, 1, (jsize*)&n);
if (retval == JNI_OK)
{
@ -252,6 +275,7 @@ void JVMLauncher::LaunchJVM() {
vm_args.ignoreUnrecognized = JNI_TRUE;
jint res = m_JVMInstance(&m_RunningJVMInstance, (void **)&m_JVMEnv, &vm_args);
if (res != JNI_OK) {
pAsyncEvent->AddError(ADDIN_E_FAIL, JVM_LAUNCHER, L"Could not launch the JVM", 3);
}
@ -688,6 +712,7 @@ bool JVMLauncher::CallAsFunc(const long lMethodNum,
case VTYPE_R4: signature.append("F"); break;
case VTYPE_R8: signature.append("D"); break;
case VTYPE_EMPTY: signature.append("V"); break;
case VTYPE_DATE: signature.append("Ljava/util/Date;"); break;
}
methodID = JNI_getStaticMethodID(findedClass, "mainInt", signature.c_str(), resultOk);
if (!resultOk) {
@ -713,6 +738,7 @@ bool JVMLauncher::CallAsFunc(const long lMethodNum,
break;
case VTYPE_PWSTR:
case VTYPE_PSTR:
case VTYPE_DATE:
result.l = JNI_callStaticObjectMethodA(findedClass, methodID, values, resultOk);
break;
case VTYPE_I4:

View File

@ -109,6 +109,7 @@ private:
std::vector<std::string> m_listOfClasses;
std::map<std::string, jclass> m_cachedClasses;
std::map<jclass, jmethodID> m_cachedMethod;
std::map<std::string, std::pair<jclass, jmethodID>> m_cachedClassesMethod;
void LaunchJVM();
bool verify();

128
Utils.cpp
View File

@ -14,7 +14,7 @@
#include <wchar.h>
#include "Utils.h"
#include <string>
#include <ctime>
jvalue* getParams(JNIEnv* env, tVariant* paParams, int start, int end) {
if (end < start) {
@ -35,6 +35,9 @@ jvalue* getParams(JNIEnv* env, tVariant* paParams, int start, int end) {
else if (TV_VT(&paParams[i]) == VTYPE_R4) {
values[i - start].f = TV_R4(&paParams[i]);
}
else if (TV_VT(&paParams[i]) == VTYPE_DATE || TV_VT(&paParams[i]) == VTYPE_TM) {
values[i - start].l = getjdateFrom1C(env, &paParams[i]);
}
}
return values;
}
@ -55,6 +58,12 @@ std::string getSignature(JNIEnv* env, tVariant* paParams, int start, int end) {
else if (TV_VT(&paParams[i]) == VTYPE_R4) {
signature.append("F");
}
else if (TV_VT(&paParams[i]) == VTYPE_DATE) {
signature.append("Ljava/util/Date;");
}
else if (TV_VT(&paParams[i]) == VTYPE_TM) {
signature.append("Ljava/util/Date;");
}
}
return signature.append(")");
}
@ -87,6 +96,40 @@ jstring getjstringFrom1C(JNIEnv* env, tVariant* paParams) {
return jstr;
}
jobject getjdateFrom1C(JNIEnv* env, tVariant* paParams) {
jobject jobj = nullptr;
switch (TV_VT(paParams))
{
case VTYPE_DATE: {
struct tm timeVal;
fromOleDate(&timeVal, TV_DATE(paParams));
time_t time = mktime(&timeVal);
jclass date = env->FindClass("java/util/Date");
jmethodID dateTypeConstructor = env->GetMethodID(date, "<init>", "(J)V");
jobj = env->NewObject(date, dateTypeConstructor, time * 1000);
jobject exh = env->ExceptionOccurred();
if (exh) {
env->ExceptionClear();
}
}
break;
case VTYPE_TM: {
struct tm timeVal = paParams->tmVal;
time_t time = mktime(&timeVal);
jclass date = env->FindClass("java/util/Date");
jmethodID dateTypeConstructor = env->GetMethodID(date, "<init>", "(J)V");
jobj = env->NewObject(date, dateTypeConstructor, time * 1000);
jobject exh = env->ExceptionOccurred();
if (exh) {
env->ExceptionClear();
}
break;
}
}
return jobj;
}
std::string getStdStringFrom1C(tVariant* paParams) {
std::string resultString;
char *name = 0;
@ -119,25 +162,24 @@ std::string getStdStringFrom1C(tVariant* paParams) {
//---------------------------------------------------------------------------//
uint32_t convToShortWchar(WCHAR_T** Dest, const wchar_t* Source, uint32_t len)
{
if (!len)
len = ::wcslen(Source)+1;
if (!len)
len = ::wcslen(Source) + 1;
if (!*Dest)
*Dest = new WCHAR_T[len];
if (!*Dest)
*Dest = new WCHAR_T[len];
WCHAR_T* tmpShort = *Dest;
wchar_t* tmpWChar = (wchar_t*) Source;
uint32_t res = 0;
WCHAR_T* tmpShort = *Dest;
wchar_t* tmpWChar = (wchar_t*)Source;
uint32_t res = 0;
::memset(*Dest, 0, len*sizeof(WCHAR_T));
do
{
*tmpShort++ = (WCHAR_T)*tmpWChar++;
++res;
}
while (len-- && *tmpWChar);
::memset(*Dest, 0, len * sizeof(WCHAR_T));
do
{
*tmpShort++ = (WCHAR_T)*tmpWChar++;
++res;
} while (len-- && *tmpWChar);
return res;
return res;
}
//---------------------------------------------------------------------------//
uint32_t getLenShortWcharStr(const WCHAR_T* Source)
@ -153,24 +195,48 @@ uint32_t getLenShortWcharStr(const WCHAR_T* Source)
//---------------------------------------------------------------------------//
uint32_t convFromShortWchar(wchar_t** Dest, const WCHAR_T* Source, uint32_t len)
{
if (!len)
len = getLenShortWcharStr(Source)+1;
if (!len)
len = getLenShortWcharStr(Source) + 1;
if (!*Dest)
*Dest = new wchar_t[len];
if (!*Dest)
*Dest = new wchar_t[len];
wchar_t* tmpWChar = *Dest;
WCHAR_T* tmpShort = (WCHAR_T*)Source;
uint32_t res = 0;
wchar_t* tmpWChar = *Dest;
WCHAR_T* tmpShort = (WCHAR_T*)Source;
uint32_t res = 0;
::memset(*Dest, 0, len*sizeof(wchar_t));
do
{
*tmpWChar++ = (wchar_t)*tmpShort++;
++res;
}
while (len-- && *tmpShort);
::memset(*Dest, 0, len * sizeof(wchar_t));
do
{
*tmpWChar++ = (wchar_t)*tmpShort++;
++res;
} while (len-- && *tmpShort);
return res;
return res;
}
void fromOleDate(struct tm* paTm, double paOADate)
{
static const int64_t OA_UnixTimestamp = -2209161600; // 30-Dec-1899
if (!(25569 <= paOADate //* 01-Jan-1970 00:00:00
&& paOADate <= 2958465)) //* 31-Dec-9999 00:00:00
{
throw std::string("OADate must be between 25569 and 2958465!");
}
time_t OADatePassedDays = paOADate;
double OADateDayTime = paOADate - OADatePassedDays;
time_t OADateSeconds = OA_UnixTimestamp
+ OADatePassedDays * 24LL * 3600LL
+ OADateDayTime * 24.0 * 3600.0;
// date was greater than 19-Jan-2038 and build is 32 bit
if (0 > OADateSeconds)
{
throw std::string("OADate must be between 25569 and 50424.134803241!");
}
gmtime_s(paTm, &OADateSeconds);
}

View File

@ -13,7 +13,9 @@ uint32_t getLenShortWcharStr(const WCHAR_T* Source);
std::wstring JStringToWString(JNIEnv* env, jstring string);
std::string getStdStringFrom1C(tVariant* paParams);
jstring getjstringFrom1C(JNIEnv* env, tVariant* paParams);
jobject getjdateFrom1C(JNIEnv* env, tVariant* paParams);
std::string getSignature(JNIEnv* env, tVariant* paParams, int start, int end);
jvalue* getParams(JNIEnv* env, tVariant* paParams, int start, int end);
void fromOleDate(struct tm* paTm, double paOADate);
#endif //__UTILS_H__