From fb29f335ec30b6aef8ce27c22ee3adfe8c7143e4 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Fri, 17 Apr 2026 09:57:44 -0700 Subject: [PATCH] fix: diagnostic logging for code_cache handling --- .../src/main/java/com/tns/RuntimeHelper.java | 8 ++-- .../java/com/tns/bindings/ProxyGenerator.java | 44 ++++++++++++++++--- .../src/main/java/com/tns/DexFactory.java | 25 +++++++++-- 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/test-app/app/src/main/java/com/tns/RuntimeHelper.java b/test-app/app/src/main/java/com/tns/RuntimeHelper.java index fa1542966..206a1123a 100644 --- a/test-app/app/src/main/java/com/tns/RuntimeHelper.java +++ b/test-app/app/src/main/java/com/tns/RuntimeHelper.java @@ -127,13 +127,15 @@ public static Runtime initRuntime(Context context) { dexDir.mkdirs(); } if (!dexDir.exists() || !dexDir.canWrite()) { - if (logger.isEnabled()) { - logger.write("Unable to use dex dir: " + dexDir.getAbsolutePath() + ", falling back to files/secondary-dexes"); - } + File primary = dexDir; dexDir = new File(appDir, "secondary-dexes"); if (!dexDir.exists()) { dexDir.mkdirs(); } + Log.w(logTag, "Unable to use primary dex dir '" + primary.getAbsolutePath() + + "' (exists=" + primary.exists() + " canWrite=" + primary.canWrite() + + "); falling back to '" + dexDir.getAbsolutePath() + + "' (exists=" + dexDir.exists() + " canWrite=" + dexDir.canWrite() + ")"); } String dexThumb = null; try { diff --git a/test-app/runtime-binding-generator/src/main/java/com/tns/bindings/ProxyGenerator.java b/test-app/runtime-binding-generator/src/main/java/com/tns/bindings/ProxyGenerator.java index 52506fbd5..913f2b11e 100644 --- a/test-app/runtime-binding-generator/src/main/java/com/tns/bindings/ProxyGenerator.java +++ b/test-app/runtime-binding-generator/src/main/java/com/tns/bindings/ProxyGenerator.java @@ -62,12 +62,46 @@ private String saveProxy(String proxyName, byte[] proxyBytes) throws IOException if (parentDir != null && !parentDir.exists()) { parentDir.mkdirs(); } - file.createNewFile(); - FileOutputStream stream = new FileOutputStream(file); - stream.write(proxyBytes); - stream.flush(); - stream.close(); + try { + file.createNewFile(); + FileOutputStream stream = new FileOutputStream(file); + try { + stream.write(proxyBytes); + stream.flush(); + } finally { + stream.close(); + } + } catch (IOException e) { + throw new IOException("Failed to save proxy dex '" + file.getAbsolutePath() + + "' (" + proxyBytes.length + " bytes): " + e.getMessage() + + " | " + describeDexDirState(file, parentDir), e); + } return file.getAbsolutePath(); } + + private static String describeDexDirState(File file, File parentDir) { + StringBuilder sb = new StringBuilder(); + sb.append("file.exists=").append(file.exists()); + if (parentDir != null) { + sb.append(" parent=").append(parentDir.getAbsolutePath()); + sb.append(" parent.exists=").append(parentDir.exists()); + sb.append(" parent.isDir=").append(parentDir.isDirectory()); + sb.append(" parent.canWrite=").append(parentDir.canWrite()); + File grand = parentDir.getParentFile(); + if (grand != null) { + sb.append(" grand=").append(grand.getAbsolutePath()); + sb.append(" grand.exists=").append(grand.exists()); + sb.append(" grand.canWrite=").append(grand.canWrite()); + } + try { + sb.append(" parent.freeSpace=").append(parentDir.getFreeSpace()); + sb.append(" parent.usableSpace=").append(parentDir.getUsableSpace()); + } catch (Throwable ignored) { + } + } else { + sb.append(" parent=null"); + } + return sb.toString(); + } } diff --git a/test-app/runtime/src/main/java/com/tns/DexFactory.java b/test-app/runtime/src/main/java/com/tns/DexFactory.java index 3622803fc..b905a19ec 100644 --- a/test-app/runtime/src/main/java/com/tns/DexFactory.java +++ b/test-app/runtime/src/main/java/com/tns/DexFactory.java @@ -56,6 +56,11 @@ public class DexFactory { odexDir.mkdir(); } + if (!dexDir.exists() || !dexDir.canWrite()) { + Log.w("JS", "DexFactory: dexDir unusable at init path=" + dexDir.getAbsolutePath() + + " exists=" + dexDir.exists() + " canWrite=" + dexDir.canWrite()); + } + this.updateDexThumbAndPurgeCache(); this.proxyGenerator.setProxyThumb(this.dexThumb); this.classStorageService = classStorageService; @@ -123,10 +128,22 @@ public Class resolveClass(String baseClassName, String name, String className } String dexFilePath; - if (isInterface) { - dexFilePath = this.generateDex(name, classToProxy, methodOverrides, implementedInterfaces, isInterface); - } else { - dexFilePath = this.generateDex(desiredDexClassName, classToProxy, methodOverrides, implementedInterfaces, isInterface); + try { + if (isInterface) { + dexFilePath = this.generateDex(name, classToProxy, methodOverrides, implementedInterfaces, isInterface); + } else { + dexFilePath = this.generateDex(desiredDexClassName, classToProxy, methodOverrides, implementedInterfaces, isInterface); + } + } catch (IOException e) { + String diag = "DexFactory.generateDex failed class=" + className + + " baseClass=" + baseClassName + + " isInterface=" + isInterface + + " dexDir=" + dexDir.getAbsolutePath() + + " dexDir.exists=" + dexDir.exists() + + " dexDir.canWrite=" + dexDir.canWrite() + + " dexThumb=" + dexThumb; + Log.e("JS", diag + " | " + e.getMessage()); + throw new IOException(diag + " | " + e.getMessage(), e); } dexFile = new File(dexFilePath); long stopGenTime = System.nanoTime();