launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java
1.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java Wed Jun 12 18:19:29 2013 +0200
1.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java Thu Jun 13 16:48:17 2013 +0200
1.3 @@ -20,8 +20,9 @@
1.4 import java.io.IOException;
1.5 import java.io.InputStream;
1.6 import java.net.URL;
1.7 -import java.net.URLClassLoader;
1.8 +import java.net.URLConnection;
1.9 import java.util.ArrayList;
1.10 +import java.util.Enumeration;
1.11 import java.util.List;
1.12 import org.objectweb.asm.AnnotationVisitor;
1.13 import org.objectweb.asm.ClassReader;
1.14 @@ -45,6 +46,9 @@
1.15
1.16 @Override
1.17 protected abstract URL findResource(String name);
1.18 +
1.19 + @Override
1.20 + protected abstract Enumeration<URL> findResources(String name);
1.21
1.22 @Override
1.23 protected Class<?> findClass(String name) throws ClassNotFoundException {
1.24 @@ -53,12 +57,25 @@
1.25 InputStream is = null;
1.26 try {
1.27 is = u.openStream();
1.28 - ClassReader cr = new ClassReader(is);
1.29 - ClassWriter w = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
1.30 - FindInClass fic = new FindInClass(w);
1.31 - cr.accept(fic, 0);
1.32 - byte[] arr = w.toByteArray();
1.33 - return defineClass(name, arr, 0, arr.length);
1.34 + byte[] arr = new byte[is.available()];
1.35 + int len = is.read(arr);
1.36 + if (len != arr.length) {
1.37 + arr = null;
1.38 + }
1.39 + is.close();
1.40 + is = null;
1.41 + ClassReader cr = new ClassReader(arr);
1.42 + FindInClass tst = new FindInClass(null);
1.43 + cr.accept(tst, 0);
1.44 + if (tst.found) {
1.45 + ClassWriter w = new ClassWriterEx(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
1.46 + FindInClass fic = new FindInClass(w);
1.47 + cr.accept(fic, 0);
1.48 + arr = w.toByteArray();
1.49 + }
1.50 + if (arr != null) {
1.51 + return defineClass(name, arr, 0, arr.length);
1.52 + }
1.53 } catch (IOException ex) {
1.54 throw new ClassNotFoundException("Can't load " + name, ex);
1.55 } finally {
1.56 @@ -81,6 +98,7 @@
1.57
1.58 private static final class FindInClass extends ClassVisitor {
1.59 private String name;
1.60 + private boolean found;
1.61
1.62 public FindInClass(ClassVisitor cv) {
1.63 super(Opcodes.ASM4, cv);
1.64 @@ -116,6 +134,7 @@
1.65 @Override
1.66 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
1.67 if ("Lorg/apidesign/bck2brwsr/core/JavaScriptBody;".equals(desc)) { // NOI18N
1.68 + found = true;
1.69 return new FindInAnno();
1.70 }
1.71 return super.visitAnnotation(desc, visible);
1.72 @@ -297,4 +316,37 @@
1.73 }
1.74 }
1.75 }
1.76 +
1.77 + private class ClassWriterEx extends ClassWriter {
1.78 +
1.79 + public ClassWriterEx(ClassReader classReader, int flags) {
1.80 + super(classReader, flags);
1.81 + }
1.82 +
1.83 + @Override
1.84 + protected String getCommonSuperClass(final String type1, final String type2) {
1.85 + Class<?> c, d;
1.86 + ClassLoader classLoader = JsClassLoader.this;
1.87 + try {
1.88 + c = Class.forName(type1.replace('/', '.'), false, classLoader);
1.89 + d = Class.forName(type2.replace('/', '.'), false, classLoader);
1.90 + } catch (Exception e) {
1.91 + throw new RuntimeException(e.toString());
1.92 + }
1.93 + if (c.isAssignableFrom(d)) {
1.94 + return type1;
1.95 + }
1.96 + if (d.isAssignableFrom(c)) {
1.97 + return type2;
1.98 + }
1.99 + if (c.isInterface() || d.isInterface()) {
1.100 + return "java/lang/Object";
1.101 + } else {
1.102 + do {
1.103 + c = c.getSuperclass();
1.104 + } while (!c.isAssignableFrom(d));
1.105 + return c.getName().replace('.', '/');
1.106 + }
1.107 + }
1.108 + }
1.109 }