/* * Creates a thread to run the applet. This method is called * each time an applet is loaded and reloaded. */ synchronized void createAppletThread() { // Create a thread group for the applet, and start a new // thread to load the applet. String nm = "applet-" + getCode(); loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey()); loader.grab(); // Keep this puppy around! // 4668479: Option to turn off codebase lookup in AppletClassLoader // during resource requests. [stanley.ho] String param = getParameter("codebase_lookup"); if (param != null && param.equals("false")) loader.setCodebaseLookup(false); else loader.setCodebaseLookup(true); ThreadGroup appletGroup = loader.getThreadGroup(); handler = new Thread(appletGroup, this, "thread " + nm, 0, false); // set the context class loader for this thread AccessController.doPrivileged( new PrivilegedAction<Object>() { @Override public Object run() { handler.setContextClassLoader(loader); return null; } }); handler.start(); }
/** Is called when the applet wants to be resized. */ @Override public void appletResize(int width, int height) { currentAppletSize.width = width; currentAppletSize.height = height; final Dimension currentSize = new Dimension(currentAppletSize.width, currentAppletSize.height); if (loader != null) { AppContext appCtxt = loader.getAppContext(); if (appCtxt != null) appEvtQ = (java.awt.EventQueue) appCtxt.get(AppContext.EVENT_QUEUE_KEY); } final AppletPanel ap = this; if (appEvtQ != null) { appEvtQ.postEvent( new InvocationEvent( Toolkit.getDefaultToolkit(), new Runnable() { @Override public void run() { if (ap != null) { ap.dispatchAppletEvent(APPLET_RESIZE, currentSize); } } })); } }
/** * This kludge is specific to get over AccessControlException thrown during Applet.stop() or * destroy() when static thread is suspended. Set a flag in AppletClassLoader to indicate that an * AccessControlException for RuntimePermission "modifyThread" or "modifyThreadGroup" had * occurred. */ private void setExceptionStatus(AccessControlException e) { Permission p = e.getPermission(); if (p instanceof RuntimePermission) { if (p.getName().startsWith("modifyThread")) { if (loader == null) loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey()); loader.setExceptionStatus(); } } }
protected void loadJarFiles(AppletClassLoader loader) throws IOException, InterruptedException { // Load the archives if present. // REMIND - this probably should be done in a separate thread, // or at least the additional archives (epll). String jarFiles = getJarFiles(); if (jarFiles != null) { StringTokenizer st = new StringTokenizer(jarFiles, ",", false); while (st.hasMoreTokens()) { String tok = st.nextToken().trim(); try { loader.addJar(tok); } catch (IllegalArgumentException e) { // bad archive name continue; } } } }
protected Applet createApplet(final AppletClassLoader loader) throws ClassNotFoundException, IllegalAccessException, IOException, InstantiationException, InterruptedException { String code = getCode(); if (code != null) { applet = (Applet) loader.loadCode(code).newInstance(); } else { String msg = "nocode"; status = APPLET_ERROR; showAppletStatus(msg); showAppletLog(msg); repaint(); } // Determine the JDK level that the applet targets. // This is critical for enabling certain backward // compatibility switch if an applet is a JDK 1.1 // applet. [stanley.ho] findAppletJDKLevel(applet); if (Thread.interrupted()) { try { status = APPLET_DISPOSE; // APPLET_ERROR? applet = null; // REMIND: This may not be exactly the right thing: the // status is set by the stop button and not necessarily // here. showAppletStatus("death"); } finally { Thread.currentThread().interrupt(); // resignal interrupt } return null; } return applet; }
void release() { if (loader != null) { loader.release(); loader = null; } }
/** Determine JDK level of an applet. */ private void findAppletJDKLevel(Applet applet) { // To determine the JDK level of an applet, the // most reliable way is to check the major version // of the applet class file. // synchronized on applet class object, so calling from // different instances of the same applet will be // serialized. Class<?> appletClass = applet.getClass(); synchronized (appletClass) { // Determine if the JDK level of an applet has been // checked before. Boolean jdk11Target = loader.isJDK11Target(appletClass); Boolean jdk12Target = loader.isJDK12Target(appletClass); // if applet JDK level has been checked before, retrieve // value and return. if (jdk11Target != null || jdk12Target != null) { jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue(); jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue(); return; } String name = appletClass.getName(); // first convert any '.' to '/' name = name.replace('.', '/'); // append .class final String resourceName = name + ".class"; byte[] classHeader = new byte[8]; try (InputStream is = AccessController.doPrivileged( (PrivilegedAction<InputStream>) () -> loader.getResourceAsStream(resourceName))) { // Read the first 8 bytes of the class file int byteRead = is.read(classHeader, 0, 8); // return if the header is not read in entirely // for some reasons. if (byteRead != 8) return; } catch (IOException e) { return; } // Check major version in class file header int major_version = readShort(classHeader, 6); // Major version in class file is as follows: // 45 - JDK 1.1 // 46 - JDK 1.2 // 47 - JDK 1.3 // 48 - JDK 1.4 // 49 - JDK 1.5 if (major_version < 46) jdk11Applet = true; else if (major_version == 46) jdk12Applet = true; // Store applet JDK level in AppContext for later lookup, // e.g. page switch. loader.setJDK11Target(appletClass, jdk11Applet); loader.setJDK12Target(appletClass, jdk12Applet); } }