Skip to content

Commit

Permalink
Try again for delete.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thrameos committed Nov 29, 2024
1 parent b54514c commit 3764749
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 15 deletions.
19 changes: 10 additions & 9 deletions jpype/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ def _expandClassPath(


_JVM_started = False
_tmp = None

def interactive():
return bool(getattr(sys, 'ps1', sys.flags.interactive))
Expand Down Expand Up @@ -303,6 +302,7 @@ def startJVM(
java_class_path.append(support_lib)
java_class_path = list(filter(len, java_class_path))
classpath = _classpath._SEP.join(java_class_path)
tmp = None

# Make sure our module is always on the classpath
if not classpath.isascii():
Expand All @@ -314,13 +314,14 @@ def startJVM(
if not support_lib.isascii():
import tempfile
import shutil
global _tmp
_tmp = tempfile.TemporaryDirectory(dir = _findTemp())
if not _tmp.name.isascii():
raise ValueError("Unable to find ascii temp directory. Clear TEMPDIR, TEMP, and TMP environment variables")
sl2 = os.path.join(_tmp.name, "org.jpype.jar")
shutil.copyfile(support_lib, sl2)
support_lib = sl2
fd, path = tempfile.mkstemp(dir = _findTemp())
if not path.isascii():
raise ValueError("Unable to find ascii temp directory.")
shutil.copyfile(support_lib, path)
support_lib = path
tmp = path
os.close(fd)
# Don't remove

# ok, setup the jpype system classloader and add to the path after startup
# this guarentees all classes have the same permissions as they did in the past
Expand All @@ -343,7 +344,7 @@ def startJVM(
prior = [locale.getlocale(i) for i in categories]
# Start the JVM
_jpype.startup(jvmpath, tuple(jvm_args + extra_jvm_args),
ignoreUnrecognized, convertStrings, interrupt)
ignoreUnrecognized, convertStrings, interrupt, tmp)
# Collect required resources for operation
initializeResources()
# Restore locale
Expand Down
47 changes: 43 additions & 4 deletions native/common/jp_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@
#include "jp_platform.h"
#include "jp_gc.h"

#ifdef WIN32
#include <Windows.h>
#else
#if defined(_HPUX) && !defined(_IA64)
#include <dl.h>
#else
#include <dlfcn.h>
#endif // HPUX
#include <errno.h>
#endif


JPResource::~JPResource() = default;


Expand Down Expand Up @@ -159,6 +171,35 @@ void JPContext::attachJVM(JNIEnv* env)
initializeResources(env, false);
}

std::string getShared()
{
#ifdef WIN32
// Windows specific
char path[MAX_PATH];
HMODULE hm = NULL;
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCSTR) &getShared, &hm) != 0 &&
GetModuleFileName(hm, path, sizeof(path)) != 0)
{
// This is needed when there is no-ascii characters in path
char shortPathBuffer[MAX_PATH];
GetShortPathName(path, shortPathBuffer, MAX_PATH);
return shortPathBuffer;
}
#else
// Linux specific
Dl_info info;
if (dladdr((void*)getShared, &info))
return info.dli_fname;
#endif
// Generic
JPPyObject import = JPPyObject::use(PyImport_AddModule("importlib.util"));
JPPyObject jpype = JPPyObject::call(PyObject_CallMethod(import.get(), "find_spec", "s", "_jpype"));
JPPyObject origin = JPPyObject::call(PyObject_GetAttrString(jpype.get(), "origin"));
return JPPyString::asStringUTF8(origin.get());
}

void JPContext::initializeResources(JNIEnv* env, bool interrupt)
{
JPJavaFrame frame = JPJavaFrame::external(this, env);
Expand Down Expand Up @@ -215,10 +256,8 @@ void JPContext::initializeResources(JNIEnv* env, bool interrupt)

if (!m_Embedded)
{
JPPyObject import = JPPyObject::use(PyImport_AddModule("importlib.util"));
JPPyObject jpype = JPPyObject::call(PyObject_CallMethod(import.get(), "find_spec", "s", "_jpype"));
JPPyObject origin = JPPyObject::call(PyObject_GetAttrString(jpype.get(), "origin"));
val[2].l = frame.fromStringUTF8(JPPyString::asStringUTF8(origin.get()));
std::string shared = getShared();
val[2].l = frame.fromStringUTF8(shared);
}

// Required before launch
Expand Down
32 changes: 30 additions & 2 deletions native/python/pyjp_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "jp_gc.h"
#include "jp_stringtype.h"
#include "jp_classloader.h"
#ifdef WIN32
#include <Windows.h>
#endif

void PyJPModule_installGC(PyObject* module);

Expand Down Expand Up @@ -229,6 +232,7 @@ int PyJP_IsInstanceSingle(PyObject* obj, PyTypeObject* type)
#ifndef ANDROID
extern JNIEnv *Android_JNI_GetEnv();

static string jarTmpPath;
static PyObject* PyJPModule_startup(PyObject* module, PyObject* pyargs)
{
JP_PY_TRY("PyJPModule_startup");
Expand All @@ -238,11 +242,23 @@ static PyObject* PyJPModule_startup(PyObject* module, PyObject* pyargs)
char ignoreUnrecognized = true;
char convertStrings = false;
char interrupt = false;
PyObject* tmp;

if (!PyArg_ParseTuple(pyargs, "OO!bbb", &vmPath, &PyTuple_Type, &vmOpt,
&ignoreUnrecognized, &convertStrings, &interrupt))
if (!PyArg_ParseTuple(pyargs, "OO!bbbO", &vmPath, &PyTuple_Type, &vmOpt,
&ignoreUnrecognized, &convertStrings, &interrupt, &tmp))
return nullptr;

if (tmp != Py_None)
{
if (!(JPPyString::check(tmp)))
{
PyErr_SetString(PyExc_TypeError, "Java jar path must be a string");
return nullptr;
}
jarTmpPath = JPPyString::asStringUTF8(tmp);
}


if (!(JPPyString::check(vmPath)))
{
PyErr_SetString(PyExc_TypeError, "Java JVM path must be a string");
Expand Down Expand Up @@ -298,6 +314,18 @@ static PyObject* PyJPModule_shutdown(PyObject* obj, PyObject* pyargs, PyObject*
return nullptr;

JPContext_global->shutdownJVM(destroyJVM, freeJVM);

#ifdef WIN32
// Thus far this doesn't work on WINDOWS. The issue is a bug in the JVM
// is holding the file open and there is no apparent method to close it
// so that this can succeed
if (jarTmpPath != "")
remove(jarTmpPath.c_str());
#else
if (jarTmpPath != "")
unlink(jarTmpPath.c_str());
#endif

Py_RETURN_NONE;
JP_PY_CATCH(nullptr);
}
Expand Down

0 comments on commit 3764749

Please sign in to comment.