Skip to content

Commit

Permalink
Fix tests that assume Class.getClassLoader() returns a URLClassLoader…
Browse files Browse the repository at this point in the history
… so that they can call getURLs() to instead parse the "java.class.path" system property.

This doesn't fully fix FinalizableReferenceQueueClassLoaderUnloadingTest: I still see a failure for testUnloadableInStaticFieldIfClosed. But at least the other 2 tests in the file pass, and the failure is now a "real" failure ("Predicate did not become true within 10 second timeout") rather than a ClassCastException.

(I've confirmed that the failing test computes exactly the same classpath under Java 9 as under Java 8, so I'm not sure exactly what's up. I may ask emcmanus.)

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=182227182
  • Loading branch information
cpovirk committed Jan 17, 2018
1 parent b0a6cfe commit 8eb3ea4
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 12 deletions.
Expand Up @@ -16,11 +16,17 @@


package com.google.common.base; package com.google.common.base;


import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_PATH;
import static com.google.common.base.StandardSystemProperty.PATH_SEPARATOR;

import com.google.common.collect.ImmutableList;
import com.google.common.testing.GcFinalization; import com.google.common.testing.GcFinalization;
import java.io.Closeable; import java.io.Closeable;
import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.security.Permission; import java.security.Permission;
Expand Down Expand Up @@ -75,9 +81,8 @@ public boolean implies(ProtectionDomain pd, Permission perm) {
} }


private WeakReference<ClassLoader> useFrqInSeparateLoader() throws Exception { private WeakReference<ClassLoader> useFrqInSeparateLoader() throws Exception {
final URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader(); final ClassLoader myLoader = getClass().getClassLoader();
final URL[] urls = myLoader.getURLs(); URLClassLoader sepLoader = new URLClassLoader(getClassPathUrls(), myLoader.getParent());
URLClassLoader sepLoader = new URLClassLoader(urls, myLoader.getParent());
// sepLoader is the loader that we will use to load the parallel FinalizableReferenceQueue (FRQ) // sepLoader is the loader that we will use to load the parallel FinalizableReferenceQueue (FRQ)
// and friends, and that we will eventually expect to see garbage-collected. The assumption // and friends, and that we will eventually expect to see garbage-collected. The assumption
// is that the ClassLoader of this test is a URLClassLoader, and that it loads FRQ itself // is that the ClassLoader of this test is a URLClassLoader, and that it loads FRQ itself
Expand Down Expand Up @@ -201,9 +206,8 @@ public void testUnloadableInStaticFieldIfClosed() throws Exception {
// gc'd even if there is a still a FinalizableReferenceQueue in a static field. (Setting the field // gc'd even if there is a still a FinalizableReferenceQueue in a static field. (Setting the field
// to null would also work, but only if there are no references to the FRQ anywhere else.) // to null would also work, but only if there are no references to the FRQ anywhere else.)
private WeakReference<ClassLoader> doTestUnloadableInStaticFieldIfClosed() throws Exception { private WeakReference<ClassLoader> doTestUnloadableInStaticFieldIfClosed() throws Exception {
final URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader(); final ClassLoader myLoader = getClass().getClassLoader();
final URL[] urls = myLoader.getURLs(); URLClassLoader sepLoader = new URLClassLoader(getClassPathUrls(), myLoader.getParent());
URLClassLoader sepLoader = new URLClassLoader(urls, myLoader.getParent());


Class<?> frqC = FinalizableReferenceQueue.class; Class<?> frqC = FinalizableReferenceQueue.class;
Class<?> sepFrqC = sepLoader.loadClass(frqC.getName()); Class<?> sepFrqC = sepLoader.loadClass(frqC.getName());
Expand Down Expand Up @@ -236,4 +240,34 @@ private WeakReference<ClassLoader> doTestUnloadableInStaticFieldIfClosed() throw


return new WeakReference<ClassLoader>(sepLoader); return new WeakReference<ClassLoader>(sepLoader);
} }

private URL[] getClassPathUrls() {
ClassLoader classLoader = getClass().getClassLoader();
return classLoader instanceof URLClassLoader
? ((URLClassLoader) classLoader).getURLs()
: parseJavaClassPath().toArray(new URL[0]);
}

/**
* Returns the URLs in the class path specified by the {@code java.class.path} {@linkplain
* System#getProperty system property}.
*/
// TODO(b/65488446): Make this a public API.
private static ImmutableList<URL> parseJavaClassPath() {
ImmutableList.Builder<URL> urls = ImmutableList.builder();
for (String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) {
try {
try {
urls.add(new File(entry).toURI().toURL());
} catch (SecurityException e) { // File.toURI checks to see if the file is a directory
urls.add(new URL("file", null, new File(entry).getAbsolutePath()));
}
} catch (MalformedURLException e) {
AssertionError error = new AssertionError("malformed class path entry: " + entry);
error.initCause(e);
throw error;
}
}
return urls.build();
}
} }
Expand Up @@ -16,11 +16,17 @@


package com.google.common.base; package com.google.common.base;


import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_PATH;
import static com.google.common.base.StandardSystemProperty.PATH_SEPARATOR;

import com.google.common.collect.ImmutableList;
import com.google.common.testing.GcFinalization; import com.google.common.testing.GcFinalization;
import java.io.Closeable; import java.io.Closeable;
import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.security.Permission; import java.security.Permission;
Expand Down Expand Up @@ -75,9 +81,8 @@ public boolean implies(ProtectionDomain pd, Permission perm) {
} }


private WeakReference<ClassLoader> useFrqInSeparateLoader() throws Exception { private WeakReference<ClassLoader> useFrqInSeparateLoader() throws Exception {
final URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader(); final ClassLoader myLoader = getClass().getClassLoader();
final URL[] urls = myLoader.getURLs(); URLClassLoader sepLoader = new URLClassLoader(getClassPathUrls(), myLoader.getParent());
URLClassLoader sepLoader = new URLClassLoader(urls, myLoader.getParent());
// sepLoader is the loader that we will use to load the parallel FinalizableReferenceQueue (FRQ) // sepLoader is the loader that we will use to load the parallel FinalizableReferenceQueue (FRQ)
// and friends, and that we will eventually expect to see garbage-collected. The assumption // and friends, and that we will eventually expect to see garbage-collected. The assumption
// is that the ClassLoader of this test is a URLClassLoader, and that it loads FRQ itself // is that the ClassLoader of this test is a URLClassLoader, and that it loads FRQ itself
Expand Down Expand Up @@ -201,9 +206,8 @@ public void testUnloadableInStaticFieldIfClosed() throws Exception {
// gc'd even if there is a still a FinalizableReferenceQueue in a static field. (Setting the field // gc'd even if there is a still a FinalizableReferenceQueue in a static field. (Setting the field
// to null would also work, but only if there are no references to the FRQ anywhere else.) // to null would also work, but only if there are no references to the FRQ anywhere else.)
private WeakReference<ClassLoader> doTestUnloadableInStaticFieldIfClosed() throws Exception { private WeakReference<ClassLoader> doTestUnloadableInStaticFieldIfClosed() throws Exception {
final URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader(); final ClassLoader myLoader = getClass().getClassLoader();
final URL[] urls = myLoader.getURLs(); URLClassLoader sepLoader = new URLClassLoader(getClassPathUrls(), myLoader.getParent());
URLClassLoader sepLoader = new URLClassLoader(urls, myLoader.getParent());


Class<?> frqC = FinalizableReferenceQueue.class; Class<?> frqC = FinalizableReferenceQueue.class;
Class<?> sepFrqC = sepLoader.loadClass(frqC.getName()); Class<?> sepFrqC = sepLoader.loadClass(frqC.getName());
Expand Down Expand Up @@ -236,4 +240,34 @@ private WeakReference<ClassLoader> doTestUnloadableInStaticFieldIfClosed() throw


return new WeakReference<ClassLoader>(sepLoader); return new WeakReference<ClassLoader>(sepLoader);
} }

private URL[] getClassPathUrls() {
ClassLoader classLoader = getClass().getClassLoader();
return classLoader instanceof URLClassLoader
? ((URLClassLoader) classLoader).getURLs()
: parseJavaClassPath().toArray(new URL[0]);
}

/**
* Returns the URLs in the class path specified by the {@code java.class.path} {@linkplain
* System#getProperty system property}.
*/
// TODO(b/65488446): Make this a public API.
private static ImmutableList<URL> parseJavaClassPath() {
ImmutableList.Builder<URL> urls = ImmutableList.builder();
for (String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) {
try {
try {
urls.add(new File(entry).toURI().toURL());
} catch (SecurityException e) { // File.toURI checks to see if the file is a directory
urls.add(new URL("file", null, new File(entry).getAbsolutePath()));
}
} catch (MalformedURLException e) {
AssertionError error = new AssertionError("malformed class path entry: " + entry);
error.initCause(e);
throw error;
}
}
return urls.build();
}
} }

0 comments on commit 8eb3ea4

Please sign in to comment.