# HG changeset patch # User Jaroslav Tulach # Date 1371134897 -7200 # Node ID 15c6903c86120028b6a96bb7bd922c435588572d # Parent f78cdceed17bef61950427f7081ff5632def9dbc New classloader can be used to load the twitter application diff -r f78cdceed17b -r 15c6903c8612 launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java Wed Jun 12 18:19:29 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java Thu Jun 13 16:48:17 2013 +0200 @@ -18,6 +18,10 @@ package org.apidesign.bck2brwsr.launcher.fximpl; import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; import java.util.TooManyListenersException; import javafx.beans.value.ChangeListener; import javafx.scene.web.WebEngine; @@ -76,6 +80,20 @@ } return null; } + + @Override + protected Enumeration findResources(String name) { + List arr = new ArrayList(); + if (ldrs != null) { + for (ClassLoader l : ldrs) { + URL u = l.getResource(name); + if (u != null) { + arr.add(u); + } + } + } + return Collections.enumeration(arr); + } @Override protected Fn defineFn(String code, String... names) { diff -r f78cdceed17b -r 15c6903c8612 launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java Wed Jun 12 18:19:29 2013 +0200 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java Thu Jun 13 16:48:17 2013 +0200 @@ -20,8 +20,9 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; -import java.net.URLClassLoader; +import java.net.URLConnection; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassReader; @@ -45,6 +46,9 @@ @Override protected abstract URL findResource(String name); + + @Override + protected abstract Enumeration findResources(String name); @Override protected Class findClass(String name) throws ClassNotFoundException { @@ -53,12 +57,25 @@ InputStream is = null; try { is = u.openStream(); - ClassReader cr = new ClassReader(is); - ClassWriter w = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); - FindInClass fic = new FindInClass(w); - cr.accept(fic, 0); - byte[] arr = w.toByteArray(); - return defineClass(name, arr, 0, arr.length); + byte[] arr = new byte[is.available()]; + int len = is.read(arr); + if (len != arr.length) { + arr = null; + } + is.close(); + is = null; + ClassReader cr = new ClassReader(arr); + FindInClass tst = new FindInClass(null); + cr.accept(tst, 0); + if (tst.found) { + ClassWriter w = new ClassWriterEx(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + FindInClass fic = new FindInClass(w); + cr.accept(fic, 0); + arr = w.toByteArray(); + } + if (arr != null) { + return defineClass(name, arr, 0, arr.length); + } } catch (IOException ex) { throw new ClassNotFoundException("Can't load " + name, ex); } finally { @@ -81,6 +98,7 @@ private static final class FindInClass extends ClassVisitor { private String name; + private boolean found; public FindInClass(ClassVisitor cv) { super(Opcodes.ASM4, cv); @@ -116,6 +134,7 @@ @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if ("Lorg/apidesign/bck2brwsr/core/JavaScriptBody;".equals(desc)) { // NOI18N + found = true; return new FindInAnno(); } return super.visitAnnotation(desc, visible); @@ -297,4 +316,37 @@ } } } + + private class ClassWriterEx extends ClassWriter { + + public ClassWriterEx(ClassReader classReader, int flags) { + super(classReader, flags); + } + + @Override + protected String getCommonSuperClass(final String type1, final String type2) { + Class c, d; + ClassLoader classLoader = JsClassLoader.this; + try { + c = Class.forName(type1.replace('/', '.'), false, classLoader); + d = Class.forName(type2.replace('/', '.'), false, classLoader); + } catch (Exception e) { + throw new RuntimeException(e.toString()); + } + if (c.isAssignableFrom(d)) { + return type1; + } + if (d.isAssignableFrom(c)) { + return type2; + } + if (c.isInterface() || d.isInterface()) { + return "java/lang/Object"; + } else { + do { + c = c.getSuperclass(); + } while (!c.isAssignableFrom(d)); + return c.getName().replace('.', '/'); + } + } + } } diff -r f78cdceed17b -r 15c6903c8612 launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java --- a/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java Wed Jun 12 18:19:29 2013 +0200 +++ b/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java Thu Jun 13 16:48:17 2013 +0200 @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; +import java.util.Enumeration; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; @@ -84,6 +85,11 @@ throw new LinkageError("Can't parse: " + sb, ex); } } + + @Override + protected Enumeration findResources(String name) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } }; methodClass = loader.loadClass(JsMethods.class.getName());