/** Use the given ClassLoader rather than using the system class */ @SuppressWarnings("rawtypes") protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { String cname = classDesc.getName(); return ClassFinder.resolveClass(cname, this.loader); }
/** * Instantiate a bean. * * <p>The bean is created based on a name relative to a class-loader. This name should be a * dot-separated name such as "a.b.c". * * <p>In Beans 1.0 the given name can indicate either a serialized object or a class. Other * mechanisms may be added in the future. In beans 1.0 we first try to treat the beanName as a * serialized object name then as a class name. * * <p>When using the beanName as a serialized object name we convert the given beanName to a * resource pathname and add a trailing ".ser" suffix. We then try to load a serialized object * from that resource. * * <p>For example, given a beanName of "x.y", Beans.instantiate would first try to read a * serialized object from the resource "x/y.ser" and if that failed it would try to load the class * "x.y" and create an instance of that class. * * <p>If the bean is a subtype of java.applet.Applet, then it is given some special * initialization. First, it is supplied with a default AppletStub and AppletContext. Second, if * it was instantiated from a classname the applet's "init" method is called. (If the bean was * deserialized this step is skipped.) * * <p>Note that for beans which are applets, it is the caller's responsiblity to call "start" on * the applet. For correct behaviour, this should be done after the applet has been added into a * visible AWT container. * * <p>Note that applets created via beans.instantiate run in a slightly different environment than * applets running inside browsers. In particular, bean applets have no access to "parameters", so * they may wish to provide property get/set methods to set parameter values. We advise * bean-applet developers to test their bean-applets against both the JDK appletviewer (for a * reference browser environment) and the BDK BeanBox (for a reference bean container). * * @return a JavaBean * @param cls the class-loader from which we should create the bean. If this is null, then the * system class-loader is used. * @param beanName the name of the bean within the class-loader. For example "sun.beanbox.foobah" * @param beanContext The BeanContext in which to nest the new bean * @param initializer The AppletInitializer for the new bean * @exception ClassNotFoundException if the class of a serialized object could not be found. * @exception IOException if an I/O error occurs. */ public static Object instantiate( ClassLoader cls, String beanName, BeanContext beanContext, AppletInitializer initializer) throws IOException, ClassNotFoundException { InputStream ins; ObjectInputStream oins = null; Object result = null; boolean serialized = false; IOException serex = null; // If the given classloader is null, we check if an // system classloader is available and (if so) // use that instead. // Note that calls on the system class loader will // look in the bootstrap class loader first. if (cls == null) { try { cls = ClassLoader.getSystemClassLoader(); } catch (SecurityException ex) { // We're not allowed to access the system class loader. // Drop through. } } // Try to find a serialized object with this name final String serName = beanName.replace('.', '/').concat(".ser"); final ClassLoader loader = cls; ins = AccessController.doPrivileged( new PrivilegedAction<InputStream>() { public InputStream run() { if (loader == null) return ClassLoader.getSystemResourceAsStream(serName); else return loader.getResourceAsStream(serName); } }); if (ins != null) { try { if (cls == null) { oins = new ObjectInputStream(ins); } else { oins = new ObjectInputStreamWithLoader(ins, cls); } result = oins.readObject(); serialized = true; oins.close(); } catch (IOException ex) { ins.close(); // Drop through and try opening the class. But remember // the exception in case we can't find the class either. serex = ex; } catch (ClassNotFoundException ex) { ins.close(); throw ex; } } if (result == null) { // No serialized object, try just instantiating the class Class<?> cl; try { cl = ClassFinder.findClass(beanName, cls); } catch (ClassNotFoundException ex) { // There is no appropriate class. If we earlier tried to // deserialize an object and got an IO exception, throw that, // otherwise rethrow the ClassNotFoundException. if (serex != null) { throw serex; } throw ex; } if (!Modifier.isPublic(cl.getModifiers())) { throw new ClassNotFoundException("" + cl + " : no public access"); } /* * Try to instantiate the class. */ try { result = cl.newInstance(); } catch (Exception ex) { // We have to remap the exception to one in our signature. // But we pass extra information in the detail message. throw new ClassNotFoundException("" + cl + " : " + ex, ex); } } if (result != null) { // Ok, if the result is an applet initialize it. AppletStub stub = null; if (result instanceof Applet) { Applet applet = (Applet) result; boolean needDummies = initializer == null; if (needDummies) { // Figure our the codebase and docbase URLs. We do this // by locating the URL for a known resource, and then // massaging the URL. // First find the "resource name" corresponding to the bean // itself. So a serialzied bean "a.b.c" would imply a // resource name of "a/b/c.ser" and a classname of "x.y" // would imply a resource name of "x/y.class". final String resourceName; if (serialized) { // Serialized bean resourceName = beanName.replace('.', '/').concat(".ser"); } else { // Regular class resourceName = beanName.replace('.', '/').concat(".class"); } URL objectUrl = null; URL codeBase = null; URL docBase = null; // Now get the URL correponding to the resource name. final ClassLoader cloader = cls; objectUrl = AccessController.doPrivileged( new PrivilegedAction<URL>() { public URL run() { if (cloader == null) return ClassLoader.getSystemResource(resourceName); else return cloader.getResource(resourceName); } }); // If we found a URL, we try to locate the docbase by taking // of the final path name component, and the code base by taking // of the complete resourceName. // So if we had a resourceName of "a/b/c.class" and we got an // objectURL of "file://bert/classes/a/b/c.class" then we would // want to set the codebase to "file://bert/classes/" and the // docbase to "file://bert/classes/a/b/" if (objectUrl != null) { String s = objectUrl.toExternalForm(); if (s.endsWith(resourceName)) { int ix = s.length() - resourceName.length(); codeBase = new URL(s.substring(0, ix)); docBase = codeBase; ix = s.lastIndexOf('/'); if (ix >= 0) { docBase = new URL(s.substring(0, ix + 1)); } } } // Setup a default context and stub. BeansAppletContext context = new BeansAppletContext(applet); stub = (AppletStub) new BeansAppletStub(applet, context, codeBase, docBase); applet.setStub(stub); } else { initializer.initialize(applet, beanContext); } // now, if there is a BeanContext, add the bean, if applicable. if (beanContext != null) { unsafeBeanContextAdd(beanContext, result); } // If it was deserialized then it was already init-ed. // Otherwise we need to initialize it. if (!serialized) { // We need to set a reasonable initial size, as many // applets are unhappy if they are started without // having been explicitly sized. applet.setSize(100, 100); applet.init(); } if (needDummies) { ((BeansAppletStub) stub).active = true; } else initializer.activate(applet); } else if (beanContext != null) unsafeBeanContextAdd(beanContext, result); } return result; }