aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/util
diff options
context:
space:
mode:
authorGravatar cushon <cushon@google.com>2017-10-05 20:20:46 +0200
committerGravatar Klaus Aehlig <aehlig@google.com>2017-10-06 19:47:51 +0200
commite9cc5120754841baafe2f37d76fcfa8bb63e7d45 (patch)
treee97fafddfaaf55aed296e6ca50278918850ce9e3 /src/main/java/com/google/devtools/build/lib/util
parent06d24101e4a77a14e006e37382e5bb25cd56e944 (diff)
Prepare Classpath reading for Java 9
PiperOrigin-RevId: 171180273
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/util')
-rw-r--r--src/main/java/com/google/devtools/build/lib/util/Classpath.java151
1 files changed, 12 insertions, 139 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/util/Classpath.java b/src/main/java/com/google/devtools/build/lib/util/Classpath.java
index 7fb48c0140..c976a20b45 100644
--- a/src/main/java/com/google/devtools/build/lib/util/Classpath.java
+++ b/src/main/java/com/google/devtools/build/lib/util/Classpath.java
@@ -13,29 +13,17 @@
// limitations under the License.
package com.google.devtools.build.lib.util;
-import java.io.File;
+import com.google.common.reflect.ClassPath;
+import com.google.common.reflect.ClassPath.ClassInfo;
import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.Paths;
-import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
-import java.util.TreeSet;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
/**
* A helper class to find all classes on the current classpath. This is used to automatically create
* JUnit 3 and 4 test suites.
*/
public final class Classpath {
- private static final String CLASS_EXTENSION = ".class";
/**
* Base exception for any classpath related errors.
@@ -49,135 +37,20 @@ public final class Classpath {
/** Finds all classes that live in or below the given package. */
public static Set<Class<?>> findClasses(String packageName) throws ClassPathException {
Set<Class<?>> result = new LinkedHashSet<>();
- String pathPrefix = (packageName + '.').replace('.', '/');
- for (String entryName : getClassPath()) {
- File classPathEntry = new File(entryName);
- if (classPathEntry.exists()) {
- try {
- Set<String> classNames;
- if (classPathEntry.isDirectory()) {
- classNames = findClassesInDirectory(classPathEntry, pathPrefix);
- } else {
- classNames = findClassesInJar(classPathEntry, pathPrefix);
- }
- for (String className : classNames) {
- try {
- Class<?> clazz = Class.forName(className);
- result.add(clazz);
- } catch (UnsatisfiedLinkError | NoClassDefFoundError unused) {
- // Ignore: we're most likely running on a different platform.
- }
- }
- } catch (IOException e) {
- throw new ClassPathException(
- "Can't read classpath entry %s: %s", entryName, e.getMessage());
- } catch (ClassNotFoundException e) {
- throw new ClassPathException(
- "Class not found even though it is on the classpath %s: %s",
- entryName, e.getMessage());
- }
- }
- }
- return result;
- }
-
- private static Set<String> findClassesInDirectory(File classPathEntry, String pathPrefix) {
- Set<String> result = new TreeSet<>();
- File directory = new File(classPathEntry, pathPrefix);
- innerFindClassesInDirectory(result, directory, pathPrefix);
- return result;
- }
-
- /**
- * Finds all classes and sub packages in the given directory that are below the given package and
- * add them to the respective sets.
- *
- * @param directory Directory to inspect
- * @param pathPrefix Prefix for the path to the classes that are requested
- * (ex: {@code com/google/foo/bar})
- */
- private static void innerFindClassesInDirectory(Set<String> classNames, File directory,
- String pathPrefix) {
- Preconditions.checkArgument(pathPrefix.endsWith("/"));
- if (directory.exists()) {
- for (File f : directory.listFiles()) {
- String name = f.getName();
- if (name.endsWith(CLASS_EXTENSION)) {
- String clzName = getClassName(pathPrefix + name);
- classNames.add(clzName);
- } else if (f.isDirectory()) {
- findClassesInDirectory(f, pathPrefix + name + "/");
- }
- }
- }
- }
-
- /**
- * Returns a set of all classes in the jar that start with the given prefix.
- */
- private static Set<String> findClassesInJar(File jarFile, String pathPrefix) throws IOException {
- Set<String> classNames = new TreeSet<>();
- try (ZipFile zipFile = new ZipFile(jarFile)) {
- Enumeration<? extends ZipEntry> entries = zipFile.entries();
- while (entries.hasMoreElements()) {
- String entryName = entries.nextElement().getName();
- if (entryName.startsWith(pathPrefix) && entryName.endsWith(CLASS_EXTENSION)) {
- classNames.add(getClassName(entryName));
- }
- }
- }
- return classNames;
- }
-
- /**
- * Given the absolute path of a class file, return the class name.
- */
- private static String getClassName(String className) {
- int classNameEnd = className.length() - CLASS_EXTENSION.length();
- return className.substring(0, classNameEnd).replace('/', '.');
- }
-
- private static void getClassPathsFromClasspathJar(File classpathJar, Set<String> classPaths)
- throws IOException, ClassPathException {
- Manifest manifest = new JarFile(classpathJar).getManifest();
- Attributes attributes = manifest.getMainAttributes();
- for (String classPath : attributes.getValue("Class-Path").split(" ")) {
- try {
- classPaths.add(Paths.get(new URI(classPath)).toAbsolutePath().toString());
- } catch (URISyntaxException e) {
- throw new ClassPathException(
- "Error parsing classpath uri %s: %s", classPath, e.getMessage());
- }
- }
- }
-
- /** Gets the classpath from current classloader. */
- private static Set<String> getClassPath() throws ClassPathException {
- ClassLoader classloader = Classpath.class.getClassLoader();
- if (!(classloader instanceof URLClassLoader)) {
- throw new IllegalStateException("Unable to find classes to test, since Test Suite class is "
- + "loaded by an unsupported Classloader.");
- }
-
- Set<String> completeClassPaths = new TreeSet<>();
- URL[] urls = ((URLClassLoader) classloader).getURLs();
- for (URL url : urls) {
- String entryName = url.getPath();
- completeClassPaths.add(entryName);
- if (entryName.endsWith("-classpath.jar")) {
- // Bazel creates a classpath jar when the class path length exceeds command line length
- // limit, read the class path value from its manifest file if it's a classpath jar.
- File classPathEntry = new File(entryName);
- if (classPathEntry.exists() && classPathEntry.isFile()) {
+ String packagePrefix = (packageName + '.').replace('/', '.');
+ try {
+ for (ClassInfo ci : ClassPath.from(Classpath.class.getClassLoader()).getAllClasses()) {
+ if (ci.getName().startsWith(packagePrefix)) {
try {
- getClassPathsFromClasspathJar(classPathEntry, completeClassPaths);
- } catch (IOException e) {
- throw new ClassPathException(
- "Can't read classpath entry %s: %s", entryName, e.getMessage());
+ result.add(ci.load());
+ } catch (UnsatisfiedLinkError | NoClassDefFoundError unused) {
+ // Ignore: we're most likely running on a different platform.
}
}
}
+ } catch (IOException e) {
+ throw new ClassPathException(e.getMessage());
}
- return completeClassPaths;
+ return result;
}
}