mirror of https://github.com/sbt/sbt.git
Merge pull request #5540 from bjaglin/service-loader
enable ServiceLoader discovery across classloader layers
This commit is contained in:
commit
ea608ccd77
|
|
@ -8,7 +8,9 @@
|
|||
package sbt.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import sbt.util.Logger;
|
||||
|
|
@ -64,6 +66,31 @@ final class ReverseLookupClassLoader extends ManagedClassLoader {
|
|||
return url != null ? url : directDescendant.get().findResource(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<URL> findResources(String name) throws IOException {
|
||||
final Enumeration<URL> parentResources = super.findResources(name);
|
||||
|
||||
if (directDescendant.get() == null) {
|
||||
return parentResources;
|
||||
}
|
||||
|
||||
final Enumeration<URL> directDescendantResources = directDescendant.get().findResources(name);
|
||||
return new Enumeration<URL>() {
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return parentResources.hasMoreElements() || directDescendantResources.hasMoreElements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL nextElement() {
|
||||
if (parentResources.hasMoreElements()) {
|
||||
return parentResources.nextElement();
|
||||
}
|
||||
return directDescendantResources.nextElement();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void setup(final File tmpDir) {
|
||||
setTempDir(tmpDir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
val dependency = project.settings(exportJars := true)
|
||||
val descendant = project.dependsOn(dependency).settings(
|
||||
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
|
||||
)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package dependency;
|
||||
|
||||
public class Runnable implements java.lang.Runnable {
|
||||
public void run() {}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
dependency.Runnable
|
||||
|
|
@ -0,0 +1 @@
|
|||
descendant.Runnable
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package descendant
|
||||
|
||||
class Runnable extends java.lang.Runnable {
|
||||
override def run(): Unit = ()
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package test
|
||||
|
||||
import collection.JavaConverters._
|
||||
import org.scalatest._
|
||||
|
||||
class ServiceLoaderTest extends FlatSpec {
|
||||
val expected = Set(classOf[dependency.Runnable], classOf[descendant.Runnable])
|
||||
|
||||
val descendantClassLoader = classOf[descendant.Runnable].getClassLoader
|
||||
val descendantRunnableLoader = java.util.ServiceLoader.load(classOf[java.lang.Runnable], descendantClassLoader)
|
||||
val descendantLoadedClasses = descendantRunnableLoader.iterator().asScala.map(_.getClass).toSet
|
||||
assert(descendantLoadedClasses == expected)
|
||||
|
||||
// this was the actual problem, when classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars
|
||||
val dependencyClassLoader = classOf[dependency.Runnable].getClassLoader
|
||||
val dependencyRunnableLoader = java.util.ServiceLoader.load(classOf[java.lang.Runnable], dependencyClassLoader)
|
||||
val dependencyLoadedClasses = dependencyRunnableLoader.iterator().asScala.map(_.getClass).toSet
|
||||
assert(dependencyLoadedClasses == expected)
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
> set descendant / Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars
|
||||
|
||||
> test
|
||||
|
||||
> set descendant / Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.ScalaLibrary
|
||||
|
||||
> test
|
||||
Loading…
Reference in New Issue