libbluray | branch: master | hpi1 <[email protected]> | 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(); _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
