diff --git a/jpype/_core.py b/jpype/_core.py index ca1191d01..aa7f2d06e 100644 --- a/jpype/_core.py +++ b/jpype/_core.py @@ -237,6 +237,11 @@ def startJVM( if classpath: extra_jvm_args += (f'-Djava.class.path={_handleClassPath(classpath)}', ) + supportLib = os.path.join(os.path.dirname(os.path.dirname(__file__)),"org.jpype.jar") + if not os.path.exists(supportLib): + raise RuntimeError("Unable to find org.jpype.jar support library at "+supportLib) + extra_jvm_args += ('-javaagent:'+supportLib,) + try: import locale # Gather a list of locale settings that Java may override (excluding LC_ALL) diff --git a/native/common/jp_classloader.cpp b/native/common/jp_classloader.cpp index 9e754fb8d..78023283b 100644 --- a/native/common/jp_classloader.cpp +++ b/native/common/jp_classloader.cpp @@ -17,29 +17,13 @@ #include #include #include +#include jobject JPClassLoader::getBootLoader() { return m_BootLoader.get(); } -static jobject toURL(JPJavaFrame &frame, const string& path) -{ - // file = new File("org.jpype.jar"); - jclass fileClass = frame.FindClass("java/io/File"); - jmethodID newFile = frame.GetMethodID(fileClass, "", "(Ljava/lang/String;)V"); - jvalue v[3]; - v[0].l = frame.NewStringUTF(path.c_str()); - jobject file = frame.NewObjectA(fileClass, newFile, v); - - // url = file.toURI().toURL(); - jmethodID toURI = frame.GetMethodID(fileClass, "toURI", "()Ljava/net/URI;"); - jobject uri = frame.CallObjectMethodA(file, toURI, nullptr); - jclass uriClass = frame.GetObjectClass(uri); - jmethodID toURL = frame.GetMethodID(uriClass, "toURL", "()Ljava/net/URL;"); - return frame.CallObjectMethodA(uri, toURL, nullptr); -} - JPClassLoader::JPClassLoader(JPJavaFrame& frame) { JP_TRACE_IN("JPClassLoader::JPClassLoader"); @@ -68,44 +52,8 @@ JPClassLoader::JPClassLoader(JPJavaFrame& frame) } frame.ExceptionClear(); - // Harder, we need to find the _jpype module and use __file__ to obtain a - // path. - JPPyObject pypath = JPPyObject::call(PyObject_GetAttrString(PyJPModule, "__file__")); - string path = JPPyString::asStringUTF8(pypath.get()); - string::size_type i = path.find_last_of('\\'); - if (i == string::npos) - i = path.find_last_of('/'); - if (i == string::npos) - JP_RAISE(PyExc_RuntimeError, "Can't find jar path"); - path = path.substr(0, i + 1); - jobject url1 = toURL(frame, path + "org.jpype.jar"); - // jobject url2 = toURL(frame, path + "lib/asm-8.0.1.jar"); - - // urlArray = new URL[]{url}; - jclass urlClass = frame.GetObjectClass(url1); - jobjectArray urlArray = frame.NewObjectArray(1, urlClass, nullptr); - frame.SetObjectArrayElement(urlArray, 0, url1); - // frame.SetObjectArrayElement(urlArray, 1, url2); - - // cl = new URLClassLoader(urlArray); - jclass urlLoaderClass = frame.FindClass("java/net/URLClassLoader"); - jmethodID newURLClassLoader = frame.GetMethodID(urlLoaderClass, "", "([Ljava/net/URL;Ljava/lang/ClassLoader;)V"); - jvalue v[3]; - v[0].l = (jobject) urlArray; - v[1].l = (jobject) m_SystemClassLoader.get(); - jobject cl = frame.NewObjectA(urlLoaderClass, newURLClassLoader, v); - - // Class dycl = Class.forName("org.jpype.classloader.DynamicClassLoader", true, cl); - v[0].l = frame.NewStringUTF("org.jpype.classloader.DynamicClassLoader"); - v[1].z = true; - v[2].l = cl; - auto dyClass = (jclass) frame.CallStaticObjectMethodA(m_ClassClass.get(), m_ForNameID, v); - - // dycl.newInstance(systemClassLoader); - jmethodID newDyLoader = frame.GetMethodID(dyClass, "", "(Ljava/lang/ClassLoader;)V"); - v[0].l = cl; - m_BootLoader = JPObjectRef(frame, frame.NewObjectA(dyClass, newDyLoader, v)); - + // org.jpype was not loaded already so we can't proceed + JP_RAISE(PyExc_RuntimeError, "Can't find org.jpype.jar support library"); JP_TRACE_OUT; // GCOVR_EXCL_LINE } diff --git a/native/java/manifest.txt b/native/java/manifest.txt new file mode 100644 index 000000000..85c360946 --- /dev/null +++ b/native/java/manifest.txt @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Premain-Class: org.jpype.agent.JPypeAgent diff --git a/native/java/org/jpype/agent/JPypeAgent.java b/native/java/org/jpype/agent/JPypeAgent.java new file mode 100644 index 000000000..9d02e4ba2 --- /dev/null +++ b/native/java/org/jpype/agent/JPypeAgent.java @@ -0,0 +1,10 @@ +package org.jpype.agent; + +import java.lang.instrument.Instrumentation; + +public class JPypeAgent +{ + public static void premain(String agentArgs, Instrumentation inst) { + System.out.println("Start jpype"); + } +} diff --git a/project/jpype_java/manifest.mf b/project/jpype_java/manifest.mf new file mode 100644 index 000000000..85c360946 --- /dev/null +++ b/project/jpype_java/manifest.mf @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Premain-Class: org.jpype.agent.JPypeAgent diff --git a/project/jpype_java/nbproject/project.properties b/project/jpype_java/nbproject/project.properties index 76c7151ac..da12f5cef 100755 --- a/project/jpype_java/nbproject/project.properties +++ b/project/jpype_java/nbproject/project.properties @@ -113,3 +113,4 @@ source.encoding=UTF-8 src.java.dir=${file.reference.native-java} test.harness.dir=${file.reference.test-harness} test.src.dir=test +manifest.file=manifest.mf diff --git a/setupext/build_ext.py b/setupext/build_ext.py index 80514bb93..00cc0a72d 100644 --- a/setupext/build_ext.py +++ b/setupext/build_ext.py @@ -315,8 +315,12 @@ def build_java_ext(self, ext): os.makedirs("build/classes", exist_ok=True) self.announce(" %s" % " ".join(cmd1), level=distutils.log.INFO) subprocess.check_call(cmd1) + manifest = None try: for file in glob.iglob("native/java/**/*.*", recursive=True): + if file.endswith("manifest.txt"): + manifest = file + continue if file.endswith(".java") or os.path.isdir(file): continue p = os.path.join(build_dir, os.path.relpath(file, "native/java")) @@ -326,7 +330,7 @@ def build_java_ext(self, ext): print("FAIL", ex) pass cmd3 = shlex.split( - '%s cvf "%s" -C "%s" .' % (jar, jarFile, build_dir)) + '%s cvfm "%s" "%s" -C "%s" .' % (jar, jarFile, manifest, build_dir)) self.announce(" %s" % " ".join(cmd3), level=distutils.log.INFO) subprocess.check_call(cmd3)