mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8302819: Remove JAR Index
Reviewed-by: mchung, alanb, lancea, jpai
This commit is contained in:
parent
0243da2e4a
commit
0d45a524b3
24 changed files with 45 additions and 1394 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -207,12 +207,18 @@ public class JarFile extends ZipFile {
|
|||
*/
|
||||
public static final String MANIFEST_NAME = META_INF + "MANIFEST.MF";
|
||||
|
||||
/**
|
||||
* The 'JAR index' feature has been removed, but JarInputStream and
|
||||
* JarVerifier's verification of signed jars still need to be
|
||||
* able to skip this entry.
|
||||
*/
|
||||
static final String INDEX_NAME = "META-INF/INDEX.LIST";
|
||||
|
||||
/**
|
||||
* Returns the version that represents the unversioned configuration of a
|
||||
* multi-release jar file.
|
||||
*
|
||||
* @return the version that represents the unversioned configuration
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public static Runtime.Version baseVersion() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -28,7 +28,6 @@ package java.util.jar;
|
|||
import java.util.zip.*;
|
||||
import java.io.*;
|
||||
import sun.security.util.ManifestEntryVerifier;
|
||||
import jdk.internal.util.jar.JarIndex;
|
||||
|
||||
/**
|
||||
* The {@code JarInputStream} class, which extends {@link ZipInputStream},
|
||||
|
@ -185,7 +184,7 @@ public class JarInputStream extends ZipInputStream {
|
|||
}
|
||||
} else {
|
||||
e = first;
|
||||
if (first.getName().equalsIgnoreCase(JarIndex.INDEX_NAME))
|
||||
if (first.getName().equalsIgnoreCase(JarFile.INDEX_NAME))
|
||||
tryManifest = true;
|
||||
first = null;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import java.security.SignatureException;
|
|||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import jdk.internal.util.jar.JarIndex;
|
||||
import sun.security.util.ManifestDigester;
|
||||
import sun.security.util.ManifestEntryVerifier;
|
||||
import sun.security.util.SignatureFileVerifier;
|
||||
|
@ -146,7 +145,7 @@ class JarVerifier {
|
|||
}
|
||||
String uname = name.toUpperCase(Locale.ENGLISH);
|
||||
if (uname.equals(JarFile.MANIFEST_NAME) ||
|
||||
uname.equals(JarIndex.INDEX_NAME)) {
|
||||
uname.equals(JarFile.INDEX_NAME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -71,8 +71,6 @@ import java.util.zip.ZipFile;
|
|||
import jdk.internal.access.JavaNetURLAccess;
|
||||
import jdk.internal.access.JavaUtilZipFileAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.util.jar.InvalidJarIndexError;
|
||||
import jdk.internal.util.jar.JarIndex;
|
||||
import sun.net.util.URLUtil;
|
||||
import sun.net.www.ParseUtil;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
@ -91,7 +89,6 @@ public class URLClassPath {
|
|||
private static final boolean DISABLE_ACC_CHECKING;
|
||||
private static final boolean DISABLE_CP_URL_CHECK;
|
||||
private static final boolean DEBUG_CP_URL_CHECK;
|
||||
private static final boolean ENABLE_JAR_INDEX;
|
||||
|
||||
static {
|
||||
Properties props = GetPropertyAction.privilegedGetProperties();
|
||||
|
@ -111,9 +108,6 @@ public class URLClassPath {
|
|||
// the check is not disabled).
|
||||
p = props.getProperty("jdk.net.URLClassPath.showIgnoredClassPathEntries");
|
||||
DEBUG_CP_URL_CHECK = p != null ? p.equals("true") || p.isEmpty() : false;
|
||||
|
||||
p = props.getProperty("jdk.net.URLClassPath.enableJarIndex");
|
||||
ENABLE_JAR_INDEX = p != null ? p.equals("true") || p.isEmpty() : false;
|
||||
}
|
||||
|
||||
/* The original search path of URLs. */
|
||||
|
@ -714,7 +708,6 @@ public class URLClassPath {
|
|||
private static class JarLoader extends Loader {
|
||||
private JarFile jar;
|
||||
private final URL csu;
|
||||
private JarIndex index;
|
||||
private URLStreamHandler handler;
|
||||
private final HashMap<String, Loader> lmap;
|
||||
@SuppressWarnings("removal")
|
||||
|
@ -779,31 +772,6 @@ public class URLClassPath {
|
|||
Thread.dumpStack();
|
||||
}
|
||||
jar = getJarFile(csu);
|
||||
if (!ENABLE_JAR_INDEX) {
|
||||
return null;
|
||||
}
|
||||
index = JarIndex.getJarIndex(jar);
|
||||
if (index != null) {
|
||||
String[] jarfiles = index.getJarFiles();
|
||||
// Add all the dependent URLs to the lmap so that loaders
|
||||
// will not be created for them by URLClassPath.getLoader(int)
|
||||
// if the same URL occurs later on the main class path. We set
|
||||
// Loader to null here to avoid creating a Loader for each
|
||||
// URL until we actually need to try to load something from them.
|
||||
for (int i = 0; i < jarfiles.length; i++) {
|
||||
try {
|
||||
@SuppressWarnings("deprecation")
|
||||
URL jarURL = new URL(csu, jarfiles[i]);
|
||||
// If a non-null loader already exists, leave it alone.
|
||||
String urlNoFragString = URLUtil.urlNoFragString(jarURL);
|
||||
if (!lmap.containsKey(urlNoFragString)) {
|
||||
lmap.put(urlNoFragString, null);
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
|
@ -847,18 +815,6 @@ public class URLClassPath {
|
|||
return checkJar(jarFile);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the index of this JarLoader if it exists.
|
||||
*/
|
||||
JarIndex getIndex() {
|
||||
try {
|
||||
ensureOpen();
|
||||
} catch (IOException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates the resource and if the check flag is set to true, checks if
|
||||
* is its okay to return the resource.
|
||||
|
@ -968,138 +924,15 @@ public class URLClassPath {
|
|||
if (entry != null)
|
||||
return checkResource(name, check, entry);
|
||||
|
||||
if (index == null)
|
||||
return null;
|
||||
|
||||
HashSet<String> visited = new HashSet<>();
|
||||
return getResource(name, check, visited);
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of getResource() that tracks the jar files that have been
|
||||
* visited by linking through the index files. This helper method uses
|
||||
* a HashSet to store the URLs of jar files that have been searched and
|
||||
* uses it to avoid going into an infinite loop, looking for a
|
||||
* non-existent resource.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
Resource getResource(final String name, boolean check,
|
||||
Set<String> visited) {
|
||||
Resource res;
|
||||
String[] jarFiles;
|
||||
int count = 0;
|
||||
List<String> jarFilesList;
|
||||
|
||||
/* If there no jar files in the index that can potential contain
|
||||
* this resource then return immediately.
|
||||
*/
|
||||
if ((jarFilesList = index.get(name)) == null)
|
||||
return null;
|
||||
|
||||
do {
|
||||
int size = jarFilesList.size();
|
||||
jarFiles = jarFilesList.toArray(new String[size]);
|
||||
/* loop through the mapped jar file list */
|
||||
while (count < size) {
|
||||
String jarName = jarFiles[count++];
|
||||
JarLoader newLoader;
|
||||
final URL url;
|
||||
|
||||
try{
|
||||
@SuppressWarnings("deprecation")
|
||||
var _unused = url = new URL(csu, jarName);
|
||||
String urlNoFragString = URLUtil.urlNoFragString(url);
|
||||
if ((newLoader = (JarLoader)lmap.get(urlNoFragString)) == null) {
|
||||
/* no loader has been set up for this jar file
|
||||
* before
|
||||
*/
|
||||
newLoader = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<>() {
|
||||
public JarLoader run() throws IOException {
|
||||
return new JarLoader(url, handler,
|
||||
lmap, acc);
|
||||
}
|
||||
}, acc);
|
||||
|
||||
/* this newly opened jar file has its own index,
|
||||
* merge it into the parent's index, taking into
|
||||
* account the relative path.
|
||||
*/
|
||||
JarIndex newIndex = newLoader.getIndex();
|
||||
if (newIndex != null) {
|
||||
int pos = jarName.lastIndexOf('/');
|
||||
newIndex.merge(this.index, (pos == -1 ?
|
||||
null : jarName.substring(0, pos + 1)));
|
||||
}
|
||||
|
||||
/* put it in the global hashtable */
|
||||
lmap.put(urlNoFragString, newLoader);
|
||||
}
|
||||
} catch (PrivilegedActionException | MalformedURLException e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Note that the addition of the url to the list of visited
|
||||
* jars incorporates a check for presence in the hashmap
|
||||
*/
|
||||
boolean visitedURL = !visited.add(URLUtil.urlNoFragString(url));
|
||||
if (!visitedURL) {
|
||||
try {
|
||||
newLoader.ensureOpen();
|
||||
} catch (IOException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
final JarEntry entry = newLoader.jar.getJarEntry(name);
|
||||
if (entry != null) {
|
||||
return newLoader.checkResource(name, check, entry);
|
||||
}
|
||||
|
||||
/* Verify that at least one other resource with the
|
||||
* same package name as the lookedup resource is
|
||||
* present in the new jar
|
||||
*/
|
||||
if (!newLoader.validIndex(name)) {
|
||||
/* the mapping is wrong */
|
||||
throw new InvalidJarIndexError("Invalid index");
|
||||
}
|
||||
}
|
||||
|
||||
/* If newLoader is the current loader or if it is a
|
||||
* loader that has already been searched or if the new
|
||||
* loader does not have an index then skip it
|
||||
* and move on to the next loader.
|
||||
*/
|
||||
if (visitedURL || newLoader == this ||
|
||||
newLoader.getIndex() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Process the index of the new loader
|
||||
*/
|
||||
if ((res = newLoader.getResource(name, check, visited))
|
||||
!= null) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
// Get the list of jar files again as the list could have grown
|
||||
// due to merging of index files.
|
||||
jarFilesList = index.get(name);
|
||||
|
||||
// If the count is unchanged, we are done.
|
||||
} while (count < jarFilesList.size());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the JAR file local class path, or null if none.
|
||||
*/
|
||||
@Override
|
||||
URL[] getClassPath() throws IOException {
|
||||
if (index != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ensureOpen();
|
||||
|
||||
// Only get manifest when necessary
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.internal.util.jar;
|
||||
|
||||
/**
|
||||
* Thrown if the URLClassLoader finds the INDEX.LIST file of
|
||||
* a jar file contains incorrect information.
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
|
||||
public class InvalidJarIndexError extends Error {
|
||||
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 0L;
|
||||
|
||||
/**
|
||||
* Constructs an {@code InvalidJarIndexError} with no detail message.
|
||||
*/
|
||||
public InvalidJarIndexError() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code InvalidJarIndexError} with the specified detail message.
|
||||
*
|
||||
* @param s the detail message.
|
||||
*/
|
||||
public InvalidJarIndexError(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
|
@ -1,333 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.internal.util.jar;
|
||||
|
||||
import sun.nio.cs.UTF_8;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.jar.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
import static sun.security.action.GetPropertyAction.privilegedGetProperty;
|
||||
|
||||
/**
|
||||
* This class is used to maintain mappings from packages, classes
|
||||
* and resources to their enclosing JAR files. Mappings are kept
|
||||
* at the package level except for class or resource files that
|
||||
* are located at the root directory. URLClassLoader uses the mapping
|
||||
* information to determine where to fetch an extension class or
|
||||
* resource from.
|
||||
*
|
||||
* @author Zhenghua Li
|
||||
* @since 1.3
|
||||
*/
|
||||
|
||||
public class JarIndex {
|
||||
|
||||
/**
|
||||
* The hash map that maintains mappings from
|
||||
* package/class/resource to jar file list(s)
|
||||
*/
|
||||
private final HashMap<String, List<String>> indexMap;
|
||||
|
||||
/**
|
||||
* The hash map that maintains mappings from
|
||||
* jar file to package/class/resource lists
|
||||
*/
|
||||
private final HashMap<String, List<String>> jarMap;
|
||||
|
||||
/*
|
||||
* An ordered list of jar file names.
|
||||
*/
|
||||
private String[] jarFiles;
|
||||
|
||||
/**
|
||||
* The index file name.
|
||||
*/
|
||||
public static final String INDEX_NAME = "META-INF/INDEX.LIST";
|
||||
|
||||
/**
|
||||
* true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
|
||||
* If true, the names of the files in META-INF, and its subdirectories, will
|
||||
* be added to the index. Otherwise, just the directory names are added.
|
||||
*/
|
||||
private static final boolean metaInfFilenames =
|
||||
"true".equals(privilegedGetProperty("sun.misc.JarIndex.metaInfFilenames"));
|
||||
|
||||
/**
|
||||
* Constructs a new, empty jar index.
|
||||
*/
|
||||
public JarIndex() {
|
||||
indexMap = new HashMap<>();
|
||||
jarMap = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new index from the specified input stream.
|
||||
*
|
||||
* @param is the input stream containing the index data
|
||||
*/
|
||||
public JarIndex(InputStream is) throws IOException {
|
||||
this();
|
||||
read(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new index for the specified list of jar files.
|
||||
*
|
||||
* @param files the list of jar files to construct the index from.
|
||||
*/
|
||||
public JarIndex(String[] files) throws IOException {
|
||||
this();
|
||||
this.jarFiles = files;
|
||||
parseJars(files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the jar index, or <code>null</code> if none.
|
||||
*
|
||||
* @param jar the JAR file to get the index from.
|
||||
* @exception IOException if an I/O error has occurred.
|
||||
*/
|
||||
public static JarIndex getJarIndex(JarFile jar) throws IOException {
|
||||
JarIndex index = null;
|
||||
JarEntry e = jar.getJarEntry(INDEX_NAME);
|
||||
// if found, then load the index
|
||||
if (e != null) {
|
||||
index = new JarIndex(jar.getInputStream(e));
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the jar files that are defined in this index.
|
||||
*/
|
||||
public String[] getJarFiles() {
|
||||
return jarFiles;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the key, value pair to the hashmap, the value will
|
||||
* be put in a list which is created if necessary.
|
||||
*/
|
||||
private void addToList(String key, String value,
|
||||
HashMap<String, List<String>> t) {
|
||||
List<String> list = t.get(key);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>(1);
|
||||
list.add(value);
|
||||
t.put(key, list);
|
||||
} else if (!list.contains(value)) {
|
||||
list.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of jar files that are mapped to the file.
|
||||
*
|
||||
* @param fileName the key of the mapping
|
||||
*/
|
||||
public List<String> get(String fileName) {
|
||||
List<String> jarFiles;
|
||||
if ((jarFiles = indexMap.get(fileName)) == null) {
|
||||
/* try the package name again */
|
||||
int pos;
|
||||
if((pos = fileName.lastIndexOf('/')) != -1) {
|
||||
jarFiles = indexMap.get(fileName.substring(0, pos));
|
||||
}
|
||||
}
|
||||
return jarFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the mapping from the specified file to the specified
|
||||
* jar file. If there were no mapping for the package of the
|
||||
* specified file before, a new list will be created,
|
||||
* the jar file is added to the list and a new mapping from
|
||||
* the package to the jar file list is added to the hashmap.
|
||||
* Otherwise, the jar file will be added to the end of the
|
||||
* existing list.
|
||||
*
|
||||
* @param fileName the file name
|
||||
* @param jarName the jar file that the file is mapped to
|
||||
*
|
||||
*/
|
||||
public void add(String fileName, String jarName) {
|
||||
String packageName;
|
||||
int pos;
|
||||
if((pos = fileName.lastIndexOf('/')) != -1) {
|
||||
packageName = fileName.substring(0, pos);
|
||||
} else {
|
||||
packageName = fileName;
|
||||
}
|
||||
|
||||
addMapping(packageName, jarName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as add(String,String) except that it doesn't strip off from the
|
||||
* last index of '/'. It just adds the jarItem (filename or package)
|
||||
* as it is received.
|
||||
*/
|
||||
private void addMapping(String jarItem, String jarName) {
|
||||
// add the mapping to indexMap
|
||||
addToList(jarItem, jarName, indexMap);
|
||||
|
||||
// add the mapping to jarMap
|
||||
addToList(jarName, jarItem, jarMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through all the jar files and construct the
|
||||
* index table.
|
||||
*/
|
||||
private void parseJars(String[] files) throws IOException {
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String currentJar = null;
|
||||
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
currentJar = files[i];
|
||||
ZipFile zrf = new ZipFile(currentJar.replace
|
||||
('/', File.separatorChar));
|
||||
|
||||
Enumeration<? extends ZipEntry> entries = zrf.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
String fileName = entry.getName();
|
||||
|
||||
// Skip the META-INF directory, the index, and manifest.
|
||||
// Any files in META-INF/ will be indexed explicitly
|
||||
if (fileName.equals("META-INF/") ||
|
||||
fileName.equals(INDEX_NAME) ||
|
||||
fileName.equals(JarFile.MANIFEST_NAME) ||
|
||||
fileName.startsWith("META-INF/versions/"))
|
||||
continue;
|
||||
|
||||
if (!metaInfFilenames || !fileName.startsWith("META-INF/")) {
|
||||
add(fileName, currentJar);
|
||||
} else if (!entry.isDirectory()) {
|
||||
// Add files under META-INF explicitly so that certain
|
||||
// services, like ServiceLoader, etc, can be located
|
||||
// with greater accuracy. Directories can be skipped
|
||||
// since each file will be added explicitly.
|
||||
addMapping(fileName, currentJar);
|
||||
}
|
||||
}
|
||||
|
||||
zrf.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the index to the specified OutputStream
|
||||
*
|
||||
* @param out the output stream
|
||||
* @exception IOException if an I/O error has occurred
|
||||
*/
|
||||
public void write(OutputStream out) throws IOException {
|
||||
BufferedWriter bw = new BufferedWriter
|
||||
(new OutputStreamWriter(out, UTF_8.INSTANCE));
|
||||
bw.write("JarIndex-Version: 1.0\n\n");
|
||||
|
||||
if (jarFiles != null) {
|
||||
for (int i = 0; i < jarFiles.length; i++) {
|
||||
/* print out the jar file name */
|
||||
String jar = jarFiles[i];
|
||||
bw.write(jar + "\n");
|
||||
List<String> jarlist = jarMap.get(jar);
|
||||
if (jarlist != null) {
|
||||
for (String s : jarlist) {
|
||||
bw.write(s + "\n");
|
||||
}
|
||||
}
|
||||
bw.write("\n");
|
||||
}
|
||||
bw.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the index from the specified InputStream.
|
||||
*
|
||||
* @param is the input stream
|
||||
* @exception IOException if an I/O error has occurred
|
||||
*/
|
||||
public void read(InputStream is) throws IOException {
|
||||
BufferedReader br = new BufferedReader
|
||||
(new InputStreamReader(is, UTF_8.INSTANCE));
|
||||
String line;
|
||||
String currentJar = null;
|
||||
|
||||
/* an ordered list of jar file names */
|
||||
ArrayList<String> jars = new ArrayList<>();
|
||||
|
||||
/* read until we see a .jar line */
|
||||
while((line = br.readLine()) != null && !line.endsWith(".jar"));
|
||||
|
||||
for(;line != null; line = br.readLine()) {
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
|
||||
if (line.endsWith(".jar")) {
|
||||
currentJar = line;
|
||||
jars.add(currentJar);
|
||||
} else {
|
||||
String name = line;
|
||||
addMapping(name, currentJar);
|
||||
}
|
||||
}
|
||||
|
||||
jarFiles = jars.toArray(new String[jars.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the current index into another index, taking into account
|
||||
* the relative path of the current index.
|
||||
*
|
||||
* @param toIndex The destination index which the current index will
|
||||
* merge into.
|
||||
* @param path The relative path of the this index to the destination
|
||||
* index.
|
||||
*
|
||||
*/
|
||||
public void merge(JarIndex toIndex, String path) {
|
||||
for (Map.Entry<String, List<String>> e : indexMap.entrySet()) {
|
||||
String packageName = e.getKey();
|
||||
List<String> from_list = e.getValue();
|
||||
for (String jarName : from_list) {
|
||||
if (path != null) {
|
||||
jarName = path.concat(jarName);
|
||||
}
|
||||
toIndex.addMapping(packageName, jarName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -274,8 +274,6 @@ module java.base {
|
|||
jdk.unsupported;
|
||||
exports jdk.internal.vm.vector to
|
||||
jdk.incubator.vector;
|
||||
exports jdk.internal.util.jar to
|
||||
jdk.jartool;
|
||||
exports jdk.internal.util.xml to
|
||||
jdk.jfr;
|
||||
exports jdk.internal.util.xml.impl to
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue