launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java
branchclassloader
changeset 1175 15c6903c8612
parent 1174 f78cdceed17b
child 1176 0250b8a739de
     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  }