Class JNLPClassLoader
java.lang.Object
java.lang.ClassLoader
java.security.SecureClassLoader
java.net.URLClassLoader
net.sourceforge.jnlp.runtime.classloader.JNLPClassLoader
- All Implemented Interfaces:
Closeable, AutoCloseable
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 $
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static enumActions to specify how cache is to be managed *static interfaceJNLPClassLoader.ExceptionalSupplier<T, E extends Exception>static enum -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final AccessControlContextsecurity contextprivate ApplicationInstancethe appprivate static final Stringall jars not yet part of classloader or active Synchronized since this field may become shared data between multiple classloading threads.Set of classpath strings declared in the manifest.mf files Synchronized since this field may become shared data between multiple classloading threads.private CodeBaseClassLoaderLoader for codebase (which is a path, rather than a file)private booleanprivate final JNLPFilethe JNLP fileprivate static final Stringprivate booleanTrue if the jar with the main class has been foundprivate booleanTrue if the application has a signed JNLP FileFile entries in the jar files available to this classloader Synchronized sinc this field may become shared data between multiple classloading threads.private final List<JarIndexAccess> 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) final Map<UrlKey, SecurityDesc> Map of specific original (remote) CodeSource Urls to securitydesc Synchronized since this field may become shared data between multiple classloading threads.(package private) final JarCertVerifierthe jar cert verifier tool to verify our jarsprivate JNLPClassLoader[]list of this, local and global loaders this loader usesprivate static final Loggerprivate ManifestAttributesCheckerprivate StringName of the application's main classprivate final NativeLibraryStorageProvides a search path invalid input: '&' temporary storage for native codeprivate final List<Permission> the permissions for the cached jar filesprivate final ResourcesDescthe resources sectionprivate final ArrayList<Permission> Permissions granted by the user during runtime.private SecurityDescthe security sectionprivate final SecurityDelegateprivate JNLPClassLoader.SigningStateprivate final booleanwhether to strictly adhere to the spec or notprivate static final StringSigned JNLP File and Templateprivate final ResourceTrackerloads the resourcesprivate static final Map<String, JNLPClassLoader> map from JNLPFile unique key to shared classloaderprivate static final Map<String, ReentrantLock> map from JNLPFile unique key to lock, the lock is needed to enforce correct initialization of applets that share a unique keyprivate final UpdatePolicythe update policy for resourcesprivate intVariable to track how many times this loader is in use -
Constructor Summary
ConstructorsModifierConstructorDescriptionJNLPClassLoader(JNLPFile file, UpdatePolicy policy) Create a new JNLPClassLoader from the specified file.privateJNLPClassLoader(JNLPFile file, UpdatePolicy policy, String mainName, boolean enableCodeBase) Create a new JNLPClassLoader from the specified file. -
Method Summary
Modifier and TypeMethodDescription(package private) voidactivateJars(List<JARDesc> jars) Ensures that the list of jars have all been transferred, and makes them available to the classloader.private voidAdds whatever resources have already been downloaded in the background.private voidAdds a new JARDesc into this classloader.private voidaddNewJar(JARDesc desc, UpdatePolicy updatePolicy) Adds a new JARDesc into this classloader.private JNLPClassLoaderAdds the next unused resource to the classloader.voidprivate voidAdds the given path to the path loaderprivate SecurityDesccheckEnforceable(SecurityDesc desc) Without a SecurityManager every permission set is effectively AllPermission, so anything less than all-permissions cannot be honoured.(package private) voidcheckForMain(List<JARDesc> jars) * Checks for the jar that contains the main class.(package private) voidCall this when it's suspected that an applet's permission level may have just changed from Full Signing to Partial Signing.private voidPrompt the user for trust on all the signers that require approval.(package private) static voidprivate static JNLPClassLoadercreateInstance(JNLPFile file, UpdatePolicy policy, String mainName, boolean enableCodeBase) Creates a fully initialized JNLP classloader for the specified JNLPFile, to be used as an applet/application's classloader.private voidDecrements loader use count by 1private VoiddoActivateJars(List<JARDesc> jars) voidAdd applet's codebase URL.private voidfillInPartJars(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 Class<?> Find the class in this loader or any of its extension loaders.protected StringfindLibrary(String lib) Return the absolute path to the native library.private StringfindLibraryExt(String lib) Try to find the library path from another peer classloader.private Class<?> findLoadedClassAll(String name) Find the loaded class in this loader or any of its extension loaders.private StringfindNativeLibrary(String lib, String syslib) findResource(String name) Finds the resource in this, the parent, or the extension class loaders.findResources(String name) Find the resources in this, the parent, or the extension class loaders.private Enumeration<URL> Find the resources in this, the parent, or the extension class loaders.(package private) AccessControlContextReturns an appropriate AccessControlContext for loading classes in the running instance.private LinkedHashSet<JARDesc> private SecurityDescgetCodeSourceSecurity(URL source) Returns the security descriptor for given code source URLprivate static JNLPClassLoadergetInstance(URL location, String uniqueKey, VersionString version, ParserSettings settings, UpdatePolicy policy, String mainName, boolean enableCodeBase) Returns a JNLP classloader for the JNLP file at the specified location.static JNLPClassLoadergetInstance(JNLPFile file, UpdatePolicy policy, boolean enableCodeBase) Returns a JNLP classloader for the specified JNLP file.private static JNLPClassLoadergetInstance(JNLPFile file, UpdatePolicy policy, String mainName, boolean enableCodeBase) Returns a JNLP classloader for the specified JNLP file.private URL(package private) JNLPClassLoader[]Returns all loaders that this loader uses, including itselfgetMainClassNameFromManifest(JARDesc mainJarDesc) Returns the permissions for the CodeSource.private PermissiongetReadPermission(JARDesc jar) booleanprivate JNLPClassLoader.SigningStateprivate static ReentrantLockgetUniqueKeyLock(String uniqueKey) Gets the lock for a given unique key, creating one if it does not yet exist.private booleanReturns true if extension loaders have the main jar(package private) booleanprivate voidIncrements loader use count by 1private voidLoad the extensions specified in the JNLP file.private void(package private) voidinitializeNewJarDownload(URL ref, String part, VersionString version) Downloads and initializes jars into this loader.private voidMake permission objects for the classpath.private voidLoad all of the JARs used in this JNLP file into the ResourceTracker for downloading.private voidInstall JVM shutdown hooks to clean up resources allocated by this ClassLoader.private static boolean(package private) booleanisInvalidJar(JARDesc jar) Check if a described jar file is invalidClass<?> Find a JAR in the shared 'extension' classloaders, this classloader, or one of the classloaders for the JNLP file's extensions.private Class<?> loadClassExt(String name) Search for the class by incrementally adding resources to the classloader and its extension classloaders until the resource is found.private Class<?> private Class<?> private Class<?> loadFromJarIndexes(String name) (package private) booleanmanageExternalJars(URL ref, String version, JNLPClassLoader.DownloadAction action) Manages DownloadService jars which are not mentioned in the JNLP fileprivate voidmerge(JNLPClassLoader extLoader) Merges the code source/security descriptor mapping from another loaderprivate Collection<URL> removeDuplicates(List<URL> lresources) (package private) voidremoveJars(JARDesc[] jars) Remove jars from the file system.voidSets the JNLP app this group is for; can only be called once.private voidprivate voidverifySignedJNLP(JarFile jarFile) Is called by checkForMain() to check if the jar file is signed and if it contains a signed JNLP file.private voidwaitForJars(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 URLClassLoader
addURL, close, definePackage, getResourceAsStream, getURLs, newInstance, newInstanceMethods inherited from class SecureClassLoader
defineClass, defineClassMethods inherited from class 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
-
Field Details
-
FILE_READ_ACTION
- See Also:
-
LOG
-
TEMPLATE
-
APPLICATION
- See Also:
-
isSignedJNLP
private boolean isSignedJNLPTrue if the application has a signed JNLP File -
uniqueKeyToLoader
map from JNLPFile unique key to shared classloader -
uniqueKeyToLock
map from JNLPFile unique key to lock, the lock is needed to enforce correct initialization of applets that share a unique key -
nativeLibraryStorage
Provides a search path invalid input: '&' temporary storage for native code -
acc
security context -
resourcePermissions
the permissions for the cached jar files -
app
the app -
loaders
list of this, local and global loaders this loader uses -
strict
private final boolean strictwhether to strictly adhere to the spec or not -
tracker
loads the resources -
updatePolicy
the update policy for resources -
file
the JNLP file -
resources
the resources section -
security
the security section -
runtimePermissions
Permissions granted by the user during runtime. -
available
-
jcv
the jar cert verifier tool to verify our jars -
signing
-
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
-
jarEntries
-
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
-
codeBaseLoader
Loader for codebase (which is a path, rather than a file) -
foundMainJar
private boolean foundMainJarTrue if the jar with the main class has been found -
mainClass
Name of the application's main class -
useCount
private int useCountVariable to track how many times this loader is in use -
enableCodeBase
private boolean enableCodeBase -
securityDelegate
-
mac
-
-
Constructor Details
-
JNLPClassLoader
Create a new JNLPClassLoader from the specified file.- Parameters:
file- the JNLP filepolicy- update policy of loader- Throws:
LaunchException- if app can not be loaded
-
JNLPClassLoader
private JNLPClassLoader(JNLPFile file, UpdatePolicy policy, String mainName, boolean enableCodeBase) throws LaunchException Create a new JNLPClassLoader from the specified file.- Parameters:
file- the JNLP filepolicy- the UpdatePolicy for this class loadermainName- name of the application's main classenableCodeBase- switch whether this classloader can search in codebase or not- Throws:
LaunchException- when need to kill an app comes.
-
-
Method Details
-
isCertUnderestimated
private static boolean isCertUnderestimated() -
consultCertificateSecurityException
- Throws:
LaunchException
-
installShutdownHooks
private void installShutdownHooks()Install JVM shutdown hooks to clean up resources allocated by this ClassLoader. -
setSecurity
- Throws:
LaunchException
-
checkEnforceable
Without a SecurityManager every permission set is effectively AllPermission, so anything less than all-permissions cannot be honoured.- Throws:
LaunchException
-
getUniqueKeyLock
Gets the lock for a given unique key, creating one if it does not yet exist. This operation is atomic invalid input: '&' thread-safe.- Parameters:
uniqueKey- the file whose unique key should be used- Returns:
- the lock
-
createInstance
private static JNLPClassLoader createInstance(JNLPFile file, UpdatePolicy policy, 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 forpolicy- the update policy to use when downloading resourcesmainName- 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 forpolicy- the update policy to use when downloading resourcesenableCodeBase- 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, String mainName, boolean enableCodeBase) throws LaunchException Returns a JNLP classloader for the specified JNLP file.- Parameters:
file- the file to load classes forpolicy- the update policy to use when downloading resourcesmainName- Overrides the main class name of the applicationenableCodeBase- 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(URL location, String uniqueKey, VersionString version, ParserSettings settings, UpdatePolicy policy, String mainName, boolean enableCodeBase) throws IOException, ParseException, LaunchException Returns a JNLP classloader for the JNLP file at the specified location.- Parameters:
location- the file's locationuniqueKey- key to manage applets/applications in shared vmversion- the file's versionsettings- settings of parserpolicy- the update policy to use when downloading resourcesmainName- Overrides the main class name of the applicationenableCodeBase- whether to enable codebase search or not- Returns:
- classloader of this app
- Throws:
IOException- when IO failsParseException- when parsing failsLaunchException- 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
-
isInvalidJar
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
Load all of the JARs used in this JNLP file into the ResourceTracker for downloading.- Throws:
LaunchException
-
initializeManifestAttributesChecker
private void initializeManifestAttributesChecker() -
getJnlpFileCodebase
-
checkForMain
* 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
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
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
Sets the JNLP app this group is for; can only be called once.- Parameters:
app- application to be ser to this group
-
getApplication
- Returns:
- the JNLP app for this classloader
-
getJNLPFile
- Returns:
- the JNLP file the classloader was created from.
-
getPermissions
Returns the permissions for the CodeSource.- Overrides:
getPermissionsin classURLClassLoader
-
addPermission
-
fillInPartJars
-
getAllAvailableJarsInPart
-
activateJars
-
doActivateJars
-
findLibrary
Return the absolute path to the native library.- Overrides:
findLibraryin classClassLoader
-
findNativeLibrary
-
findLibraryExt
-
waitForJars
-
findLoadedClassAll
-
loadClass
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.htmlAffected fields: available, classpaths, jarIndexes, jarEntries, jarLocationSecurityMap
- Overrides:
loadClassin classClassLoader- Throws:
ClassNotFoundException
-
loadClassFromParentClassloader
- Throws:
ClassNotFoundException
-
loadClassFromInternalManifestClasspath
- Throws:
ClassNotFoundException
-
loadFromJarIndexes
- Throws:
ClassNotFoundException
-
addNewJar
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
Adds a new JARDesc into this classloader.- Parameters:
desc- the JARDesc for the new jarupdatePolicy- the UpdatePolicy for the resource
-
findClass
Find the class in this loader or any of its extension loaders.- Overrides:
findClassin classURLClassLoader- Throws:
ClassNotFoundException
-
loadClassExt
Search for the class by incrementally adding resources to the classloader and its extension classloaders until the resource is found.- Throws:
ClassNotFoundException
-
findResource
Finds the resource in this, the parent, or the extension class loaders.- Overrides:
findResourcein classURLClassLoader- Returns:
- a
URLfor the resource, ornullif the resource could not be found.
-
findResources
Find the resources in this, the parent, or the extension class loaders. Load lazy resources if not found in current resources.- Overrides:
findResourcesin classURLClassLoader- Throws:
IOException
-
findResourcesBySearching
Find the resources in this, the parent, or the extension class loaders.- Throws:
IOException
-
removeDuplicates
-
addAvailable
private void addAvailable()Adds whatever resources have already been downloaded in the background. -
addNextResource
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
-
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. -
getSigningState
-
getSecurity
-
getCodeSourceSecurity
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
Merges the code source/security descriptor mapping from another loader- Parameters:
extLoader- The loader form which to merge- Throws:
SecurityException- if the code is called from an untrusted source
-
addToCodeBaseLoader
Adds the given path to the path loader- Parameters:
u- the path to add- Throws:
IllegalArgumentException- If the given url is not a path
-
incrementLoaderUseCount
private void incrementLoaderUseCount()Increments loader use count by 1- Throws:
SecurityException- if caller is not trusted
-
getLoaders
JNLPClassLoader[] getLoaders()Returns all loaders that this loader uses, including itself -
removeJars
Remove jars from the file system.- Parameters:
jars- Jars marked for removal.
-
initializeNewJarDownload
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
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 1If count reaches 0, loader is removed from list of available loaders
- Throws:
SecurityException- if caller is not trusted
-
getAccessControlContextForClassLoading
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
-
getTracker
-
getMainClassNameFromManifest
- Throws:
IOException
-