jdk/src/share/classes/sun/misc/ClassLoaderUtil.java
author alanb
Fri, 22 Feb 2013 14:04:06 +0000
changeset 16023 58ecc1b8327b
parent 14342 8435a30053c1
permissions -rw-r--r--
8008290: (profiles) Startup regression due to additional checking of JAR file manifests Reviewed-by: lancea, chegar, iris, mchung, sherman
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
14342
8435a30053c1 7197491: update copyright year to match last edit in jdk8 jdk repository
alanb
parents: 11131
diff changeset
     2
 * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2176
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2176
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2176
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2176
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2176
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.misc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * Provides utility functions related to URLClassLoaders or subclasses of it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 *                  W  A  R  N  I  N  G
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * This class uses undocumented, unpublished, private data structures inside
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * java.net.URLClassLoader and sun.misc.URLClassPath.  Use with extreme caution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * @author      tjquinn
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.net.URLClassLoader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.util.jar.JarFile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
public class ClassLoaderUtil {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
     * Releases resources held by a URLClassLoader. A new classloader must
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
     * be created before the underlying resources can be accessed again.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
     * @param classLoader the instance of URLClassLoader (or a subclass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    public static void releaseLoader(URLClassLoader classLoader) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
        releaseLoader(classLoader, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     * Releases resources held by a URLClassLoader.  Notably, close the jars
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     * opened by the loader. Initializes and updates the List of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     * jars that have been successfully closed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     * @param classLoader the instance of URLClassLoader (or a subclass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     * @param jarsClosed a List of Strings that will contain the names of jars
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     *  successfully closed; can be null if the caller does not need the information returned
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     * @return a List of IOExceptions reporting jars that failed to close; null
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
     * indicates that an error other than an IOException occurred attempting to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
     * release the loader; empty indicates a successful release; non-empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
     * indicates at least one error attempting to close an open jar.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    public static List<IOException> releaseLoader(URLClassLoader classLoader, List<String> jarsClosed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        List<IOException> ioExceptions = new LinkedList<IOException>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
            /* Records all IOExceptions thrown while closing jar files. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
            if (jarsClosed != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
                jarsClosed.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
            URLClassPath ucp = SharedSecrets.getJavaNetAccess()
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
                                                .getURLClassPath(classLoader);
11131
27747ee5a62a 7116857: Warnings in javax.security and some sun.misc
weijun
parents: 5506
diff changeset
    82
            ArrayList<?> loaders = ucp.loaders;
27747ee5a62a 7116857: Warnings in javax.security and some sun.misc
weijun
parents: 5506
diff changeset
    83
            Stack<?> urls = ucp.urls;
27747ee5a62a 7116857: Warnings in javax.security and some sun.misc
weijun
parents: 5506
diff changeset
    84
            HashMap<?,?> lmap = ucp.lmap;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
             *The urls variable in the URLClassPath object holds URLs that have not yet
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
             *been used to resolve a resource or load a class and, therefore, do
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
             *not yet have a loader associated with them.  Clear the stack so any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
             *future requests that might incorrectly reach the loader cannot be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
             *resolved and cannot open a jar file after we think we've closed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
             *them all.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            synchronized(urls) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
                urls.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
             *Also clear the map of URLs to loaders so the class loader cannot use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
             *previously-opened jar files - they are about to be closed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            synchronized(lmap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                lmap.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
             *The URLClassPath object's path variable records the list of all URLs that are on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
             *the URLClassPath's class path.  Leave that unchanged.  This might
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
             *help someone trying to debug why a released class loader is still used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
             *Because the stack and lmap are now clear, code that incorrectly uses a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
             *the released class loader will trigger an exception if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
             *class or resource would have been resolved by the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
             *loader (and no other) if it had not been released.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
             *The list of URLs might provide some hints to the person as to where
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
             *in the code the class loader was set up, which might in turn suggest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
             *where in the code the class loader needs to stop being used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
             *The URLClassPath does not use the path variable to open new jar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
             *files - it uses the urls Stack for that - so leaving the path variable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
             *will not by itself allow the class loader to continue handling requests.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
             *For each loader, close the jar file associated with that loader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
             *The URLClassPath's use of loaders is sync-ed on the entire URLClassPath
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
             *object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            synchronized (ucp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                for (Object o : loaders) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                    if (o != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
                        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                         *If the loader is a JarLoader inner class and its jarFile
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                         *field is non-null then try to close that jar file.  Add
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                         *it to the list of closed files if successful.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                        if (o instanceof URLClassPath.JarLoader) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                                URLClassPath.JarLoader jl = (URLClassPath.JarLoader)o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                                JarFile jarFile = jl.getJarFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                                    if (jarFile != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                                        jarFile.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                                        if (jarsClosed != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                                            jarsClosed.add(jarFile.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
                                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                                } catch (IOException ioe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                                     *Wrap the IOException to identify which jar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                                     *could not be closed and add it to the list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                                     *of IOExceptions to be returned to the caller.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                                    String jarFileName = (jarFile == null) ? "filename not available":jarFile.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                                    String msg = "Error closing JAR file: " + jarFileName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                                    IOException newIOE = new IOException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                                    newIOE.initCause(ioe);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                                    ioExceptions.add(newIOE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                 *Now clear the loaders ArrayList.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                loaders.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        } catch (Throwable t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            throw new RuntimeException (t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        return ioExceptions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
}