Skip to content

Commit

Permalink
Simplify ResourceLoaders.
Browse files Browse the repository at this point in the history
Remove the ability to create a ResourceLoader from an arbitrary
ClassLoader and provide instead a ResourceLoader associated with
the current context ClassLoader, which is the way this class
was actually used anyway.

Change-Id: Ic1b873d524f0c194d18ee68b8fbbd26574100161
  • Loading branch information
rluble committed Jul 28, 2017
1 parent 5b7560c commit 3b47a80
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 66 deletions.
Expand Up @@ -437,7 +437,7 @@ private ModuleDef loadModule(TreeLogger logger) throws UnableToCompleteException
ZipFileClassPathEntry.clearCache(); ZipFileClassPathEntry.clearCache();
ResourceOracleImpl.clearCache(); ResourceOracleImpl.clearCache();


ResourceLoader resources = ResourceLoaders.forClassLoader(Thread.currentThread()); ResourceLoader resources = ResourceLoaders.fromContextClassLoader();
resources = ResourceLoaders.forPathAndFallback(options.getSourcePath(), resources); resources = ResourceLoaders.forPathAndFallback(options.getSourcePath(), resources);
this.resourceLoader.set(resources); this.resourceLoader.set(resources);


Expand Down
2 changes: 1 addition & 1 deletion dev/core/src/com/google/gwt/dev/Link.java
Expand Up @@ -418,7 +418,7 @@ private static void doProduceOutput(TreeLogger logger, ArtifactSet artifacts,
if (saveSources) { if (saveSources) {
// Assume that all source code is available in the compiler's classpath. // Assume that all source code is available in the compiler's classpath.
// (This will have to be adjusted to work with Super Dev Mode.) // (This will have to be adjusted to work with Super Dev Mode.)
ResourceLoader loader = ResourceLoaders.forClassLoader(Thread.currentThread()); ResourceLoader loader = ResourceLoaders.fromContextClassLoader();
SourceSaver.save(logger, artifacts, loader, options, destPrefix, extraFileSet); SourceSaver.save(logger, artifacts, loader, options, destPrefix, extraFileSet);
} }


Expand Down
2 changes: 1 addition & 1 deletion dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
Expand Up @@ -178,7 +178,7 @@ public static boolean isValidModuleName(String moduleName) {
private Map<String, String> gwtXmlPathByModuleName = Maps.newHashMap(); private Map<String, String> gwtXmlPathByModuleName = Maps.newHashMap();


public ModuleDef(String name) { public ModuleDef(String name) {
this(name, ResourceLoaders.forClassLoader(Thread.currentThread())); this(name, ResourceLoaders.fromContextClassLoader());
} }


public ModuleDef(String name, ResourceLoader resources) { public ModuleDef(String name, ResourceLoader resources) {
Expand Down
4 changes: 2 additions & 2 deletions dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
Expand Up @@ -84,7 +84,7 @@ public static ModuleDef createSyntheticModule(TreeLogger logger, String moduleNa
return moduleDef; return moduleDef;
} }


ResourceLoader resources = ResourceLoaders.forClassLoader(Thread.currentThread()); ResourceLoader resources = ResourceLoaders.fromContextClassLoader();


ModuleDefLoader loader = new ModuleDefLoader(resources) { ModuleDefLoader loader = new ModuleDefLoader(resources) {
@Override @Override
Expand Down Expand Up @@ -122,7 +122,7 @@ public static ModuleDef loadFromClassPath(TreeLogger logger, String moduleName)
*/ */
public static ModuleDef loadFromClassPath(TreeLogger logger, String moduleName, boolean refresh) public static ModuleDef loadFromClassPath(TreeLogger logger, String moduleName, boolean refresh)
throws UnableToCompleteException { throws UnableToCompleteException {
ResourceLoader resources = ResourceLoaders.forClassLoader(Thread.currentThread()); ResourceLoader resources = ResourceLoaders.fromContextClassLoader();
return loadFromResources(logger, moduleName, resources, refresh); return loadFromResources(logger, moduleName, resources, refresh);
} }


Expand Down
41 changes: 17 additions & 24 deletions dev/core/src/com/google/gwt/dev/cfg/ResourceLoaders.java
Expand Up @@ -18,44 +18,46 @@
import static com.google.gwt.thirdparty.guava.common.base.StandardSystemProperty.JAVA_CLASS_PATH; import static com.google.gwt.thirdparty.guava.common.base.StandardSystemProperty.JAVA_CLASS_PATH;


import com.google.gwt.thirdparty.guava.common.base.Splitter; import com.google.gwt.thirdparty.guava.common.base.Splitter;
import com.google.gwt.thirdparty.guava.common.collect.Sets;


import java.io.File; import java.io.File;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;


/** /**
* Creates instances of {@link ResourceLoader}. * Creates instances of {@link ResourceLoader}.
*/ */
public class ResourceLoaders { public class ResourceLoaders {


private static class ClassLoaderAdapter implements ResourceLoader { private static class ContextClassLoaderAdapter implements ResourceLoader {
private final ClassLoader wrapped; private final ClassLoader contextClassLoader;


public ClassLoaderAdapter(ClassLoader wrapped) { public ContextClassLoaderAdapter() {
// TODO(rluble): Maybe stop wrapping arbitrary class loaders here and always use the this.contextClassLoader = Thread.currentThread().getContextClassLoader();
// system ClassLoader.
this.wrapped = wrapped;
} }


@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (!(other instanceof ClassLoaderAdapter)) { if (!(other instanceof ContextClassLoaderAdapter)) {
return false; return false;
} }
ClassLoaderAdapter otherAdapter = (ClassLoaderAdapter) other; ContextClassLoaderAdapter otherAdapter = (ContextClassLoaderAdapter) other;
return wrapped.equals(otherAdapter.wrapped); return contextClassLoader.equals(otherAdapter.contextClassLoader);
} }


/** /**
* Returns the URLs for the system class path. * Returns the URLs for the system class path.
*/ */
@Override @Override
public List<URL> getClassPath() { public List<URL> getClassPath() {
List<URL> result = new ArrayList<URL>(); List<URL> result = new ArrayList<>();
for (String entry : Splitter.on(File.pathSeparatorChar).split(JAVA_CLASS_PATH.value())) { LinkedHashSet<String> uniqueClassPathEntries =
Sets.newLinkedHashSet(Splitter.on(File.pathSeparatorChar).split(JAVA_CLASS_PATH.value()));
for (String entry : uniqueClassPathEntries) {
try { try {
result.add(Paths.get(entry).toUri().toURL()); result.add(Paths.get(entry).toUri().toURL());
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
Expand All @@ -66,12 +68,12 @@ public List<URL> getClassPath() {


@Override @Override
public URL getResource(String resourceName) { public URL getResource(String resourceName) {
return wrapped.getResource(resourceName); return contextClassLoader.getResource(resourceName);
} }


@Override @Override
public int hashCode() { public int hashCode() {
return wrapped.hashCode(); return contextClassLoader.hashCode();
} }
} }


Expand Down Expand Up @@ -137,8 +139,8 @@ public int hashCode() {
/** /**
* Creates a ResourceLoader that loads from the given thread's class loader. * Creates a ResourceLoader that loads from the given thread's class loader.
*/ */
public static ResourceLoader forClassLoader(Thread thread) { public static ResourceLoader fromContextClassLoader() {
return wrap(thread.getContextClassLoader()); return new ContextClassLoaderAdapter();
} }


/** /**
Expand All @@ -149,15 +151,6 @@ public static ResourceLoader forPathAndFallback(List<File> path, ResourceLoader
return new PrefixLoader(path, fallback); return new PrefixLoader(path, fallback);
} }


/**
* Adapts a ClassLoader to work as a ResourceLoader.
* (Caveat: any ClassLoader in the chain that isn't a URLClassLoader won't contribute to the
* results of {@link ResourceLoader#getClassPath}.)
*/
public static ResourceLoader wrap(ClassLoader loader) {
return new ClassLoaderAdapter(loader);
}

private ResourceLoaders() { private ResourceLoaders() {
} }
} }
Expand Up @@ -204,14 +204,7 @@ public static ClassPathEntry createEntryForUrl(TreeLogger logger, URL url)
* Preinitializes the classpath from the thread default {@link ClassLoader}. * Preinitializes the classpath from the thread default {@link ClassLoader}.
*/ */
public static void preload(TreeLogger logger) { public static void preload(TreeLogger logger) {
preload(logger, Thread.currentThread().getContextClassLoader()); preload(logger, ResourceLoaders.fromContextClassLoader());
}

/**
* Preinitializes the classpath for a given {@link ClassLoader}.
*/
public static void preload(TreeLogger logger, ClassLoader classLoader) {
preload(logger, ResourceLoaders.wrap(classLoader));
} }


/** /**
Expand Down Expand Up @@ -387,17 +380,7 @@ public ResourceOracleImpl(List<ClassPathEntry> classPathEntries) {
* {@link ClassLoader}. * {@link ClassLoader}.
*/ */
public ResourceOracleImpl(TreeLogger logger) { public ResourceOracleImpl(TreeLogger logger) {
this(logger, Thread.currentThread().getContextClassLoader()); this(logger, ResourceLoaders.fromContextClassLoader());
}

/**
* Constructs a {@link ResourceOracleImpl} from a {@link ClassLoader}. The
* specified {@link ClassLoader} and all of its parents which are instances of
* {@link java.net.URLClassLoader} will have their class path entries added to this
* instances underlying class path.
*/
public ResourceOracleImpl(TreeLogger logger, ClassLoader classLoader) {
this(logger, ResourceLoaders.wrap(classLoader));
} }


public ResourceOracleImpl(TreeLogger logger, ResourceLoader resources) { public ResourceOracleImpl(TreeLogger logger, ResourceLoader resources) {
Expand Down
4 changes: 2 additions & 2 deletions dev/core/test/com/google/gwt/dev/CompilerTest.java
Expand Up @@ -2504,7 +2504,7 @@ private void assertCompileSucceeds(CompilerOptions options, String moduleName,


// Fake out the resource loader to read resources both from the normal classpath as well as // Fake out the resource loader to read resources both from the normal classpath as well as
// this new application directory. // this new application directory.
ResourceLoader resourceLoader = ResourceLoaders.forClassLoader(Thread.currentThread()); ResourceLoader resourceLoader = ResourceLoaders.fromContextClassLoader();
resourceLoader = resourceLoader =
ResourceLoaders.forPathAndFallback(ImmutableList.of(applicationDir), resourceLoader); ResourceLoaders.forPathAndFallback(ImmutableList.of(applicationDir), resourceLoader);


Expand Down Expand Up @@ -2688,7 +2688,7 @@ private String compileToJs(TreeLogger logger, CompilerOptions compilerOptions, F


// Fake out the resource loader to read resources both from the normal classpath as well as this // Fake out the resource loader to read resources both from the normal classpath as well as this
// new application directory. // new application directory.
ResourceLoader resourceLoader = ResourceLoaders.forClassLoader(Thread.currentThread()); ResourceLoader resourceLoader = ResourceLoaders.fromContextClassLoader();
resourceLoader = resourceLoader =
ResourceLoaders.forPathAndFallback(ImmutableList.of(applicationDir), resourceLoader); ResourceLoaders.forPathAndFallback(ImmutableList.of(applicationDir), resourceLoader);


Expand Down
Expand Up @@ -27,7 +27,6 @@
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
Expand Down Expand Up @@ -335,25 +334,18 @@ public void testReadingResource() throws IOException, URISyntaxException {
} }


/** /**
* Verify that duplicate entries are removed from the classpath, and that * Verify ResourceOracleImpls created from the same state return the same list of
* multiple ResourceOracleImpls created from the same classloader return the * ClassPathEntries.
* same list of ClassPathEntries.
*/ */
public void testRemoveDuplicates() { public void testSameClassPathEntries() {
TreeLogger logger = createTestTreeLogger(); TreeLogger logger = createTestTreeLogger();
URL cpe1 = findUrl("com/google/gwt/dev/resource/impl/testdata/cpe1.jar"); ResourceOracleImpl oracle = new ResourceOracleImpl(logger);
URL cpe2 = findUrl("com/google/gwt/dev/resource/impl/testdata/cpe2.zip");
URLClassLoader classLoader = new URLClassLoader(new URL[]{
cpe1, cpe2, cpe2, cpe1, cpe2,}, null);
ResourceOracleImpl oracle = new ResourceOracleImpl(logger, classLoader);
List<ClassPathEntry> classPathEntries = oracle.getClassPathEntries(); List<ClassPathEntry> classPathEntries = oracle.getClassPathEntries();
assertEquals(2, classPathEntries.size());
assertJarEntry(classPathEntries.get(0), "cpe1.jar"); oracle = new ResourceOracleImpl(logger);
assertJarEntry(classPathEntries.get(1), "cpe2.zip");
oracle = new ResourceOracleImpl(logger, classLoader);
List<ClassPathEntry> classPathEntries2 = oracle.getClassPathEntries(); List<ClassPathEntry> classPathEntries2 = oracle.getClassPathEntries();
assertEquals(2, classPathEntries2.size()); assertEquals(classPathEntries.size(), classPathEntries2.size());
for (int i = 0; i < 2; ++i) { for (int i = 0; i < classPathEntries2.size(); ++i) {
assertSame(classPathEntries.get(i), classPathEntries2.get(i)); assertSame(classPathEntries.get(i), classPathEntries2.get(i));
} }
} }
Expand Down

0 comments on commit 3b47a80

Please sign in to comment.