[libbluray-devel] Improve class file translation.

hpi1 git at videolan.org
Sun Nov 8 19:05:26 CET 2015


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Sun Nov  8 19:28:53 2015 +0200| [626ee490972744c8f52e4f82eb2faa1ca9f7c357] | committer: hpi1

Improve class file translation.

Translate in class loader:
- works with Java 8+
- allows translating also files that are not invalid
- does not depend on sun implementation-specific interfaces

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=626ee490972744c8f52e4f82eb2faa1ca9f7c357
---

 .../java/org/videolan/BDJClassFileTransformer.java |    6 +-
 .../bdj/java/org/videolan/BDJClassLoader.java      |   72 ++++++++++++++++++++
 src/libbluray/bdj/java/org/videolan/Libbluray.java |    7 --
 3 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java b/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java
index 4f8cb32..988e76e 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java
@@ -20,7 +20,7 @@
 package org.videolan;
 
 /**
- * This is a class which is called by java.lang.ClassLoader
+ * This is a class which is called by BDJClassLoader
  * when ClassFormatError is thrown inside defineClass().
  *
  * Some discs have invalid debug info in class files (broken by
@@ -32,8 +32,6 @@ package org.videolan;
  *       in class file com/tcs/blr/bluray/pal/fox/controller/d
  */
 
-import sun.misc.ClassFileTransformer;
-
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.ClassVisitor;
@@ -41,7 +39,7 @@ import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Attribute;
 
-public class BDJClassFileTransformer extends ClassFileTransformer
+class BDJClassFileTransformer
 {
     public byte[] transform(byte[] b, int off, int len)
         throws ClassFormatError
diff --git a/src/libbluray/bdj/java/org/videolan/BDJClassLoader.java b/src/libbluray/bdj/java/org/videolan/BDJClassLoader.java
index c3f2099..2eb3844 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJClassLoader.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJClassLoader.java
@@ -21,6 +21,7 @@ package org.videolan;
 
 import java.net.MalformedURLException;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.InputStream;
 import java.io.IOException;
@@ -138,6 +139,77 @@ public class BDJClassLoader extends URLClassLoader {
         }
     }
 
+    private byte[] loadClassCode(String name) throws ClassNotFoundException {
+        String path = name.replace('.', '/').concat(".class");
+
+        URL res = super.findResource(path);
+        if (res == null) {
+            logger.error("loadClassCode(): resource for class " + name + "not found");
+            throw new ClassNotFoundException(name);
+        }
+
+        InputStream is = null;
+        ByteArrayOutputStream os = null;
+        try {
+            is = res.openStream();
+            os = new ByteArrayOutputStream();
+            byte[] buffer = new byte[0xffff];
+            while (true) {
+                int r = is.read(buffer);
+                if (r == -1) break;
+                os.write(buffer, 0, r);
+            }
+
+            return os.toByteArray();
+
+        } catch (Exception e) {
+            logger.error("loadClassCode(" + name + ") failed: " + e);
+            throw new ClassNotFoundException(name);
+
+        } finally {
+            try {
+                if (is != null)
+                    is.close();
+            } catch (IOException ioe) {
+            }
+            try {
+                if (os != null)
+                    os.close();
+            } catch (IOException ioe) {
+            }
+        }
+    }
+
+    protected Class findClass(String name) throws ClassNotFoundException {
+        try {
+            return super.findClass(name);
+
+        } catch (ClassFormatError ce) {
+
+            /* try to "fix" broken class file */
+            /* if we got ClassFormatError, package was already created. */
+            byte[] b = loadClassCode(name);
+            if (b == null) {
+                logger.error("loadClassCode(" + name + ") failed");
+                /* this usually kills Xlet ... */
+                throw ce;
+            }
+            try {
+                b = new BDJClassFileTransformer().transform(b, 0, b.length);
+                return defineClass(b, 0, b.length);
+            } catch (ThreadDeath td) {
+                throw td;
+            } catch (Throwable t) {
+                logger.error("Class rewriting failed: " + t);
+                throw new ClassNotFoundException(name);
+            }
+
+        } catch (Error er) {
+            logger.error("Unexpected error: " + er + " " + Logger.dumpStack(er));
+            throw er;
+        }
+    }
+
     public URL getResource(String name) {
         name = name.replace('\\', '/');
         return super.getResource(name);
diff --git a/src/libbluray/bdj/java/org/videolan/Libbluray.java b/src/libbluray/bdj/java/org/videolan/Libbluray.java
index f2f6078..e46ebfa 100644
--- a/src/libbluray/bdj/java/org/videolan/Libbluray.java
+++ b/src/libbluray/bdj/java/org/videolan/Libbluray.java
@@ -81,13 +81,6 @@ public class Libbluray {
             System.err.println("hookProperties() failed: " + t);
         }
 
-        /* hook class loading (fix invalid class files) */
-        try {
-            sun.misc.ClassFileTransformer.add(new BDJClassFileTransformer());
-        } catch (Throwable t) {
-            System.err.println("Adding class file transformer failed: " + t);
-        }
-
         /* hook sockets (limit network connections) */
         try {
             BDJSocketFactory.init();



More information about the libbluray-devel mailing list