[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