Skip to content

Android Crash: Uncaught JPypeException during Python-Java Interop with Modified JPype Bindings #1257

Description

@YuYuKunKun

Environment:

  • Python: 3.13
  • JPype Version: 1.5.2 (1.4.1)
  • Android Versions: 11 (API 30) & 15 (API 34+)

Issue Description:
The Android application crashes during JVM-Python interoperation through modified JPype bindings, showing a fatal JPypeException originating from native code. Key symptoms include:

  1. Critical Crash:

     ---------------------------- PROCESS STARTED (6812) for package org.python.testbed ----------------------------
     2025-01-26 11:19:36.968  2356-2743  VerityUtils             system_server                        E  Failed to measure fs-verity, errno 1: /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk
     2025-01-26 11:19:37.033  6812-6812  Perf                    org.python.testbed                   I  Connecting to perf service.
     2025-01-26 11:19:37.036  6812-6812  GraphicsEnvironment     org.python.testbed                   V  ANGLE Developer option for 'org.python.testbed' set to: 'default'
     2025-01-26 11:19:37.036  6812-6812  GraphicsEnvironment     org.python.testbed                   V  ANGLE GameManagerService for org.python.testbed: false
     2025-01-26 11:19:37.037  6812-6812  GraphicsEnvironment     org.python.testbed                   V  Updatable production driver is not supported on the device.
     2025-01-26 11:19:37.038  6812-6812  LoadedApk               org.python.testbed                   I  No resource references to update in package androidzte
     2025-01-26 11:19:37.039  6812-6812  NetworkSecurityConfig   org.python.testbed                   D  No Network Security Config specified, using platform default
     2025-01-26 11:19:37.039  6812-6812  NetworkSecurityConfig   org.python.testbed                   D  No Network Security Config specified, using platform default
     2025-01-26 11:19:37.040  6812-6812  ZteBinderProxy          org.python.testbed                   I  initLastBindTime: USE_CACHE = true
     2025-01-26 11:19:37.043  6812-6812  CustomActivityOnCrash   org.python.testbed                   I  CustomActivityOnCrash has been installed.
     2025-01-26 11:19:37.052  6812-6908  libc                    org.python.testbed                   W  Access denied finding property "vendor.MB.running"
     2025-01-26 11:19:37.055  6812-6812  ActivityThread          org.python.testbed                   D  ***** handleLaunchActivity ActivityRecord{119164 token=android.os.BinderProxy@d20cef7 {org.python.testbed/org.python.testbed.MainActivity}}
     2025-01-26 11:19:37.072  6812-6812  AppCompatDelegate       org.python.testbed                   D  Checking for metadata for AppLocalesMetadataHolderService : Service not found
     2025-01-26 11:19:37.088  6812-6812  Typeface                org.python.testbed                   E  updateDefaultTypeface(fontPath: /data/resource-cache/font/default_font_android_id)
     2025-01-26 11:19:37.091  6812-6812  .python.testbed         org.python.testbed                   W  Accessing hidden method Landroid/content/res/AssetManager;->addAssetPath(Ljava/lang/String;)I (unsupported, reflection, allowed)
     2025-01-26 11:19:37.107  6812-6812  .python.testbed         org.python.testbed                   W  Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (unsupported, reflection, allowed)
     2025-01-26 11:19:37.120  6812-6812  Compatibil...geReporter org.python.testbed                   D  Compat change id reported: 210923482; UID 10503; state: ENABLED
     2025-01-26 11:19:37.844  2356-2970  CpuFreezer...rServiceV2 system_server                        E  init add package updateNewAppinfoToList app=org.python.testbed
     2025-01-26 11:19:39.344  6812-6812  .python.testbed         org.python.testbed                   W  type=1400 audit(0.0:273383): avc: denied { read } for name="overcommit_memory" dev="proc" ino=42311951 scontext=u:r:untrusted_app:s0:c247,c257,c512,c768 tcontext=u:object_r:proc_overcommit_memory:s0 tclass=file permissive=0
     2025-01-26 11:19:40.132  6812-6812  .python.testbed         org.python.testbed                   W  type=1400 audit(0.0:273384): avc: granted { execute } for path="/data/data/org.python.testbed/files/python/lib/python3.13/lib-dynload/_socket.cpython-313-aarch64-linux-android.so" dev="dm-15" ino=2635017 scontext=u:r:untrusted_app:s0:c247,c257,c512,c768 tcontext=u:object_r:app_data_file:s0:c247,c257,c512,c768 tclass=file
     2025-01-26 11:19:40.444  6812-7045  native.stderr           org.python.testbed                   W  libc++abi: 
     2025-01-26 11:19:40.444  6812-7045  native.stderr           org.python.testbed                   W  terminating due to uncaught exception of type JPypeException
     2025-01-26 11:19:40.444  6812-6812  libc++abi               org.python.testbed                   E  terminating due to uncaught exception of type JPypeException
     2025-01-26 11:19:40.444  6812-6812  libc                    org.python.testbed                   A  Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 6812 (.python.testbed), pid 6812 (.python.testbed)
     2025-01-26 11:19:41.092  7050-7050  DEBUG                   pid-7050                             A  Cmdline: org.python.testbed
     2025-01-26 11:19:41.092  7050-7050  DEBUG                   pid-7050                             A  pid: 6812, tid: 6812, name: .python.testbed  >>> org.python.testbed <<<
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #01 pc 00000000000a0210  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libc++_shared.so (BuildId: b04675a35ad96f8a9dcaa073e3bd31d4536f00ad)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #02 pc 000000000009eec8  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libc++_shared.so (BuildId: b04675a35ad96f8a9dcaa073e3bd31d4536f00ad)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #03 pc 000000000009f374  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libc++_shared.so (BuildId: b04675a35ad96f8a9dcaa073e3bd31d4536f00ad)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #04 pc 00000000000babc8  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libc++_shared.so (BuildId: b04675a35ad96f8a9dcaa073e3bd31d4536f00ad)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #05 pc 00000000000bab3c  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libc++_shared.so (__cxa_throw+128) (BuildId: b04675a35ad96f8a9dcaa073e3bd31d4536f00ad)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #06 pc 0000000000095574  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libmain_activity.so (PyJPModule_loadResources(_object*)+2152) (BuildId: 7bbb7ee3ad262798f6810af1fc9064ef237455a3)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #07 pc 0000000000096928  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libmain_activity.so (BuildId: 7bbb7ee3ad262798f6810af1fc9064ef237455a3)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #08 pc 000000000028ebfc  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #09 pc 000000000023d7e8  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (PyObject_Vectorcall+92) (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #10 pc 00000000003698a4  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (_PyEval_EvalFrameDefault+20512) (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #11 pc 0000000000364618  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (PyEval_EvalCode+252) (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #12 pc 0000000000361968  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #13 pc 0000000000368b10  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (_PyEval_EvalFrameDefault+17036) (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #14 pc 0000000000364618  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (PyEval_EvalCode+252) (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #15 pc 0000000000361968  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #16 pc 000000000028ea9c  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #17 pc 000000000023d7e8  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (PyObject_Vectorcall+92) (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #18 pc 00000000003698a4  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (_PyEval_EvalFrameDefault+20512) (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #19 pc 00000000003ed764  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #20 pc 00000000003ed370  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libpython3.13.so (Py_RunMain+1472) (BuildId: 9856c77c7f6e2ad616a3bc30ee37e3e92fcf68dc)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #21 pc 00000000000549c4  /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!libmain_activity.so (Java_org_python_testbed_PythonTestRunner_runPython+496) (BuildId: 7bbb7ee3ad262798f6810af1fc9064ef237455a3)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #24 pc 00000000000022a2  [anon:dalvik-classes10.dex extracted in memory from /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!classes10.dex] (org.python.testbed.PythonTestRunner.run+110)
     2025-01-26 11:19:41.093  7050-7050  DEBUG                   pid-7050                             A        #26 pc 000000000000219a  [anon:dalvik-classes10.dex extracted in memory from /data/app/~~c6gw2riMPDlE-LWqM-_S5w==/org.python.testbed-5IqLwSTyCE0_S6ei3-iFWg==/base.apk!classes10.dex] (org.python.testbed.MainActivity.onCreate+82)
     ---------------------------- PROCESS ENDED (6812) for package org.python.testbed ----------------------------
    
    
  2. Patch info:

     diff --color -ruN ./jpype/native/common/jp_context.cpp ./jpype.mod/native/common/jp_context.cpp
     --- ./jpype/native/common/jp_context.cpp	2025-01-26 10:56:08.327270802 +0800
     +++ ./jpype.mod/native/common/jp_context.cpp	2025-01-26 09:56:52.649778241 +0800
     @@ -404,7 +404,7 @@
     void JPContext::attachCurrentThread()
     {
         JNIEnv* env;
     -	jint res = m_JavaVM->functions->AttachCurrentThread(m_JavaVM, (void**) &env, nullptr);
     +	jint res = m_JavaVM->functions->AttachCurrentThread(m_JavaVM, &env, nullptr);
         if (res != JNI_OK)
             JP_RAISE(PyExc_RuntimeError, "Unable to attach to thread");
     }
     @@ -412,7 +412,7 @@
     void JPContext::attachCurrentThreadAsDaemon()
     {
         JNIEnv* env;
     -	jint res = m_JavaVM->functions->AttachCurrentThreadAsDaemon(m_JavaVM, (void**) &env, nullptr);
     +	jint res = m_JavaVM->functions->AttachCurrentThreadAsDaemon(m_JavaVM, &env, nullptr);
         if (res != JNI_OK)
             JP_RAISE(PyExc_RuntimeError, "Unable to attach to thread as daemon");
     }
     @@ -444,7 +444,7 @@
         {
             // We will attach as daemon so that the newly attached thread does
             // not deadlock the shutdown.  The user can convert later if they want.
     -		res = m_JavaVM->AttachCurrentThreadAsDaemon((void**) &env, nullptr);
     +		res = m_JavaVM->AttachCurrentThreadAsDaemon(&env, nullptr);
             if (res != JNI_OK)
                 JP_RAISE(PyExc_RuntimeError, "Unable to attach to local thread");
         }
     diff --color -ruN ./jpype/native/java/org/jpype/JPypeClassLoader.java ./jpype.mod/native/java/org/jpype/JPypeClassLoader.java
     --- ./jpype/native/java/org/jpype/JPypeClassLoader.java	2025-01-26 10:56:08.330604095 +0800
     +++ ./jpype.mod/native/java/org/jpype/JPypeClassLoader.java	2025-01-26 10:50:46.037882437 +0800
     @@ -184,32 +184,40 @@
     @Override
     public Class findClass(String name) throws ClassNotFoundException, ClassFormatError
     {
     -    String aname = name.replace('.', '/') + ".class";
     -    URL url = this.getResource(aname);
     -    if (url == null)
     -      throw new ClassNotFoundException(name);
     +    if (org.python.AndroidPlatform.isAndroid()) {
     +      try {
     +        // 尝试加载安卓系统特有的类
     +        return Class.forName(name);
     +      } catch (ClassNotFoundException e) {
     +        throw new ClassNotFoundException(name);
     +      }
     
     -    try
     +    }
     +    else
         {
     -      URLConnection connection = url.openConnection();
     -      try (InputStream is = connection.getInputStream())
     -      {
     -        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
     -        int bytes;
     -        byte[] d = new byte[1024];
     -        while ((bytes = is.read(d, 0, d.length)) != -1)
     -        {
     -          buffer.write(d, 0, bytes);
     -        }
     +      String aname = name.replace('.', '/') + ".class";
     +      URL url = this.getResource(aname);
     +      if (url == null)
     +        throw new ClassNotFoundException(name);
     
     -        buffer.flush();
     -        byte[] data = buffer.toByteArray();
     -        return defineClass(null, data, 0, data.length);
     +      try {
     +        URLConnection connection = url.openConnection();
     +        try (InputStream is = connection.getInputStream()) {
     +          ByteArrayOutputStream buffer = new ByteArrayOutputStream();
     +          int bytes;
     +          byte[] d = new byte[1024];
     +          while ((bytes = is.read(d, 0, d.length)) != -1) {
     +            buffer.write(d, 0, bytes);
     +          }
     +
     +          buffer.flush();
     +          byte[] data = buffer.toByteArray();
     +          return defineClass(null, data, 0, data.length);
     +        }
     +      } catch (IOException ex) {
         }
     -    } catch (IOException ex)
     -    {
     +      throw new ClassNotFoundException(name);
         }
     -    throw new ClassNotFoundException(name);
     }
     
     @Override
     diff --color -ruN ./jpype/native/java/org/jpype/JPypeContext.java ./jpype.mod/native/java/org/jpype/JPypeContext.java
     --- ./jpype/native/java/org/jpype/JPypeContext.java	2025-01-26 10:56:08.330604095 +0800
     +++ ./jpype.mod/native/java/org/jpype/JPypeContext.java	2025-01-26 11:17:57.416356259 +0800
     @@ -650,7 +650,9 @@
     
     private static long getHeapMemory()
     {
     -    java.lang.management.MemoryMXBean memoryBean = java.lang.management.ManagementFactory.getMemoryMXBean();
     -    return memoryBean.getHeapMemoryUsage().getUsed();
     +    //java.lang.management.MemoryMXBean memoryBean = java.lang.management.ManagementFactory.getMemoryMXBean();
     +    //return memoryBean.getHeapMemoryUsage().getUsed();
     +    Runtime runtime = Runtime.getRuntime();
     +    return runtime.totalMemory() - runtime.freeMemory();
     }
     }
     diff --color -ruN ./jpype/native/java/org/jpype/JPypeUtilities.java ./jpype.mod/native/java/org/jpype/JPypeUtilities.java
     --- ./jpype/native/java/org/jpype/JPypeUtilities.java	2025-01-26 10:56:08.330604095 +0800
     +++ ./jpype.mod/native/java/org/jpype/JPypeUtilities.java	2025-01-26 09:58:11.705731379 +0800
     @@ -1,7 +1,7 @@
     package org.jpype;
     
     import java.lang.invoke.MethodHandle;
     -import java.lang.invoke.MethodHandleProxies;
     +//import java.lang.invoke.MethodHandleProxies;
     import java.lang.invoke.MethodHandles;
     import java.lang.reflect.Method;
     import java.lang.reflect.Modifier;
     @@ -26,6 +26,7 @@
     static
     {
         Predicate<Class> result = null;
     +    /*
         try
         {
         Method m = Class.class.getMethod("isSealed");
     @@ -40,6 +41,8 @@
         // if isSealed doesn't exist then neither do sealed classes
         result = c -> false;
         }
     +    */
     +    result = c -> false;
         isSealed = result;
     }
    
    

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions