Class JNLPClassLoader

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable

    public class JNLPClassLoader
    extends java.net.URLClassLoader
    Classloader that takes it's resources from a JNLP file. If the JNLP file defines extensions, separate classloaders for these will be created automatically. Classes are loaded with the security context when the classloader was created.
    Version:
    $Revision: 1.20 $
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.security.AccessControlContext acc
      security context
      private java.util.Set<UrlKey> alreadyTried  
      private ApplicationInstance app
      the app
      private static java.lang.String APPLICATION  
      private java.util.List<JARDesc> available
      all jars not yet part of classloader or active Synchronized since this field may become shared data between multiple classloading threads.
      private java.util.Set<java.lang.String> classpaths
      Set of classpath strings declared in the manifest.mf files Synchronized since this field may become shared data between multiple classloading threads.
      private CodeBaseClassLoader codeBaseLoader
      Loader for codebase (which is a path, rather than a file)
      private boolean enableCodeBase  
      private JNLPFile file
      the JNLP file
      private static java.lang.String FILE_READ_ACTION  
      private boolean foundMainJar
      True if the jar with the main class has been found
      private boolean isSignedJNLP
      True if the application has a signed JNLP File
      private java.util.Set<java.lang.String> jarEntries
      File entries in the jar files available to this classloader Synchronized sinc this field may become shared data between multiple classloading threads.
      private java.util.List<JarIndexAccess> jarIndexes
      ArrayList containing jar indexes for various jars available to this classloader Synchronized since this field may become shared data between multiple classloading threads/ See loadClass(String) and CodebaseClassLoader.findClassNonRecursive(String).
      (package private) java.util.Map<UrlKey,​SecurityDesc> jarLocationSecurityMap
      Map of specific original (remote) CodeSource Urls to securitydesc Synchronized since this field may become shared data between multiple classloading threads.
      (package private) JarCertVerifier jcv
      the jar cert verifier tool to verify our jars
      private JNLPClassLoader[] loaders
      list of this, local and global loaders this loader uses
      private static Logger LOG  
      private ManifestAttributesChecker mac  
      private java.lang.String mainClass
      Name of the application's main class
      private NativeLibraryStorage nativeLibraryStorage
      Provides a search path & temporary storage for native code
      private java.util.List<java.security.Permission> resourcePermissions
      the permissions for the cached jar files
      private ResourcesDesc resources
      the resources section
      private java.util.ArrayList<java.security.Permission> runtimePermissions
      Permissions granted by the user during runtime.
      private SecurityDesc security
      the security section
      private SecurityDelegate securityDelegate  
      private JNLPClassLoader.SigningState signing  
      private boolean strict
      whether to strictly adhere to the spec or not
      private static java.lang.String TEMPLATE
      Signed JNLP File and Template
      private ResourceTracker tracker
      loads the resources
      private static java.util.Map<java.lang.String,​JNLPClassLoader> uniqueKeyToLoader
      map from JNLPFile unique key to shared classloader
      private static java.util.Map<java.lang.String,​java.util.concurrent.locks.ReentrantLock> uniqueKeyToLock
      map from JNLPFile unique key to lock, the lock is needed to enforce correct initialization of applets that share a unique key
      private UpdatePolicy updatePolicy
      the update policy for resources
      private int useCount
      Variable to track how many times this loader is in use
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
        JNLPClassLoader​(JNLPFile file, UpdatePolicy policy)
      Create a new JNLPClassLoader from the specified file.
      private JNLPClassLoader​(JNLPFile file, UpdatePolicy policy, java.lang.String mainName, boolean enableCodeBase)
      Create a new JNLPClassLoader from the specified file.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      (package private) void activateJars​(java.util.List<JARDesc> jars)
      Ensures that the list of jars have all been transferred, and makes them available to the classloader.
      private void addAvailable()
      Adds whatever resources have already been downloaded in the background.
      private void addNewJar​(JARDesc desc)
      Adds a new JARDesc into this classloader.
      private void addNewJar​(JARDesc desc, UpdatePolicy updatePolicy)
      Adds a new JARDesc into this classloader.
      private JNLPClassLoader addNextResource()
      Adds the next unused resource to the classloader.
      void addPermission​(java.security.Permission p)  
      private void addToCodeBaseLoader​(java.net.URL u)
      Adds the given path to the path loader
      private SecurityDesc checkEnforceable​(SecurityDesc desc)
      Without a SecurityManager every permission set is effectively AllPermission, so anything less than all-permissions cannot be honoured.
      (package private) void checkForMain​(java.util.List<JARDesc> jars)
      * Checks for the jar that contains the main class.
      (package private) void checkPartialSigningWithUser()
      Call this when it's suspected that an applet's permission level may have just changed from Full Signing to Partial Signing.
      private void checkTrustWithUser()
      Prompt the user for trust on all the signers that require approval.
      (package private) static void consultCertificateSecurityException​(LaunchException ex)  
      private static JNLPClassLoader createInstance​(JNLPFile file, UpdatePolicy policy, java.lang.String mainName, boolean enableCodeBase)
      Creates a fully initialized JNLP classloader for the specified JNLPFile, to be used as an applet/application's classloader.
      private void decrementLoaderUseCount()
      Decrements loader use count by 1
      private java.lang.Void doActivateJars​(java.util.List<JARDesc> jars)  
      void enableCodeBase()
      Add applet's codebase URL.
      private void fillInPartJars​(java.util.List<JARDesc> jars)
      Adds to the specified list of JARS any other JARs that need to be loaded at the same time as the JARs specified (ie, are in the same part).
      protected java.lang.Class<?> findClass​(java.lang.String name)
      Find the class in this loader or any of its extension loaders.
      protected java.lang.String findLibrary​(java.lang.String lib)
      Return the absolute path to the native library.
      private java.lang.String findLibraryExt​(java.lang.String lib)
      Try to find the library path from another peer classloader.
      private java.lang.Class<?> findLoadedClassAll​(java.lang.String name)
      Find the loaded class in this loader or any of its extension loaders.
      private java.lang.String findNativeLibrary​(java.lang.String lib, java.lang.String syslib)  
      java.net.URL findResource​(java.lang.String name)
      Finds the resource in this, the parent, or the extension class loaders.
      java.util.Enumeration<java.net.URL> findResources​(java.lang.String name)
      Find the resources in this, the parent, or the extension class loaders.
      private java.util.Enumeration<java.net.URL> findResourcesBySearching​(java.lang.String name)
      Find the resources in this, the parent, or the extension class loaders.
      (package private) java.security.AccessControlContext getAccessControlContextForClassLoading()
      Returns an appropriate AccessControlContext for loading classes in the running instance.
      private java.util.LinkedHashSet<JARDesc> getAllAvailableJarsInPart​(java.lang.String part)  
      ApplicationInstance getApplication()  
      private SecurityDesc getCodeSourceSecurity​(java.net.URL source)
      Returns the security descriptor for given code source URL
      private static JNLPClassLoader getInstance​(java.net.URL location, java.lang.String uniqueKey, VersionString version, ParserSettings settings, UpdatePolicy policy, java.lang.String mainName, boolean enableCodeBase)
      Returns a JNLP classloader for the JNLP file at the specified location.
      static JNLPClassLoader getInstance​(JNLPFile file, UpdatePolicy policy, boolean enableCodeBase)
      Returns a JNLP classloader for the specified JNLP file.
      private static JNLPClassLoader getInstance​(JNLPFile file, UpdatePolicy policy, java.lang.String mainName, boolean enableCodeBase)
      Returns a JNLP classloader for the specified JNLP file.
      JNLPFile getJNLPFile()  
      private java.net.URL getJnlpFileCodebase()  
      (package private) JNLPClassLoader[] getLoaders()
      Returns all loaders that this loader uses, including itself
      java.lang.String getMainClass()  
      java.lang.String getMainClassNameFromManifest​(JARDesc mainJarDesc)  
      private java.util.List<JARDesc> getNextJarsToLoad()  
      java.security.PermissionCollection getPermissions​(java.security.CodeSource cs)
      Returns the permissions for the CodeSource.
      private java.security.Permission getReadPermission​(JARDesc jar)  
      SecurityDesc getSecurity()  
      boolean getSigning()  
      private JNLPClassLoader.SigningState getSigningState()  
      ResourceTracker getTracker()  
      private static java.util.concurrent.locks.ReentrantLock getUniqueKeyLock​(java.lang.String uniqueKey)
      Gets the lock for a given unique key, creating one if it does not yet exist.
      private boolean hasMainInExtensions()
      Returns true if extension loaders have the main jar
      (package private) boolean hasMainJar()  
      private void incrementLoaderUseCount()
      Increments loader use count by 1
      private void initializeExtensions()
      Load the extensions specified in the JNLP file.
      private void initializeManifestAttributesChecker()  
      (package private) void initializeNewJarDownload​(java.net.URL ref, java.lang.String part, VersionString version)
      Downloads and initializes jars into this loader.
      private void initializeReadJarPermissions()
      Make permission objects for the classpath.
      private void initializeResources()
      Load all of the JARs used in this JNLP file into the ResourceTracker for downloading.
      private void installShutdownHooks()
      Install JVM shutdown hooks to clean up resources allocated by this ClassLoader.
      private static boolean isCertUnderestimated()  
      (package private) boolean isInvalidJar​(JARDesc jar)
      Check if a described jar file is invalid
      java.lang.Class<?> loadClass​(java.lang.String name)
      Find a JAR in the shared 'extension' classloaders, this classloader, or one of the classloaders for the JNLP file's extensions.
      private java.lang.Class<?> loadClassExt​(java.lang.String name)
      Search for the class by incrementally adding resources to the classloader and its extension classloaders until the resource is found.
      private java.lang.Class<?> loadClassFromInternalManifestClasspath​(java.lang.String name)  
      private java.lang.Class<?> loadClassFromParentClassloader​(java.lang.String name)  
      private java.lang.Class<?> loadFromJarIndexes​(java.lang.String name)  
      (package private) boolean manageExternalJars​(java.net.URL ref, java.lang.String version, JNLPClassLoader.DownloadAction action)
      Manages DownloadService jars which are not mentioned in the JNLP file
      private void merge​(JNLPClassLoader extLoader)
      Merges the code source/security descriptor mapping from another loader
      private java.util.Collection<java.net.URL> removeDuplicates​(java.util.List<java.net.URL> lresources)  
      (package private) void removeJars​(JARDesc[] jars)
      Remove jars from the file system.
      void setApplication​(ApplicationInstance app)
      Sets the JNLP app this group is for; can only be called once.
      private void setSecurity()  
      private void verifySignedJNLP​(JarFile jarFile)
      Is called by checkForMain() to check if the jar file is signed and if it contains a signed JNLP file.
      private void waitForJars​(java.util.List<JARDesc> jars)
      Wait for a group of JARs, and send download events if there is a download listener or display a progress window otherwise.
      • Methods inherited from class java.net.URLClassLoader

        addURL, close, definePackage, getResourceAsStream, getURLs, newInstance, newInstance
      • Methods inherited from class java.security.SecureClassLoader

        defineClass, defineClass
      • Methods inherited from class java.lang.ClassLoader

        clearAssertionStatus, defineClass, defineClass, defineClass, defineClass, definePackage, findClass, findLoadedClass, findResource, findSystemClass, getClassLoadingLock, getDefinedPackage, getDefinedPackages, getName, getPackage, getPackages, getParent, getPlatformClassLoader, getResource, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, getUnnamedModule, isRegisteredAsParallelCapable, loadClass, registerAsParallelCapable, resolveClass, resources, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • FILE_READ_ACTION

        private static final java.lang.String FILE_READ_ACTION
        See Also:
        Constant Field Values
      • LOG

        private static final Logger LOG
      • TEMPLATE

        private static final java.lang.String TEMPLATE
        Signed JNLP File and Template
        See Also:
        Constant Field Values
      • isSignedJNLP

        private boolean isSignedJNLP
        True if the application has a signed JNLP File
      • uniqueKeyToLoader

        private static final java.util.Map<java.lang.String,​JNLPClassLoader> uniqueKeyToLoader
        map from JNLPFile unique key to shared classloader
      • uniqueKeyToLock

        private static final java.util.Map<java.lang.String,​java.util.concurrent.locks.ReentrantLock> uniqueKeyToLock
        map from JNLPFile unique key to lock, the lock is needed to enforce correct initialization of applets that share a unique key
      • nativeLibraryStorage

        private final NativeLibraryStorage nativeLibraryStorage
        Provides a search path & temporary storage for native code
      • acc

        private final java.security.AccessControlContext acc
        security context
      • resourcePermissions

        private final java.util.List<java.security.Permission> resourcePermissions
        the permissions for the cached jar files
      • loaders

        private JNLPClassLoader[] loaders
        list of this, local and global loaders this loader uses
      • strict

        private final boolean strict
        whether to strictly adhere to the spec or not
      • updatePolicy

        private final UpdatePolicy updatePolicy
        the update policy for resources
      • file

        private final JNLPFile file
        the JNLP file
      • resources

        private final ResourcesDesc resources
        the resources section
      • security

        private SecurityDesc security
        the security section
      • runtimePermissions

        private final java.util.ArrayList<java.security.Permission> runtimePermissions
        Permissions granted by the user during runtime.
      • available

        private final java.util.List<JARDesc> available
        all jars not yet part of classloader or active Synchronized since this field may become shared data between multiple classloading threads. See loadClass(String) and CodebaseClassLoader.findClassNonRecursive(String).
      • jcv

        final JarCertVerifier jcv
        the jar cert verifier tool to verify our jars
      • jarIndexes

        private final java.util.List<JarIndexAccess> jarIndexes
        ArrayList containing jar indexes for various jars available to this classloader Synchronized since this field may become shared data between multiple classloading threads/ See loadClass(String) and CodebaseClassLoader.findClassNonRecursive(String).
      • classpaths

        private final java.util.Set<java.lang.String> classpaths
        Set of classpath strings declared in the manifest.mf files Synchronized since this field may become shared data between multiple classloading threads. See loadClass(String) and CodebaseClassLoader.findClassNonRecursive(String).
      • jarEntries

        private final java.util.Set<java.lang.String> jarEntries
        File entries in the jar files available to this classloader Synchronized sinc this field may become shared data between multiple classloading threads. See loadClass(String) and CodebaseClassLoader.findClassNonRecursive(String).
      • jarLocationSecurityMap

        final java.util.Map<UrlKey,​SecurityDesc> jarLocationSecurityMap
        Map of specific original (remote) CodeSource Urls to securitydesc Synchronized since this field may become shared data between multiple classloading threads. See loadClass(String) and CodebaseClassLoader.findClassNonRecursive(String).
      • alreadyTried

        private final java.util.Set<UrlKey> alreadyTried
      • codeBaseLoader

        private CodeBaseClassLoader codeBaseLoader
        Loader for codebase (which is a path, rather than a file)
      • foundMainJar

        private boolean foundMainJar
        True if the jar with the main class has been found
      • mainClass

        private java.lang.String mainClass
        Name of the application's main class
      • useCount

        private int useCount
        Variable to track how many times this loader is in use
      • enableCodeBase

        private boolean enableCodeBase
    • Constructor Detail

      • JNLPClassLoader

        public JNLPClassLoader​(JNLPFile file,
                               UpdatePolicy policy)
                        throws LaunchException
        Create a new JNLPClassLoader from the specified file.
        Parameters:
        file - the JNLP file
        policy - update policy of loader
        Throws:
        LaunchException - if app can not be loaded
      • JNLPClassLoader

        private JNLPClassLoader​(JNLPFile file,
                                UpdatePolicy policy,
                                java.lang.String mainName,
                                boolean enableCodeBase)
                         throws LaunchException
        Create a new JNLPClassLoader from the specified file.
        Parameters:
        file - the JNLP file
        policy - the UpdatePolicy for this class loader
        mainName - name of the application's main class
        enableCodeBase - switch whether this classloader can search in codebase or not
        Throws:
        LaunchException - when need to kill an app comes.
    • Method Detail

      • isCertUnderestimated

        private static boolean isCertUnderestimated()
      • installShutdownHooks

        private void installShutdownHooks()
        Install JVM shutdown hooks to clean up resources allocated by this ClassLoader.
      • getUniqueKeyLock

        private static java.util.concurrent.locks.ReentrantLock getUniqueKeyLock​(java.lang.String uniqueKey)
        Gets the lock for a given unique key, creating one if it does not yet exist. This operation is atomic & thread-safe.
        Parameters:
        uniqueKey - the file whose unique key should be used
        Returns:
        the lock
      • createInstance

        private static JNLPClassLoader createInstance​(JNLPFile file,
                                                      UpdatePolicy policy,
                                                      java.lang.String mainName,
                                                      boolean enableCodeBase)
                                               throws LaunchException
        Creates a fully initialized JNLP classloader for the specified JNLPFile, to be used as an applet/application's classloader. In contrast, JNLP classloaders can also be constructed simply to merge its resources into another classloader.
        Parameters:
        file - the file to load classes for
        policy - the update policy to use when downloading resources
        mainName - Overrides the main class name of the application
        Throws:
        LaunchException
      • getInstance

        public static JNLPClassLoader getInstance​(JNLPFile file,
                                                  UpdatePolicy policy,
                                                  boolean enableCodeBase)
                                           throws LaunchException
        Returns a JNLP classloader for the specified JNLP file.
        Parameters:
        file - the file to load classes for
        policy - the update policy to use when downloading resources
        enableCodeBase - true if codebase can be searched (ok for applets,false for apps)
        Returns:
        existing classloader. creates new if none reliable exists
        Throws:
        LaunchException - when launch is doomed
      • getInstance

        private static JNLPClassLoader getInstance​(JNLPFile file,
                                                   UpdatePolicy policy,
                                                   java.lang.String mainName,
                                                   boolean enableCodeBase)
                                            throws LaunchException
        Returns a JNLP classloader for the specified JNLP file.
        Parameters:
        file - the file to load classes for
        policy - the update policy to use when downloading resources
        mainName - Overrides the main class name of the application
        enableCodeBase - ue if codebase can be searched (ok for applets,false for apps)
        Returns:
        existing classloader. creates new if none reliable exists
        Throws:
        LaunchException - when launch is doomed
      • getInstance

        private static JNLPClassLoader getInstance​(java.net.URL location,
                                                   java.lang.String uniqueKey,
                                                   VersionString version,
                                                   ParserSettings settings,
                                                   UpdatePolicy policy,
                                                   java.lang.String mainName,
                                                   boolean enableCodeBase)
                                            throws java.io.IOException,
                                                   ParseException,
                                                   LaunchException
        Returns a JNLP classloader for the JNLP file at the specified location.
        Parameters:
        location - the file's location
        uniqueKey - key to manage applets/applications in shared vm
        version - the file's version
        settings - settings of parser
        policy - the update policy to use when downloading resources
        mainName - Overrides the main class name of the application
        enableCodeBase - whether to enable codebase search or not
        Returns:
        classloader of this app
        Throws:
        java.io.IOException - when IO fails
        ParseException - when parsing fails
        LaunchException - when launch is doomed
      • initializeExtensions

        private void initializeExtensions()
        Load the extensions specified in the JNLP file.
      • initializeReadJarPermissions

        private void initializeReadJarPermissions()
        Make permission objects for the classpath.
      • getReadPermission

        private java.security.Permission getReadPermission​(JARDesc jar)
      • isInvalidJar

        boolean isInvalidJar​(JARDesc jar)
        Check if a described jar file is invalid
        Parameters:
        jar - the jar to check
        Returns:
        true if file exists AND is an invalid jar, false otherwise
      • initializeResources

        private void initializeResources()
                                  throws LaunchException
        Load all of the JARs used in this JNLP file into the ResourceTracker for downloading.
        Throws:
        LaunchException
      • initializeManifestAttributesChecker

        private void initializeManifestAttributesChecker()
      • getJnlpFileCodebase

        private java.net.URL getJnlpFileCodebase()
      • checkForMain

        void checkForMain​(java.util.List<JARDesc> jars)
                   throws LaunchException
        * Checks for the jar that contains the main class. If the main class was found, it checks to see if the jar is signed and whether it contains a signed JNLP file
        Parameters:
        jars - Jars that are checked to see if they contain the main class
        Throws:
        LaunchException - Thrown if the signed JNLP file, within the main jar, fails to be verified or does not match
      • hasMainJar

        boolean hasMainJar()
        Returns:
        true if this loader has the main jar
      • hasMainInExtensions

        private boolean hasMainInExtensions()
        Returns true if extension loaders have the main jar
      • verifySignedJNLP

        private void verifySignedJNLP​(JarFile jarFile)
                               throws LaunchException
        Is called by checkForMain() to check if the jar file is signed and if it contains a signed JNLP file.
        Parameters:
        jarFile - the jar file
        Throws:
        LaunchException - thrown if the signed JNLP file, within the main jar, fails to be verified or does not match
      • checkTrustWithUser

        private void checkTrustWithUser()
                                 throws LaunchException
        Prompt the user for trust on all the signers that require approval.
        Throws:
        LaunchException - if the user does not approve every dialog prompt.
      • enableCodeBase

        public void enableCodeBase()
        Add applet's codebase URL. This allows compatibility with applets that load resources from their codebase instead of through JARs, but can slow down resource loading. Resources loaded from the codebase are not cached.
      • setApplication

        public void setApplication​(ApplicationInstance app)
        Sets the JNLP app this group is for; can only be called once.
        Parameters:
        app - application to be ser to this group
      • getApplication

        public ApplicationInstance getApplication()
        Returns:
        the JNLP app for this classloader
      • getJNLPFile

        public JNLPFile getJNLPFile()
        Returns:
        the JNLP file the classloader was created from.
      • getPermissions

        public java.security.PermissionCollection getPermissions​(java.security.CodeSource cs)
        Returns the permissions for the CodeSource.
        Overrides:
        getPermissions in class java.net.URLClassLoader
      • addPermission

        public void addPermission​(java.security.Permission p)
      • fillInPartJars

        private void fillInPartJars​(java.util.List<JARDesc> jars)
        Adds to the specified list of JARS any other JARs that need to be loaded at the same time as the JARs specified (ie, are in the same part).
        Parameters:
        jars - jar archives to be added
      • getAllAvailableJarsInPart

        private java.util.LinkedHashSet<JARDesc> getAllAvailableJarsInPart​(java.lang.String part)
      • activateJars

        void activateJars​(java.util.List<JARDesc> jars)
        Ensures that the list of jars have all been transferred, and makes them available to the classloader. If a jar contains native code, the libraries will be extracted and placed in the path.
        Parameters:
        jars - the list of jars to load
      • doActivateJars

        private java.lang.Void doActivateJars​(java.util.List<JARDesc> jars)
      • findLibrary

        protected java.lang.String findLibrary​(java.lang.String lib)
        Return the absolute path to the native library.
        Overrides:
        findLibrary in class java.lang.ClassLoader
      • findNativeLibrary

        private java.lang.String findNativeLibrary​(java.lang.String lib,
                                                   java.lang.String syslib)
      • findLibraryExt

        private java.lang.String findLibraryExt​(java.lang.String lib)
        Try to find the library path from another peer classloader.
        Parameters:
        lib - library to be found
        Returns:
        location of library
      • waitForJars

        private void waitForJars​(java.util.List<JARDesc> jars)
        Wait for a group of JARs, and send download events if there is a download listener or display a progress window otherwise.
        Parameters:
        jars - the jars
      • findLoadedClassAll

        private java.lang.Class<?> findLoadedClassAll​(java.lang.String name)
        Find the loaded class in this loader or any of its extension loaders.
        Parameters:
        name - name of class
        Returns:
        the class found by name
      • loadClass

        public java.lang.Class<?> loadClass​(java.lang.String name)
                                     throws java.lang.ClassNotFoundException
        Find a JAR in the shared 'extension' classloaders, this classloader, or one of the classloaders for the JNLP file's extensions. This method used to be qualified "synchronized." This was done solely for the purpose of ensuring only one thread entered the method at a time. This was not strictly necessary - ensuring that all affected fields are thread-safe is sufficient. Locking on the JNLPClassLoader instance when this method is called can result in deadlock if another thread is dealing with the CodebaseClassLoader at the same time. This solution is very heavy-handed as the instance lock is not truly required, and taking the lock on the classloader instance when not needed is not in general a good idea because it can and will lead to deadlock when multithreaded classloading is in effect. The solution is to keep the fields thread safe on their own. This is accomplished by wrapping them in Collections.synchronized* to provide atomic add/remove operations, and synchronizing on them when iterating or performing multiple mutations. See bug report RH976833. On some systems this bug will manifest itself as deadlock on every webpage with more than one Java applet, potentially also causing the browser process to hang. More information in the mailing list archives: http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2013-September/024536.html

        Affected fields: available, classpaths, jarIndexes, jarEntries, jarLocationSecurityMap

        Overrides:
        loadClass in class java.lang.ClassLoader
        Throws:
        java.lang.ClassNotFoundException
      • loadClassFromParentClassloader

        private java.lang.Class<?> loadClassFromParentClassloader​(java.lang.String name)
                                                           throws java.lang.ClassNotFoundException
        Throws:
        java.lang.ClassNotFoundException
      • loadClassFromInternalManifestClasspath

        private java.lang.Class<?> loadClassFromInternalManifestClasspath​(java.lang.String name)
                                                                   throws java.lang.ClassNotFoundException
        Throws:
        java.lang.ClassNotFoundException
      • loadFromJarIndexes

        private java.lang.Class<?> loadFromJarIndexes​(java.lang.String name)
                                               throws java.lang.ClassNotFoundException
        Throws:
        java.lang.ClassNotFoundException
      • addNewJar

        private void addNewJar​(JARDesc desc)
        Adds a new JARDesc into this classloader.

        This will add the JARDesc into the resourceTracker and block until it is downloaded.

        Parameters:
        desc - the JARDesc for the new jar
      • addNewJar

        private void addNewJar​(JARDesc desc,
                               UpdatePolicy updatePolicy)
        Adds a new JARDesc into this classloader.
        Parameters:
        desc - the JARDesc for the new jar
        updatePolicy - the UpdatePolicy for the resource
      • findClass

        protected java.lang.Class<?> findClass​(java.lang.String name)
                                        throws java.lang.ClassNotFoundException
        Find the class in this loader or any of its extension loaders.
        Overrides:
        findClass in class java.net.URLClassLoader
        Throws:
        java.lang.ClassNotFoundException
      • loadClassExt

        private java.lang.Class<?> loadClassExt​(java.lang.String name)
                                         throws java.lang.ClassNotFoundException
        Search for the class by incrementally adding resources to the classloader and its extension classloaders until the resource is found.
        Throws:
        java.lang.ClassNotFoundException
      • findResource

        public java.net.URL findResource​(java.lang.String name)
        Finds the resource in this, the parent, or the extension class loaders.
        Overrides:
        findResource in class java.net.URLClassLoader
        Returns:
        a URL for the resource, or null if the resource could not be found.
      • findResources

        public java.util.Enumeration<java.net.URL> findResources​(java.lang.String name)
                                                          throws java.io.IOException
        Find the resources in this, the parent, or the extension class loaders. Load lazy resources if not found in current resources.
        Overrides:
        findResources in class java.net.URLClassLoader
        Throws:
        java.io.IOException
      • findResourcesBySearching

        private java.util.Enumeration<java.net.URL> findResourcesBySearching​(java.lang.String name)
                                                                      throws java.io.IOException
        Find the resources in this, the parent, or the extension class loaders.
        Throws:
        java.io.IOException
      • removeDuplicates

        private java.util.Collection<java.net.URL> removeDuplicates​(java.util.List<java.net.URL> lresources)
      • addAvailable

        private void addAvailable()
        Adds whatever resources have already been downloaded in the background.
      • addNextResource

        private JNLPClassLoader addNextResource()
                                         throws LaunchException
        Adds the next unused resource to the classloader. That resource and all those in the same part will be downloaded and added to the classloader before returning. If there are no more resources to add, the method returns immediately.
        Returns:
        the classloader that resources were added to, or null
        Throws:
        LaunchException - Thrown if the signed JNLP file, within the main jar, fails to be verified or does not match
      • getNextJarsToLoad

        private java.util.List<JARDesc> getNextJarsToLoad()
      • getSigning

        public boolean getSigning()
      • checkPartialSigningWithUser

        void checkPartialSigningWithUser()
        Call this when it's suspected that an applet's permission level may have just changed from Full Signing to Partial Signing. This will display a one-time prompt asking the user to confirm running the partially signed applet. Partially Signed applets always start off as appearing to be Fully Signed, and then during the initialization or loading process, we find that we actually need to demote the applet to Partial, either due to finding that not all of its JARs are actually signed, or because it needs to load something unsigned out of the codebase.
      • getCodeSourceSecurity

        private SecurityDesc getCodeSourceSecurity​(java.net.URL source)
        Returns the security descriptor for given code source URL
        Parameters:
        source - the origin (remote) url of the code
        Returns:
        The SecurityDescriptor for that source
      • merge

        private void merge​(JNLPClassLoader extLoader)
        Merges the code source/security descriptor mapping from another loader
        Parameters:
        extLoader - The loader form which to merge
        Throws:
        java.lang.SecurityException - if the code is called from an untrusted source
      • addToCodeBaseLoader

        private void addToCodeBaseLoader​(java.net.URL u)
        Adds the given path to the path loader
        Parameters:
        u - the path to add
        Throws:
        java.lang.IllegalArgumentException - If the given url is not a path
      • incrementLoaderUseCount

        private void incrementLoaderUseCount()
        Increments loader use count by 1
        Throws:
        java.lang.SecurityException - if caller is not trusted
      • getLoaders

        JNLPClassLoader[] getLoaders()
        Returns all loaders that this loader uses, including itself
      • removeJars

        void removeJars​(JARDesc[] jars)
        Remove jars from the file system.
        Parameters:
        jars - Jars marked for removal.
      • initializeNewJarDownload

        void initializeNewJarDownload​(java.net.URL ref,
                                      java.lang.String part,
                                      VersionString version)
        Downloads and initializes jars into this loader.
        Parameters:
        ref - Path of the launch or extension JNLP File containing the resource. If null, main JNLP's file location will be used instead.
        part - The name of the path.
        version - of jar to be downloaded
      • manageExternalJars

        boolean manageExternalJars​(java.net.URL ref,
                                   java.lang.String version,
                                   JNLPClassLoader.DownloadAction action)
        Manages DownloadService jars which are not mentioned in the JNLP file
        Parameters:
        ref - Path to the resource.
        version - The version of resource. If null, no version is specified.
        action - The action to perform with the resource. Either DOWNLOADTOCACHE, REMOVEFROMCACHE, or CHECKCACHE.
        Returns:
        true if CHECKCACHE and the resource is cached.
      • decrementLoaderUseCount

        private void decrementLoaderUseCount()
        Decrements loader use count by 1

        If count reaches 0, loader is removed from list of available loaders

        Throws:
        java.lang.SecurityException - if caller is not trusted
      • getAccessControlContextForClassLoading

        java.security.AccessControlContext getAccessControlContextForClassLoading()
        Returns an appropriate AccessControlContext for loading classes in the running instance.

        The default context during class-loading only allows connection to codebase. However applets are allowed to load jars from arbitrary locations and the codebase only access falls short if a class from one location needs a class from another.

        Given protected access since CodeBaseClassloader uses this function too.

        Returns:
        The appropriate AccessControlContext for loading classes for this instance
      • getMainClass

        public java.lang.String getMainClass()
      • getMainClassNameFromManifest

        public java.lang.String getMainClassNameFromManifest​(JARDesc mainJarDesc)
                                                      throws java.io.IOException
        Throws:
        java.io.IOException