Skip to content

Commit 3764749

Browse files
committed
Try again for delete.
1 parent b54514c commit 3764749

File tree

3 files changed

+83
-15
lines changed

3 files changed

+83
-15
lines changed

jpype/_core.py

+10-9
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ def _expandClassPath(
158158

159159

160160
_JVM_started = False
161-
_tmp = None
162161

163162
def interactive():
164163
return bool(getattr(sys, 'ps1', sys.flags.interactive))
@@ -303,6 +302,7 @@ def startJVM(
303302
java_class_path.append(support_lib)
304303
java_class_path = list(filter(len, java_class_path))
305304
classpath = _classpath._SEP.join(java_class_path)
305+
tmp = None
306306

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

325326
# ok, setup the jpype system classloader and add to the path after startup
326327
# this guarentees all classes have the same permissions as they did in the past
@@ -343,7 +344,7 @@ def startJVM(
343344
prior = [locale.getlocale(i) for i in categories]
344345
# Start the JVM
345346
_jpype.startup(jvmpath, tuple(jvm_args + extra_jvm_args),
346-
ignoreUnrecognized, convertStrings, interrupt)
347+
ignoreUnrecognized, convertStrings, interrupt, tmp)
347348
# Collect required resources for operation
348349
initializeResources()
349350
# Restore locale

native/common/jp_context.cpp

+43-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@
2222
#include "jp_platform.h"
2323
#include "jp_gc.h"
2424

25+
#ifdef WIN32
26+
#include <Windows.h>
27+
#else
28+
#if defined(_HPUX) && !defined(_IA64)
29+
#include <dl.h>
30+
#else
31+
#include <dlfcn.h>
32+
#endif // HPUX
33+
#include <errno.h>
34+
#endif
35+
36+
2537
JPResource::~JPResource() = default;
2638

2739

@@ -159,6 +171,35 @@ void JPContext::attachJVM(JNIEnv* env)
159171
initializeResources(env, false);
160172
}
161173

174+
std::string getShared()
175+
{
176+
#ifdef WIN32
177+
// Windows specific
178+
char path[MAX_PATH];
179+
HMODULE hm = NULL;
180+
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
181+
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
182+
(LPCSTR) &getShared, &hm) != 0 &&
183+
GetModuleFileName(hm, path, sizeof(path)) != 0)
184+
{
185+
// This is needed when there is no-ascii characters in path
186+
char shortPathBuffer[MAX_PATH];
187+
GetShortPathName(path, shortPathBuffer, MAX_PATH);
188+
return shortPathBuffer;
189+
}
190+
#else
191+
// Linux specific
192+
Dl_info info;
193+
if (dladdr((void*)getShared, &info))
194+
return info.dli_fname;
195+
#endif
196+
// Generic
197+
JPPyObject import = JPPyObject::use(PyImport_AddModule("importlib.util"));
198+
JPPyObject jpype = JPPyObject::call(PyObject_CallMethod(import.get(), "find_spec", "s", "_jpype"));
199+
JPPyObject origin = JPPyObject::call(PyObject_GetAttrString(jpype.get(), "origin"));
200+
return JPPyString::asStringUTF8(origin.get());
201+
}
202+
162203
void JPContext::initializeResources(JNIEnv* env, bool interrupt)
163204
{
164205
JPJavaFrame frame = JPJavaFrame::external(this, env);
@@ -215,10 +256,8 @@ void JPContext::initializeResources(JNIEnv* env, bool interrupt)
215256

216257
if (!m_Embedded)
217258
{
218-
JPPyObject import = JPPyObject::use(PyImport_AddModule("importlib.util"));
219-
JPPyObject jpype = JPPyObject::call(PyObject_CallMethod(import.get(), "find_spec", "s", "_jpype"));
220-
JPPyObject origin = JPPyObject::call(PyObject_GetAttrString(jpype.get(), "origin"));
221-
val[2].l = frame.fromStringUTF8(JPPyString::asStringUTF8(origin.get()));
259+
std::string shared = getShared();
260+
val[2].l = frame.fromStringUTF8(shared);
222261
}
223262

224263
// Required before launch

native/python/pyjp_module.cpp

+30-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
#include "jp_gc.h"
2121
#include "jp_stringtype.h"
2222
#include "jp_classloader.h"
23+
#ifdef WIN32
24+
#include <Windows.h>
25+
#endif
2326

2427
void PyJPModule_installGC(PyObject* module);
2528

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

235+
static string jarTmpPath;
232236
static PyObject* PyJPModule_startup(PyObject* module, PyObject* pyargs)
233237
{
234238
JP_PY_TRY("PyJPModule_startup");
@@ -238,11 +242,23 @@ static PyObject* PyJPModule_startup(PyObject* module, PyObject* pyargs)
238242
char ignoreUnrecognized = true;
239243
char convertStrings = false;
240244
char interrupt = false;
245+
PyObject* tmp;
241246

242-
if (!PyArg_ParseTuple(pyargs, "OO!bbb", &vmPath, &PyTuple_Type, &vmOpt,
243-
&ignoreUnrecognized, &convertStrings, &interrupt))
247+
if (!PyArg_ParseTuple(pyargs, "OO!bbbO", &vmPath, &PyTuple_Type, &vmOpt,
248+
&ignoreUnrecognized, &convertStrings, &interrupt, &tmp))
244249
return nullptr;
245250

251+
if (tmp != Py_None)
252+
{
253+
if (!(JPPyString::check(tmp)))
254+
{
255+
PyErr_SetString(PyExc_TypeError, "Java jar path must be a string");
256+
return nullptr;
257+
}
258+
jarTmpPath = JPPyString::asStringUTF8(tmp);
259+
}
260+
261+
246262
if (!(JPPyString::check(vmPath)))
247263
{
248264
PyErr_SetString(PyExc_TypeError, "Java JVM path must be a string");
@@ -298,6 +314,18 @@ static PyObject* PyJPModule_shutdown(PyObject* obj, PyObject* pyargs, PyObject*
298314
return nullptr;
299315

300316
JPContext_global->shutdownJVM(destroyJVM, freeJVM);
317+
318+
#ifdef WIN32
319+
// Thus far this doesn't work on WINDOWS. The issue is a bug in the JVM
320+
// is holding the file open and there is no apparent method to close it
321+
// so that this can succeed
322+
if (jarTmpPath != "")
323+
remove(jarTmpPath.c_str());
324+
#else
325+
if (jarTmpPath != "")
326+
unlink(jarTmpPath.c_str());
327+
#endif
328+
301329
Py_RETURN_NONE;
302330
JP_PY_CATCH(nullptr);
303331
}

0 commit comments

Comments
 (0)