src/share/classes/sun/applet/AppletClassLoader.java

Print this page
rev 10175 : 8042872: Fix raw and unchecked warnings in sun.applet
Reviewed-by:


 120      */
 121     protected void addJar(String name) throws IOException {
 122         URL url;
 123         try {
 124             url = new URL(base, name);
 125         } catch (MalformedURLException e) {
 126             throw new IllegalArgumentException("name");
 127         }
 128         addURL(url);
 129         // DEBUG
 130         //URL[] urls = getURLs();
 131         //for (int i = 0; i < urls.length; i++) {
 132         //    System.out.println("url[" + i + "] = " + urls[i]);
 133         //}
 134     }
 135 
 136     /*
 137      * Override loadClass so that class loading errors can be caught in
 138      * order to print better error messages.
 139      */
 140     public synchronized Class loadClass(String name, boolean resolve)
 141         throws ClassNotFoundException
 142     {
 143         // First check if we have permission to access the package. This
 144         // should go away once we've added support for exported packages.
 145         int i = name.lastIndexOf('.');
 146         if (i != -1) {
 147             SecurityManager sm = System.getSecurityManager();
 148             if (sm != null)
 149                 sm.checkPackageAccess(name.substring(0, i));
 150         }
 151         try {
 152             return super.loadClass(name, resolve);
 153         } catch (ClassNotFoundException e) {
 154             //printError(name, e.getException());
 155             throw e;
 156         } catch (RuntimeException e) {
 157             //printError(name, e);
 158             throw e;
 159         } catch (Error e) {
 160             //printError(name, e);
 161             throw e;
 162         }
 163     }
 164 
 165     /*
 166      * Finds the applet class with the specified name. First searches
 167      * loaded JAR files then the applet code base for the class.
 168      */
 169     protected Class findClass(String name) throws ClassNotFoundException {
 170 
 171         int index = name.indexOf(';');
 172         String cookie = "";
 173         if(index != -1) {
 174                 cookie = name.substring(index, name.length());
 175                 name = name.substring(0, index);
 176         }
 177 
 178         // check loaded JAR files
 179         try {
 180             return super.findClass(name);
 181         } catch (ClassNotFoundException e) {
 182         }
 183 
 184         // Otherwise, try loading the class from the code base URL
 185 
 186         // 4668479: Option to turn off codebase lookup in AppletClassLoader
 187         // during resource requests. [stanley.ho]
 188         if (codebaseLookup == false)
 189             throw new ClassNotFoundException(name);
 190 
 191 //      final String path = name.replace('.', '/').concat(".class").concat(cookie);
 192         String encodedName = ParseUtil.encodePath(name.replace('.', '/'), false);
 193         final String path = (new StringBuffer(encodedName)).append(".class").append(cookie).toString();
 194         try {
 195             byte[] b = (byte[]) AccessController.doPrivileged(
 196                                new PrivilegedExceptionAction() {
 197                 public Object run() throws IOException {
 198                    try {
 199                         URL finalURL = new URL(base, path);
 200 
 201                         // Make sure the codebase won't be modified
 202                         if (base.getProtocol().equals(finalURL.getProtocol()) &&
 203                             base.getHost().equals(finalURL.getHost()) &&
 204                             base.getPort() == finalURL.getPort()) {
 205                             return getBytes(finalURL);
 206                         }
 207                         else {
 208                             return null;
 209                         }
 210                     } catch (Exception e) {
 211                         return null;
 212                     }
 213                 }
 214             }, acc);
 215 
 216             if (b != null) {
 217                 return defineClass(name, b, 0, b.length, codesource);


 539                  *
 540                  * The same connection should be reused to avoid multiple
 541                  * HTTP connections
 542                  */
 543 
 544                 // our best guess for the other cases
 545                 InputStream is = conn.getInputStream();
 546                 is.close();
 547             }
 548         } catch (Exception ex) {
 549             ok = false;
 550         }
 551         return ok;
 552     }
 553 
 554     /*
 555      * Returns an enumeration of all the applet resources with the specified
 556      * name. First checks loaded JAR files then the applet code base for all
 557      * available resources.
 558      */
 559     public Enumeration findResources(String name) throws IOException {

 560 
 561         final Enumeration e = super.findResources(name);
 562 
 563         // 6215746:  Disable META-INF/* lookup from codebase in
 564         // applet/plugin classloader. [stanley.ho]
 565         if (name.startsWith("META-INF/"))
 566             return e;
 567 
 568         // 4668479: Option to turn off codebase lookup in AppletClassLoader
 569         // during resource requests. [stanley.ho]
 570         if (codebaseLookup == false)
 571             return e;
 572 
 573         URL u = new URL(base, ParseUtil.encodePath(name, false));
 574         if (!resourceExists(u)) {
 575             u = null;
 576         }
 577 
 578         final URL url = u;
 579         return new Enumeration() {
 580             private boolean done;
 581             public Object nextElement() {
 582                 if (!done) {
 583                     if (e.hasMoreElements()) {
 584                         return e.nextElement();
 585                     }
 586                     done = true;
 587                     if (url != null) {
 588                         return url;
 589                     }
 590                 }
 591                 throw new NoSuchElementException();
 592             }
 593             public boolean hasMoreElements() {
 594                 return !done && (e.hasMoreElements() || url != null);
 595             }
 596         };
 597     }
 598 
 599     /*
 600      * Load and resolve the file specified by the applet tag CODE
 601      * attribute. The argument can either be the relative path
 602      * of the class file itself or just the name of the class.
 603      */
 604     Class loadCode(String name) throws ClassNotFoundException {
 605         // first convert any '/' or native file separator to .
 606         name = name.replace('/', '.');
 607         name = name.replace(File.separatorChar, '.');
 608 
 609         // deal with URL rewriting
 610         String cookie = null;
 611         int index = name.indexOf(';');
 612         if(index != -1) {
 613                 cookie = name.substring(index, name.length());
 614                 name = name.substring(0, index);
 615         }
 616 
 617         // save that name for later
 618         String fullName = name;
 619         // then strip off any suffixes
 620         if (name.endsWith(".class") || name.endsWith(".java")) {
 621             name = name.substring(0, name.lastIndexOf('.'));
 622         }
 623         try {
 624                 if(cookie != null)


 629         // then if it didn't end with .java or .class, or in the
 630         // really pathological case of a class named class or java
 631         if(cookie != null)
 632                 fullName = (new StringBuffer(fullName)).append(cookie).toString();
 633 
 634         return loadClass(fullName);
 635     }
 636 
 637     /*
 638      * The threadgroup that the applets loaded by this classloader live
 639      * in. In the sun.* implementation of applets, the security manager's
 640      * (AppletSecurity) getThreadGroup returns the thread group of the
 641      * first applet on the stack, which is the applet's thread group.
 642      */
 643     private AppletThreadGroup threadGroup;
 644     private AppContext appContext;
 645 
 646     public ThreadGroup getThreadGroup() {
 647       synchronized (threadGroupSynchronizer) {
 648         if (threadGroup == null || threadGroup.isDestroyed()) {
 649             AccessController.doPrivileged(new PrivilegedAction() {
 650                 public Object run() {
 651                     threadGroup = new AppletThreadGroup(base + "-threadGroup");
 652                     // threadGroup.setDaemon(true);
 653                     // threadGroup is now destroyed by AppContext.dispose()
 654 
 655                     // Create the new AppContext from within a Thread belonging
 656                     // to the newly created ThreadGroup, and wait for the
 657                     // creation to complete before returning from this method.
 658                     AppContextCreator creatorThread = new AppContextCreator(threadGroup);
 659 
 660                     // Since this thread will later be used to launch the
 661                     // applet's AWT-event dispatch thread and we want the applet
 662                     // code executing the AWT callbacks to use their own class
 663                     // loader rather than the system class loader, explicitly
 664                     // set the context class loader to the AppletClassLoader.
 665                     creatorThread.setContextClassLoader(AppletClassLoader.this);
 666 
 667                     creatorThread.start();
 668                     try {
 669                         synchronized(creatorThread.syncObject) {


 753      * not dispose the AppContext. PluginClassLoader does not
 754      * use UsageCount to decide whether to dispose AppContext
 755      *
 756      * @return previous AppContext
 757      */
 758     protected AppContext resetAppContext() {
 759         AppContext tempAppContext = null;
 760 
 761         synchronized(threadGroupSynchronizer) {
 762             // Store app context in temp variable
 763             tempAppContext = appContext;
 764             usageCount = 0;
 765             appContext = null;
 766             threadGroup = null;
 767         }
 768         return tempAppContext;
 769     }
 770 
 771 
 772     // Hash map to store applet compatibility info
 773     private HashMap jdk11AppletInfo = new HashMap();
 774     private HashMap jdk12AppletInfo = new HashMap();
 775 
 776     /**
 777      * Set applet target level as JDK 1.1.
 778      *
 779      * @param clazz Applet class.
 780      * @param bool true if JDK is targeted for JDK 1.1;
 781      *             false otherwise.
 782      */
 783     void setJDK11Target(Class clazz, boolean bool)
 784     {
 785          jdk11AppletInfo.put(clazz.toString(), Boolean.valueOf(bool));
 786     }
 787 
 788     /**
 789      * Set applet target level as JDK 1.2.
 790      *
 791      * @param clazz Applet class.
 792      * @param bool true if JDK is targeted for JDK 1.2;
 793      *             false otherwise.
 794      */
 795     void setJDK12Target(Class clazz, boolean bool)
 796     {
 797         jdk12AppletInfo.put(clazz.toString(), Boolean.valueOf(bool));
 798     }
 799 
 800     /**
 801      * Determine if applet is targeted for JDK 1.1.
 802      *
 803      * @param applet Applet class.
 804      * @return TRUE if applet is targeted for JDK 1.1;
 805      *         FALSE if applet is not;
 806      *         null if applet is unknown.
 807      */
 808     Boolean isJDK11Target(Class clazz)
 809     {
 810         return (Boolean) jdk11AppletInfo.get(clazz.toString());
 811     }
 812 
 813     /**
 814      * Determine if applet is targeted for JDK 1.2.
 815      *
 816      * @param applet Applet class.
 817      * @return TRUE if applet is targeted for JDK 1.2;
 818      *         FALSE if applet is not;
 819      *         null if applet is unknown.
 820      */
 821     Boolean isJDK12Target(Class clazz)
 822     {
 823         return (Boolean) jdk12AppletInfo.get(clazz.toString());
 824     }
 825 
 826     private static AppletMessageHandler mh =
 827         new AppletMessageHandler("appletclassloader");
 828 
 829     /*
 830      * Prints a class loading error message.
 831      */
 832     private static void printError(String name, Throwable e) {
 833         String s = null;
 834         if (e == null) {
 835             s = mh.getMessage("filenotfound", name);
 836         } else if (e instanceof IOException) {
 837             s = mh.getMessage("fileioexception", name);
 838         } else if (e instanceof ClassFormatError) {
 839             s = mh.getMessage("fileformat", name);
 840         } else if (e instanceof ThreadDeath) {
 841             s = mh.getMessage("filedeath", name);
 842         } else if (e instanceof Error) {
 843             s = mh.getMessage("fileerror", e.toString(), name);




 120      */
 121     protected void addJar(String name) throws IOException {
 122         URL url;
 123         try {
 124             url = new URL(base, name);
 125         } catch (MalformedURLException e) {
 126             throw new IllegalArgumentException("name");
 127         }
 128         addURL(url);
 129         // DEBUG
 130         //URL[] urls = getURLs();
 131         //for (int i = 0; i < urls.length; i++) {
 132         //    System.out.println("url[" + i + "] = " + urls[i]);
 133         //}
 134     }
 135 
 136     /*
 137      * Override loadClass so that class loading errors can be caught in
 138      * order to print better error messages.
 139      */
 140     public synchronized Class<?> loadClass(String name, boolean resolve)
 141         throws ClassNotFoundException
 142     {
 143         // First check if we have permission to access the package. This
 144         // should go away once we've added support for exported packages.
 145         int i = name.lastIndexOf('.');
 146         if (i != -1) {
 147             SecurityManager sm = System.getSecurityManager();
 148             if (sm != null)
 149                 sm.checkPackageAccess(name.substring(0, i));
 150         }
 151         try {
 152             return super.loadClass(name, resolve);
 153         } catch (ClassNotFoundException e) {
 154             //printError(name, e.getException());
 155             throw e;
 156         } catch (RuntimeException e) {
 157             //printError(name, e);
 158             throw e;
 159         } catch (Error e) {
 160             //printError(name, e);
 161             throw e;
 162         }
 163     }
 164 
 165     /*
 166      * Finds the applet class with the specified name. First searches
 167      * loaded JAR files then the applet code base for the class.
 168      */
 169     protected Class<?> findClass(String name) throws ClassNotFoundException {
 170 
 171         int index = name.indexOf(';');
 172         String cookie = "";
 173         if(index != -1) {
 174                 cookie = name.substring(index, name.length());
 175                 name = name.substring(0, index);
 176         }
 177 
 178         // check loaded JAR files
 179         try {
 180             return super.findClass(name);
 181         } catch (ClassNotFoundException e) {
 182         }
 183 
 184         // Otherwise, try loading the class from the code base URL
 185 
 186         // 4668479: Option to turn off codebase lookup in AppletClassLoader
 187         // during resource requests. [stanley.ho]
 188         if (codebaseLookup == false)
 189             throw new ClassNotFoundException(name);
 190 
 191 //      final String path = name.replace('.', '/').concat(".class").concat(cookie);
 192         String encodedName = ParseUtil.encodePath(name.replace('.', '/'), false);
 193         final String path = (new StringBuffer(encodedName)).append(".class").append(cookie).toString();
 194         try {
 195             byte[] b = AccessController.doPrivileged(
 196                                new PrivilegedExceptionAction<byte[]>() {
 197                 public byte[] run() throws IOException {
 198                    try {
 199                         URL finalURL = new URL(base, path);
 200 
 201                         // Make sure the codebase won't be modified
 202                         if (base.getProtocol().equals(finalURL.getProtocol()) &&
 203                             base.getHost().equals(finalURL.getHost()) &&
 204                             base.getPort() == finalURL.getPort()) {
 205                             return getBytes(finalURL);
 206                         }
 207                         else {
 208                             return null;
 209                         }
 210                     } catch (Exception e) {
 211                         return null;
 212                     }
 213                 }
 214             }, acc);
 215 
 216             if (b != null) {
 217                 return defineClass(name, b, 0, b.length, codesource);


 539                  *
 540                  * The same connection should be reused to avoid multiple
 541                  * HTTP connections
 542                  */
 543 
 544                 // our best guess for the other cases
 545                 InputStream is = conn.getInputStream();
 546                 is.close();
 547             }
 548         } catch (Exception ex) {
 549             ok = false;
 550         }
 551         return ok;
 552     }
 553 
 554     /*
 555      * Returns an enumeration of all the applet resources with the specified
 556      * name. First checks loaded JAR files then the applet code base for all
 557      * available resources.
 558      */
 559     @Override
 560     public Enumeration<URL> findResources(String name) throws IOException {
 561 
 562         final Enumeration<URL> e = super.findResources(name);
 563 
 564         // 6215746:  Disable META-INF/* lookup from codebase in
 565         // applet/plugin classloader. [stanley.ho]
 566         if (name.startsWith("META-INF/"))
 567             return e;
 568 
 569         // 4668479: Option to turn off codebase lookup in AppletClassLoader
 570         // during resource requests. [stanley.ho]
 571         if (codebaseLookup == false)
 572             return e;
 573 
 574         URL u = new URL(base, ParseUtil.encodePath(name, false));
 575         if (!resourceExists(u)) {
 576             u = null;
 577         }
 578 
 579         final URL url = u;
 580         return new Enumeration<URL>() {
 581             private boolean done;
 582             public URL nextElement() {
 583                 if (!done) {
 584                     if (e.hasMoreElements()) {
 585                         return e.nextElement();
 586                     }
 587                     done = true;
 588                     if (url != null) {
 589                         return url;
 590                     }
 591                 }
 592                 throw new NoSuchElementException();
 593             }
 594             public boolean hasMoreElements() {
 595                 return !done && (e.hasMoreElements() || url != null);
 596             }
 597         };
 598     }
 599 
 600     /*
 601      * Load and resolve the file specified by the applet tag CODE
 602      * attribute. The argument can either be the relative path
 603      * of the class file itself or just the name of the class.
 604      */
 605     Class<?> loadCode(String name) throws ClassNotFoundException {
 606         // first convert any '/' or native file separator to .
 607         name = name.replace('/', '.');
 608         name = name.replace(File.separatorChar, '.');
 609 
 610         // deal with URL rewriting
 611         String cookie = null;
 612         int index = name.indexOf(';');
 613         if(index != -1) {
 614                 cookie = name.substring(index, name.length());
 615                 name = name.substring(0, index);
 616         }
 617 
 618         // save that name for later
 619         String fullName = name;
 620         // then strip off any suffixes
 621         if (name.endsWith(".class") || name.endsWith(".java")) {
 622             name = name.substring(0, name.lastIndexOf('.'));
 623         }
 624         try {
 625                 if(cookie != null)


 630         // then if it didn't end with .java or .class, or in the
 631         // really pathological case of a class named class or java
 632         if(cookie != null)
 633                 fullName = (new StringBuffer(fullName)).append(cookie).toString();
 634 
 635         return loadClass(fullName);
 636     }
 637 
 638     /*
 639      * The threadgroup that the applets loaded by this classloader live
 640      * in. In the sun.* implementation of applets, the security manager's
 641      * (AppletSecurity) getThreadGroup returns the thread group of the
 642      * first applet on the stack, which is the applet's thread group.
 643      */
 644     private AppletThreadGroup threadGroup;
 645     private AppContext appContext;
 646 
 647     public ThreadGroup getThreadGroup() {
 648       synchronized (threadGroupSynchronizer) {
 649         if (threadGroup == null || threadGroup.isDestroyed()) {
 650             AccessController.doPrivileged(new PrivilegedAction<Object>() {
 651                 public Object run() {
 652                     threadGroup = new AppletThreadGroup(base + "-threadGroup");
 653                     // threadGroup.setDaemon(true);
 654                     // threadGroup is now destroyed by AppContext.dispose()
 655 
 656                     // Create the new AppContext from within a Thread belonging
 657                     // to the newly created ThreadGroup, and wait for the
 658                     // creation to complete before returning from this method.
 659                     AppContextCreator creatorThread = new AppContextCreator(threadGroup);
 660 
 661                     // Since this thread will later be used to launch the
 662                     // applet's AWT-event dispatch thread and we want the applet
 663                     // code executing the AWT callbacks to use their own class
 664                     // loader rather than the system class loader, explicitly
 665                     // set the context class loader to the AppletClassLoader.
 666                     creatorThread.setContextClassLoader(AppletClassLoader.this);
 667 
 668                     creatorThread.start();
 669                     try {
 670                         synchronized(creatorThread.syncObject) {


 754      * not dispose the AppContext. PluginClassLoader does not
 755      * use UsageCount to decide whether to dispose AppContext
 756      *
 757      * @return previous AppContext
 758      */
 759     protected AppContext resetAppContext() {
 760         AppContext tempAppContext = null;
 761 
 762         synchronized(threadGroupSynchronizer) {
 763             // Store app context in temp variable
 764             tempAppContext = appContext;
 765             usageCount = 0;
 766             appContext = null;
 767             threadGroup = null;
 768         }
 769         return tempAppContext;
 770     }
 771 
 772 
 773     // Hash map to store applet compatibility info
 774     private HashMap<String, Boolean> jdk11AppletInfo = new HashMap<>();
 775     private HashMap<String, Boolean> jdk12AppletInfo = new HashMap<>();
 776 
 777     /**
 778      * Set applet target level as JDK 1.1.
 779      *
 780      * @param clazz Applet class.
 781      * @param bool true if JDK is targeted for JDK 1.1;
 782      *             false otherwise.
 783      */
 784     void setJDK11Target(Class<?> clazz, boolean bool)
 785     {
 786          jdk11AppletInfo.put(clazz.toString(), Boolean.valueOf(bool));
 787     }
 788 
 789     /**
 790      * Set applet target level as JDK 1.2.
 791      *
 792      * @param clazz Applet class.
 793      * @param bool true if JDK is targeted for JDK 1.2;
 794      *             false otherwise.
 795      */
 796     void setJDK12Target(Class<?> clazz, boolean bool)
 797     {
 798         jdk12AppletInfo.put(clazz.toString(), Boolean.valueOf(bool));
 799     }
 800 
 801     /**
 802      * Determine if applet is targeted for JDK 1.1.
 803      *
 804      * @param applet Applet class.
 805      * @return TRUE if applet is targeted for JDK 1.1;
 806      *         FALSE if applet is not;
 807      *         null if applet is unknown.
 808      */
 809     Boolean isJDK11Target(Class<?> clazz)
 810     {
 811         return jdk11AppletInfo.get(clazz.toString());
 812     }
 813 
 814     /**
 815      * Determine if applet is targeted for JDK 1.2.
 816      *
 817      * @param applet Applet class.
 818      * @return TRUE if applet is targeted for JDK 1.2;
 819      *         FALSE if applet is not;
 820      *         null if applet is unknown.
 821      */
 822     Boolean isJDK12Target(Class<?> clazz)
 823     {
 824         return jdk12AppletInfo.get(clazz.toString());
 825     }
 826 
 827     private static AppletMessageHandler mh =
 828         new AppletMessageHandler("appletclassloader");
 829 
 830     /*
 831      * Prints a class loading error message.
 832      */
 833     private static void printError(String name, Throwable e) {
 834         String s = null;
 835         if (e == null) {
 836             s = mh.getMessage("filenotfound", name);
 837         } else if (e instanceof IOException) {
 838             s = mh.getMessage("fileioexception", name);
 839         } else if (e instanceof ClassFormatError) {
 840             s = mh.getMessage("fileformat", name);
 841         } else if (e instanceof ThreadDeath) {
 842             s = mh.getMessage("filedeath", name);
 843         } else if (e instanceof Error) {
 844             s = mh.getMessage("fileerror", e.toString(), name);