undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,235 @@
/*
* Copyright (c) 2016, 2026, 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.
*
* 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.
*/
/**
* @test
* @library /test/lib
* @modules jdk.compiler
* @build jdk.test.lib.compiler.CompilerUtils
* @run junit/othervm BadProvidersTest
* @summary Basic test of ServiceLoader with bad provider and bad provider
* factories deployed on the module path
*/
import java.lang.classfile.ClassFile;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import java.lang.reflect.AccessFlag;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.Set;
import java.util.stream.Collectors;
import jdk.test.lib.compiler.CompilerUtils;
import static java.lang.classfile.ClassFile.ACC_PUBLIC;
import static java.lang.classfile.ClassFile.ACC_STATIC;
import static java.lang.constant.ConstantDescs.CD_Object;
import static java.lang.constant.ConstantDescs.INIT_NAME;
import static java.lang.constant.ConstantDescs.MTD_void;
import org.junit.jupiter.api.Assertions;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
/**
* Basic test of `provides S with PF` and `provides S with P` where the provider
* factory or provider
*/
public class BadProvidersTest {
private static final String TEST_SRC = System.getProperty("test.src");
private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
private static final Path SRC_DIR = Paths.get(TEST_SRC, "modules");
private static final Path BADFACTORIES_DIR = Paths.get(TEST_SRC, "badfactories");
private static final Path BADPROVIDERS_DIR = Paths.get(TEST_SRC, "badproviders");
private static final String TEST1_MODULE = "test1";
private static final String TEST2_MODULE = "test2";
private static final String TEST_SERVICE = "p.Service";
/**
* Compiles a module, returning a module path with the compiled module.
*/
private Path compileTest(String moduleName) throws Exception {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
Path output = Files.createDirectory(dir.resolve(moduleName));
boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(moduleName), output);
assertTrue(compiled);
return dir;
}
/**
* Resolves a test module and loads it into its own layer. ServiceLoader
* is then used to load all providers.
*/
private List<Provider> loadProviders(Path mp, String moduleName) throws Exception {
ModuleFinder finder = ModuleFinder.of(mp);
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration cf = bootLayer.configuration()
.resolveAndBind(finder, ModuleFinder.of(), Set.of(moduleName));
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);
Class<?> service = layer.findLoader(moduleName).loadClass(TEST_SERVICE);
return ServiceLoader.load(layer, service)
.stream()
.collect(Collectors.toList());
}
@Test
public void sanityTest1() throws Exception {
Path mods = compileTest(TEST1_MODULE);
List<Provider> list = loadProviders(mods, TEST1_MODULE);
assertTrue(list.size() == 1);
// the provider is a singleton, enforced by the provider factory
Object p1 = list.get(0).get();
Object p2 = list.get(0).get();
assertTrue(p1 != null);
assertTrue(p1 == p2);
}
@Test
public void sanityTest2() throws Exception {
Path mods = compileTest(TEST2_MODULE);
List<Provider> list = loadProviders(mods, TEST2_MODULE);
assertTrue(list.size() == 1);
Object p = list.get(0).get();
assertTrue(p != null);
}
@ParameterizedTest
@ValueSource(strings = { "classnotpublic", "methodnotpublic", "badreturntype",
"returnsnull", "throwsexception" })
public void testBadFactory(String testName) throws Exception {
Path mods = compileTest(TEST1_MODULE);
// compile the bad factory
Path source = BADFACTORIES_DIR.resolve(testName);
Path output = Files.createTempDirectory(USER_DIR, "tmp");
boolean compiled = CompilerUtils.compile(source, output);
assertTrue(compiled);
// copy the compiled class into the module
Path classFile = Paths.get("p", "ProviderFactory.class");
Files.copy(output.resolve(classFile),
mods.resolve(TEST1_MODULE).resolve(classFile),
StandardCopyOption.REPLACE_EXISTING);
Assertions.assertThrows(ServiceConfigurationError.class,
// load providers and instantiate each one
() -> loadProviders(mods, TEST1_MODULE).forEach(Provider::get)
);
}
@ParameterizedTest
@ValueSource(strings = { "notpublic", "ctornotpublic", "notasubtype", "throwsexception" })
public void testBadProvider(String testName) throws Exception {
Path mods = compileTest(TEST2_MODULE);
// compile the bad provider
Path source = BADPROVIDERS_DIR.resolve(testName);
Path output = Files.createTempDirectory(USER_DIR, "tmp");
boolean compiled = CompilerUtils.compile(source, output);
assertTrue(compiled);
// copy the compiled class into the module
Path classFile = Paths.get("p", "Provider.class");
Files.copy(output.resolve(classFile),
mods.resolve(TEST2_MODULE).resolve(classFile),
StandardCopyOption.REPLACE_EXISTING);
Assertions.assertThrows(ServiceConfigurationError.class,
// load providers and instantiate each one
() -> loadProviders(mods, TEST2_MODULE).forEach(Provider::get)
);
}
/**
* Test a service provider that defines more than one no-args
* public static "provider" method.
*/
@Test
public void testWithTwoFactoryMethods() throws Exception {
Path mods = compileTest(TEST1_MODULE);
var bytes = ClassFile.of().build(ClassDesc.of("p", "ProviderFactory"), clb -> {
clb.withSuperclass(CD_Object);
clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
var providerFactory$1 = ClassDesc.of("p", "ProviderFactory$1");
// public static p.Service provider()
clb.withMethodBody("provider", MethodTypeDesc.of(ClassDesc.of("p", "Service")),
ACC_PUBLIC | ACC_STATIC, cob -> {
cob.new_(providerFactory$1);
cob.dup();
cob.invokespecial(providerFactory$1, INIT_NAME, MTD_void);
cob.areturn();
});
// public static p.ProviderFactory$1 provider()
clb.withMethodBody("provider", MethodTypeDesc.of(providerFactory$1),
ACC_PUBLIC | ACC_STATIC, cob -> {
cob.new_(providerFactory$1);
cob.dup();
cob.invokespecial(providerFactory$1, INIT_NAME, MTD_void);
cob.areturn();
});
});
// write the class bytes into the compiled module directory
Path classFile = mods.resolve(TEST1_MODULE)
.resolve("p")
.resolve("ProviderFactory.class");
Files.write(classFile, bytes);
Assertions.assertThrows(ServiceConfigurationError.class,
// load providers and instantiate each one
() -> loadProviders(mods, TEST1_MODULE).forEach(Provider::get)
);
}
}

View file

@ -0,0 +1,187 @@
/*
* Copyright (c) 2017, 2026, 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.
*
* 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.
*/
/**
* @test
* @summary Test ServiceLoader caches
* @run junit CachingTest
*/
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.Spliterator;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class CachingTest {
// service type
public static interface S { }
// service provider implementations
public static class S1 implements S { }
public static class S2 implements S { }
private static ClassLoader testClassLoader;
// creates the services configuration file and sets the ClassLoader
@BeforeAll
static void setup() throws Exception {
String classes = System.getProperty("test.classes");
Path dir = Paths.get(classes, "META-INF", "services");
Files.createDirectories(dir);
Path config = dir.resolve(S.class.getName());
Files.write(config, List.of(S1.class.getName(), S2.class.getName()));
testClassLoader = CachingTest.class.getClassLoader();
}
private void checkLists(List<?> list1, List<?> list2) {
assertTrue(list1.size() == 2);
assertTrue(list2.size() == 2);
Iterator<?> iterator1 = list1.iterator();
Iterator<?> iterator2 = list2.iterator();
while (iterator1.hasNext()) {
assertTrue(iterator1.next() == iterator2.next());
}
}
@Test
public void testIterator1() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
List<S> list1 = new ArrayList<>();
List<S> list2 = new ArrayList<>();
// 1-1-2-2
sl.forEach(list1::add);
sl.forEach(list2::add);
checkLists(list1, list2);
}
// interleaved
@Test
public void testIterator2() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
List<S> list1 = new ArrayList<>();
List<S> list2 = new ArrayList<>();
Iterator<S> iterator1 = sl.iterator();
Iterator<S> iterator2 = sl.iterator();
// 1-2-1-2
list1.add(iterator1.next());
list2.add(iterator2.next());
list1.add(iterator1.next());
list2.add(iterator2.next());
checkLists(list1, list2);
}
// interleaved
@Test
public void testIterator3() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
List<S> list1 = new ArrayList<>();
List<S> list2 = new ArrayList<>();
Iterator<S> iterator1 = sl.iterator();
Iterator<S> iterator2 = sl.iterator();
// 1-2-2-1
list1.add(iterator1.next());
list2.add(iterator2.next());
list2.add(iterator2.next());
list1.add(iterator1.next());
checkLists(list1, list2);
}
@Test
public void testStream1() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
// 1-1-2-2
List<Provider<S>> list1 = sl.stream().collect(Collectors.toList());
List<Provider<S>> list2 = sl.stream().collect(Collectors.toList());
checkLists(list1, list2);
}
// interleaved
@Test
public void testStream2() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
List<Provider<S>> list1 = new ArrayList<>();
List<Provider<S>> list2 = new ArrayList<>();
Spliterator<Provider<S>> spliterator1 = sl.stream().spliterator();
Spliterator<Provider<S>> spliterator2 = sl.stream().spliterator();
// 1-2-1-2
spliterator1.tryAdvance(list1::add);
spliterator2.tryAdvance(list2::add);
spliterator1.tryAdvance(list1::add);
spliterator2.tryAdvance(list2::add);
assertFalse(spliterator1.tryAdvance(e -> assertTrue(false)));
assertFalse(spliterator2.tryAdvance(e -> assertTrue(false)));
checkLists(list1, list2);
}
// interleaved
@Test
public void testStream3() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
List<Provider<S>> list1 = new ArrayList<>();
List<Provider<S>> list2 = new ArrayList<>();
Spliterator<Provider<S>> spliterator1 = sl.stream().spliterator();
Spliterator<Provider<S>> spliterator2 = sl.stream().spliterator();
// 1-2-2-1
spliterator1.tryAdvance(list1::add);
spliterator2.tryAdvance(list2::add);
spliterator2.tryAdvance(list2::add);
spliterator1.tryAdvance(list1::add);
assertFalse(spliterator1.tryAdvance(e -> assertTrue(false)));
assertFalse(spliterator2.tryAdvance(e -> assertTrue(false)));
checkLists(list1, list2);
}
}

View file

@ -0,0 +1,496 @@
/*
* Copyright (c) 2016, 2026, 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.
*
* 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.
*/
/**
* @test
* @modules java.scripting
* @library modules /test/lib
* @build bananascript/*
* @build jdk.test.lib.util.JarUtils
* @compile classpath/pearscript/org/pear/PearScriptEngineFactory.java
* classpath/pearscript/org/pear/PearScript.java
* @run junit/othervm ModulesTest
* @summary Basic test for ServiceLoader with a provider deployed as a module.
*/
import java.io.File;
import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.script.ScriptEngineFactory;
import jdk.test.lib.util.JarUtils;
import org.junit.jupiter.api.Assertions;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* Basic test for ServiceLoader. The test make use of two service providers:
* 1. BananaScriptEngine - a ScriptEngineFactory deployed as a module on the
* module path. It implementations a singleton via the public static
* provider method.
* 2. PearScriptEngine - a ScriptEngineFactory deployed on the class path
* with a service configuration file.
*/
public class ModulesTest {
// Copy the services configuration file for "pearscript" into place.
@BeforeAll
public static void setup() throws Exception {
Path src = Paths.get(System.getProperty("test.src"));
Path classes = Paths.get(System.getProperty("test.classes"));
String st = ScriptEngineFactory.class.getName();
Path config = Paths.get("META-INF", "services", st);
Path source = src.resolve("classpath").resolve("pearscript").resolve(config);
Path target = classes.resolve(config);
Files.createDirectories(target.getParent());
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
}
/**
* Basic test of iterator() to ensure that providers located as modules
* and on the class path are found.
*/
@Test
public void testIterator() {
ServiceLoader<ScriptEngineFactory> loader
= ServiceLoader.load(ScriptEngineFactory.class);
Set<String> names = collectAll(loader)
.stream()
.map(ScriptEngineFactory::getEngineName)
.collect(Collectors.toSet());
assertTrue(names.contains("BananaScriptEngine"));
assertTrue(names.contains("PearScriptEngine"));
}
/**
* Basic test of iterator() to test iteration order. Providers deployed
* as named modules should be found before providers deployed on the class
* path.
*/
@Test
public void testIteratorOrder() {
ServiceLoader<ScriptEngineFactory> loader
= ServiceLoader.load(ScriptEngineFactory.class);
boolean foundUnnamed = false;
for (ScriptEngineFactory factory : collectAll(loader)) {
if (factory.getClass().getModule().isNamed()) {
if (foundUnnamed) {
assertTrue(false, "Named module element after unnamed");
}
} else {
foundUnnamed = true;
}
}
}
/**
* Basic test of Provider::type
*/
@Test
public void testProviderType() {
Set<String> types = ServiceLoader.load(ScriptEngineFactory.class)
.stream()
.map(Provider::type)
.map(Class::getName)
.collect(Collectors.toSet());
assertTrue(types.contains("org.banana.BananaScriptEngineFactory"));
assertTrue(types.contains("org.pear.PearScriptEngineFactory"));
}
/**
* Basic test of Provider::get
*/
@Test
public void testProviderGet() {
Set<String> names = ServiceLoader.load(ScriptEngineFactory.class)
.stream()
.map(Provider::get)
.map(ScriptEngineFactory::getEngineName)
.collect(Collectors.toSet());
assertTrue(names.contains("BananaScriptEngine"));
assertTrue(names.contains("PearScriptEngine"));
}
/**
* Basic test of the public static provider method. BananaScriptEngine
* defines a provider method that returns the same instance.
*/
@Test
public void testSingleton() {
Optional<Provider<ScriptEngineFactory>> oprovider
= ServiceLoader.load(ScriptEngineFactory.class)
.stream()
.filter(p -> p.type().getName().equals("org.banana.BananaScriptEngineFactory"))
.findFirst();
assertTrue(oprovider.isPresent());
Provider<ScriptEngineFactory> provider = oprovider.get();
// invoke Provider::get twice
ScriptEngineFactory factory1 = provider.get();
ScriptEngineFactory factory2 = provider.get();
assertTrue(factory1 == factory2);
}
/**
* Basic test of stream() to ensure that elements for providers in named
* modules come before elements for providers in unnamed modules.
*/
@Test
public void testStreamOrder() {
List<Class<?>> types = ServiceLoader.load(ScriptEngineFactory.class)
.stream()
.map(Provider::type)
.collect(Collectors.toList());
boolean foundUnnamed = false;
for (Class<?> factoryClass : types) {
if (factoryClass.getModule().isNamed()) {
if (foundUnnamed) {
assertTrue(false, "Named module element after unnamed");
}
} else {
foundUnnamed = true;
}
}
}
/**
* Basic test of ServiceLoader.findFirst()
*/
@Test
public void testFindFirst() {
Optional<ScriptEngineFactory> ofactory
= ServiceLoader.load(ScriptEngineFactory.class).findFirst();
assertTrue(ofactory.isPresent());
ScriptEngineFactory factory = ofactory.get();
assertTrue(factory.getClass().getModule().isNamed());
class S { }
assertFalse(ServiceLoader.load(S.class).findFirst().isPresent());
}
/**
* Basic test ServiceLoader.load specifying the platform class loader.
* The providers on the module path and class path should not be located.
*/
@Test
public void testWithPlatformClassLoader() {
ClassLoader pcl = ClassLoader.getPlatformClassLoader();
// iterator
ServiceLoader<ScriptEngineFactory> loader
= ServiceLoader.load(ScriptEngineFactory.class, pcl);
Set<String> names = collectAll(loader)
.stream()
.map(ScriptEngineFactory::getEngineName)
.collect(Collectors.toSet());
assertFalse(names.contains("BananaScriptEngine"));
assertFalse(names.contains("PearScriptEngine"));
// stream
names = ServiceLoader.load(ScriptEngineFactory.class, pcl)
.stream()
.map(Provider::get)
.map(ScriptEngineFactory::getEngineName)
.collect(Collectors.toSet());
assertFalse(names.contains("BananaScriptEngine"));
assertFalse(names.contains("PearScriptEngine"));
}
/**
* Basic test of ServiceLoader.load where the service provider module is an
* automatic module.
*/
@Test
public void testWithAutomaticModule() throws Exception {
Path here = Paths.get("");
Path jar = Files.createTempDirectory(here, "lib").resolve("pearscript.jar");
Path classes = Paths.get(System.getProperty("test.classes"));
JarUtils.createJarFile(jar, classes, "META-INF", "org");
ModuleFinder finder = ModuleFinder.of(jar);
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration parent = bootLayer.configuration();
Configuration cf = parent.resolveAndBind(finder, ModuleFinder.of(), Set.of());
assertTrue(cf.modules().size() == 1);
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
assertTrue(layer.modules().size() == 1);
ClassLoader loader = layer.findLoader("pearscript");
ScriptEngineFactory factory;
// load using the class loader as context
factory = ServiceLoader.load(ScriptEngineFactory.class, loader)
.findFirst()
.orElse(null);
assertNotNull(factory);
assertTrue(factory.getClass().getClassLoader() == loader);
// load using the layer as context
factory = ServiceLoader.load(layer, ScriptEngineFactory.class)
.findFirst()
.orElse(null);
assertNotNull(factory);
assertTrue(factory.getClass().getClassLoader() == loader);
}
/**
* Basic test of ServiceLoader.load, using the class loader for
* a module in a custom layer as the context.
*/
@Test
public void testWithCustomLayer1() {
ModuleLayer layer = createCustomLayer("bananascript");
ClassLoader loader = layer.findLoader("bananascript");
List<ScriptEngineFactory> providers
= collectAll(ServiceLoader.load(ScriptEngineFactory.class, loader));
// should have at least 2 x bananascript + pearscript
assertTrue(providers.size() >= 3);
// first element should be the provider in the custom layer
ScriptEngineFactory factory = providers.get(0);
assertTrue(factory.getClass().getClassLoader() == loader);
assertTrue(factory.getClass().getModule().getLayer() == layer);
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
// remainder should be the boot layer
providers.remove(0);
Set<String> names = providers.stream()
.map(ScriptEngineFactory::getEngineName)
.collect(Collectors.toSet());
assertTrue(names.contains("BananaScriptEngine"));
assertTrue(names.contains("PearScriptEngine"));
}
/**
* Basic test of ServiceLoader.load using a custom Layer as the context.
*/
@Test
public void testWithCustomLayer2() {
ModuleLayer layer = createCustomLayer("bananascript");
List<ScriptEngineFactory> factories
= collectAll(ServiceLoader.load(layer, ScriptEngineFactory.class));
// should have at least 2 x bananascript
assertTrue(factories.size() >= 2);
// first element should be the provider in the custom layer
ScriptEngineFactory factory = factories.get(0);
assertTrue(factory.getClass().getModule().getLayer() == layer);
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
// remainder should be the boot layer
factories.remove(0);
Set<String> names = factories.stream()
.map(ScriptEngineFactory::getEngineName)
.collect(Collectors.toSet());
assertTrue(names.contains("BananaScriptEngine"));
assertFalse(names.contains("PearScriptEngine"));
}
/**
* Basic test of ServiceLoader.load with a tree of layers.
*
* Test scenario:
* - boot layer contains "bananascript", maybe other script engines
* - layer1, with boot layer as parent, contains "bananascript"
* - layer2, with boot layer as parent, contains "bananascript"
* - layer3, with layer1 ad layer as parents, contains "bananascript"
*
* ServiceLoader should locate all 4 script engine factories in DFS order.
*/
@Test
public void testWithCustomLayer3() {
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration cf0 = bootLayer.configuration();
// boot layer should contain "bananascript"
List<ScriptEngineFactory> factories
= collectAll(ServiceLoader.load(bootLayer, ScriptEngineFactory.class));
int countInBootLayer = factories.size();
assertTrue(countInBootLayer >= 1);
assertTrue(factories.stream()
.map(p -> p.getEngineName())
.filter("BananaScriptEngine"::equals)
.findAny()
.isPresent());
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleFinder finder = ModuleFinder.of(testModulePath());
// layer1
Configuration cf1 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
ModuleLayer layer1 = bootLayer.defineModulesWithOneLoader(cf1, scl);
assertTrue(layer1.modules().size() == 1);
// layer2
Configuration cf2 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
ModuleLayer layer2 = bootLayer.defineModulesWithOneLoader(cf2, scl);
assertTrue(layer2.modules().size() == 1);
// layer3 with layer1 and layer2 as parents
Configuration cf3 = Configuration.resolveAndBind(finder,
List.of(cf1, cf2),
ModuleFinder.of(),
Set.of());
ModuleLayer layer3
= ModuleLayer.defineModulesWithOneLoader(cf3, List.of(layer1, layer2), scl).layer();
assertTrue(layer3.modules().size() == 1);
// class loaders
ClassLoader loader1 = layer1.findLoader("bananascript");
ClassLoader loader2 = layer2.findLoader("bananascript");
ClassLoader loader3 = layer3.findLoader("bananascript");
assertTrue(loader1 != loader2);
assertTrue(loader1 != loader3);
assertTrue(loader2 != loader3);
// load all factories with layer3 as the context
factories = collectAll(ServiceLoader.load(layer3, ScriptEngineFactory.class));
int count = factories.size();
assertTrue(count == countInBootLayer + 3);
// the ordering should be layer3, layer1, boot layer, layer2
ScriptEngineFactory factory = factories.get(0);
assertTrue(factory.getClass().getModule().getLayer() == layer3);
assertTrue(factory.getClass().getClassLoader() == loader3);
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
factory = factories.get(1);
assertTrue(factory.getClass().getModule().getLayer() == layer1);
assertTrue(factory.getClass().getClassLoader() == loader1);
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
// boot layer "bananascript" and maybe other factories
int last = count -1;
boolean found = false;
for (int i=2; i<last; i++) {
factory = factories.get(i);
assertTrue(factory.getClass().getModule().getLayer() == bootLayer);
if (factory.getEngineName().equals("BananaScriptEngine")) {
assertFalse(found);
found = true;
}
}
assertTrue(found);
factory = factories.get(last);
assertTrue(factory.getClass().getModule().getLayer() == layer2);
assertTrue(factory.getClass().getClassLoader() == loader2);
assertTrue(factory.getEngineName().equals("BananaScriptEngine"));
}
// -- nulls --
@Test
public void testLoadNull1() {
Assertions.assertThrows(NullPointerException.class,
() -> ServiceLoader.load(null));
}
@Test
public void testLoadNull2() {
Assertions.assertThrows(NullPointerException.class,
() -> ServiceLoader.load((Class<?>) null, ClassLoader.getSystemClassLoader()));
}
@Test
public void testLoadNull3() {
class S { }
Assertions.assertThrows(NullPointerException.class, () -> {
ServiceLoader.load((ModuleLayer) null, S.class);
});
}
@Test
public void testLoadNull4() {
Assertions.assertThrows(NullPointerException.class,
() -> ServiceLoader.load(ModuleLayer.empty(), null));
}
@Test
public void testLoadNull5() {
Assertions.assertThrows(NullPointerException.class,
() -> ServiceLoader.loadInstalled(null));
}
/**
* Create a custom layer by resolving the given module names. The modules
* are located on the test module path ({@code ${test.module.path}}).
*/
private ModuleLayer createCustomLayer(String... modules) {
ModuleFinder finder = ModuleFinder.of(testModulePath());
Set<String> roots = new HashSet<>();
Collections.addAll(roots, modules);
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration parent = bootLayer.configuration();
Configuration cf = parent.resolve(finder, ModuleFinder.of(), roots);
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
assertTrue(layer.modules().size() == 1);
return layer;
}
private Path[] testModulePath() {
String mp = System.getProperty("test.module.path");
return Stream.of(mp.split(File.pathSeparator))
.map(Paths::get)
.toArray(Path[]::new);
}
private <E> List<E> collectAll(ServiceLoader<E> loader) {
List<E> list = new ArrayList<>();
Iterator<E> iterator = loader.iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2012, 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.
*
* 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.
*/
/**
* @test
* @bug 7197642
* @summary test ServiceLoader.load methods for NullPointerException.
*/
import java.util.ServiceLoader;
import java.util.Arrays;
public final class NPE {
abstract static class Test {
String name;
Test(String name) { this.name = name; }
abstract void run();
}
static Test load = new Test("ServiceLoader.load(null)") {
void run() { ServiceLoader.load(null); }
};
static Test loadWithClassLoader = new Test("ServiceLoader.load(null, loader)") {
void run() { ServiceLoader.load(null, NPE.class.getClassLoader()); }
};
static Test loadInstalled = new Test("ServiceLoader.loadInstalled(null)") {
void run() { ServiceLoader.loadInstalled(null); }
};
public static void main(String[] args) throws Exception {
for (Test t : Arrays.asList(load, loadWithClassLoader, loadInstalled)) {
NullPointerException caught = null;
try {
t.run();
} catch (NullPointerException e) {
caught = e;
}
if (caught == null) {
throw new RuntimeException("NullPointerException expected for method invocation of " + t.name);
}
}
}
}

View file

@ -0,0 +1,153 @@
/*
* Copyright (c) 2017, 2026, 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.
*
* 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.
*/
/**
* @test
* @library /test/lib
* @modules jdk.compiler
* @build jdk.test.lib.compiler.CompilerUtils
* @run junit NoInterferenceTest
* @summary Basic test of ServiceLoader that ensures there is no interference
* when there are two service interfaces of the same name in a layer
* or overridden in a child layer.
*/
import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import jdk.test.lib.compiler.CompilerUtils;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class NoInterferenceTest {
private static final String TEST_SRC = System.getProperty("test.src");
private static final Path SRC_DIR = Paths.get(TEST_SRC, "modules");
private static final Path MODS_DIR = Paths.get("mods");
private static final List<String> MODULES = Arrays.asList("s1", "p1", "s2", "p2");
@BeforeAll
static void compile() throws Exception {
Files.createDirectory(MODS_DIR);
for (String name : MODULES) {
Path src = SRC_DIR.resolve(name);
Path output = Files.createDirectory(MODS_DIR.resolve(name));
assertTrue(CompilerUtils.compile(src, output, "-p", MODS_DIR.toString()));
}
}
@Test
public void test() throws Exception {
ModuleFinder empty = ModuleFinder.of();
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration cf0 = bootLayer.configuration();
Configuration cf1 = cf0.resolveAndBind(finder, empty, Set.of("s1", "s2"));
Configuration cf2 = cf1.resolveAndBind(finder, empty, Set.of("s1", "s2"));
// cf1 contains s1, p1, s2, p2
assertTrue(cf1.modules().size() == 4);
// cf1 contains s1, p1, s2, p2
assertTrue(cf2.modules().size() == 4);
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer1 = bootLayer.defineModulesWithManyLoaders(cf1, scl);
testLayer(layer1);
ModuleLayer layer2 = layer1.defineModulesWithManyLoaders(cf2, scl);
testLayer(layer2);
}
/**
* Tests that the layer contains s1, p1, s2, and p2.
*
* Tests loading instances of s1/p.S and s2/p.S.
*/
private void testLayer(ModuleLayer layer) throws Exception {
assertTrue(layer.modules().size() == 4);
Module s1 = layer.findModule("s1").get();
Module p1 = layer.findModule("p1").get();
Module s2 = layer.findModule("s2").get();
Module p2 = layer.findModule("p2").get();
// p1 reads s1
assertTrue(p1.canRead(s1));
assertFalse(p1.canRead(s2));
// p2 reads s2
assertTrue(p2.canRead(s2));
assertFalse(p2.canRead(s1));
// iterate over implementations of s1/p.S
{
ClassLoader loader = layer.findLoader("s1");
Class<?> service = loader.loadClass("p.S");
List<?> list = collectAll(ServiceLoader.load(service, loader));
assertTrue(list.size() == 1);
assertTrue(list.get(0).getClass().getModule() == p1);
list = collectAll(ServiceLoader.load(layer, service));
assertTrue(list.size() == 1);
assertTrue(list.get(0).getClass().getModule() == p1);
}
// iterate over implementations of s2/p.S
{
ClassLoader loader = layer.findLoader("s2");
Class<?> service = loader.loadClass("p.S");
List<?> list = collectAll(ServiceLoader.load(service, loader));
assertTrue(list.size() == 1);
assertTrue(list.get(0).getClass().getModule() == p2);
list = collectAll(ServiceLoader.load(layer, service));
assertTrue(list.size() == 1);
assertTrue(list.get(0).getClass().getModule() == p2);
}
}
private <E> List<E> collectAll(ServiceLoader<E> loader) {
List<E> list = new ArrayList<>();
Iterator<E> iterator = loader.iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
}

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2017, 2026, 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.
*
* 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.
*/
/*
* @test
* @modules java.scripting
* @library modules classpath/pearscript
* @build ReloadTest org.pear.PearScript org.pear.PearScriptEngineFactory bananascript/*
* @run junit/othervm ReloadTest
* @summary Basic test of ServiceLoader.reload
*/
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.Spliterator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.ServiceLoader.*;
import javax.script.ScriptEngineFactory;
import org.junit.jupiter.api.Assertions;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class ReloadTest {
@Test
public void testReload() {
ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
List<String> names1 = sl.stream()
.map(Provider::get)
.map(ScriptEngineFactory::getEngineName)
.collect(Collectors.toList());
assertFalse(names1.isEmpty());
sl.reload();
List<String> names2 = sl.stream()
.map(Provider::get)
.map(ScriptEngineFactory::getEngineName)
.collect(Collectors.toList());
assertEquals(names2, names1);
}
@Test
public void testIteratorHasNext() {
ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
Iterator<ScriptEngineFactory> iterator = sl.iterator();
sl.reload();
Assertions.assertThrows(ConcurrentModificationException.class, iterator::hasNext);
}
@Test
public void testIteratorNext() {
ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
Iterator<ScriptEngineFactory> iterator = sl.iterator();
assertTrue(iterator.hasNext());
sl.reload();
Assertions.assertThrows(ConcurrentModificationException.class, iterator::next);
}
@Test
public void testStreamFindAny() {
ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
Stream<Provider<ScriptEngineFactory>> stream = sl.stream();
sl.reload();
Assertions.assertThrows(ConcurrentModificationException.class, stream::findAny);
}
@Test
public void testSpliteratorTryAdvance() {
ServiceLoader<ScriptEngineFactory> sl = load(ScriptEngineFactory.class);
Stream<Provider<ScriptEngineFactory>> stream = sl.stream();
Spliterator<Provider<ScriptEngineFactory>> spliterator = stream.spliterator();
sl.reload();
Assertions.assertThrows(ConcurrentModificationException.class,
() -> spliterator.tryAdvance(System.out::println));
}
}

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2015, 2026, 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.
*
* 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.
*/
/**
* @test
* @summary Test ServiceLoader with two iterators, interleaving their use
* to test that they don't interfere with each other
* @run junit TwoIterators
*/
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Iterator;
import java.util.ServiceLoader;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class TwoIterators {
// service type
public static interface S { }
// service provider implementations
public static class S1 implements S { }
public static class S2 implements S { }
private static ClassLoader testClassLoader;
// creates the services configuration file and sets the ClassLoader
@BeforeAll
static void setup() throws Exception {
String classes = System.getProperty("test.classes");
Path dir = Paths.get(classes, "META-INF", "services");
Files.createDirectories(dir);
Path config = dir.resolve(S.class.getName());
Files.write(config, Arrays.asList(S1.class.getName(), S2.class.getName()));
testClassLoader = TwoIterators.class.getClassLoader();
}
@Test
public void testSequentialUse1() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
Iterator<S> iterator1 = sl.iterator();
iterator1.next();
iterator1.next();
assertFalse(iterator1.hasNext());
Iterator<S> iterator2 = sl.iterator();
iterator2.next();
iterator2.next();
assertFalse(iterator2.hasNext());
}
@Test
public void testSequentialUse2() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
Iterator<S> iterator1 = sl.iterator();
Iterator<S> iterator2 = sl.iterator();
iterator1.next();
iterator1.next();
assertFalse(iterator1.hasNext());
iterator2.next();
iterator2.next();
assertFalse(iterator2.hasNext());
}
@Test
public void testInterleaved1() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
Iterator<S> iterator1 = sl.iterator();
Iterator<S> iterator2 = sl.iterator();
iterator1.next();
iterator2.next();
iterator1.next();
iterator2.next();
assertFalse(iterator1.hasNext());
assertFalse(iterator2.hasNext());
}
@Test
public void testInterleaved2() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
Iterator<S> iterator1 = sl.iterator();
iterator1.next();
Iterator<S> iterator2 = sl.iterator();
assertTrue(iterator1.hasNext());
assertTrue(iterator2.hasNext());
iterator1.next();
iterator2.next();
iterator2.next();
assertFalse(iterator1.hasNext());
assertFalse(iterator2.hasNext());
}
@Test
public void testInterleaved3() {
ServiceLoader<S> sl = ServiceLoader.load(S.class, testClassLoader);
Iterator<S> iterator1 = sl.iterator();
iterator1.next();
Iterator<S> iterator2 = sl.iterator();
assertTrue(iterator2.hasNext());
assertTrue(iterator1.hasNext());
iterator2.next();
iterator2.next();
iterator1.next();
assertFalse(iterator1.hasNext());
assertFalse(iterator2.hasNext());
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* A provider factory with a provider() method with a return type that is not
* p.Service
*/
public class ProviderFactory {
ProviderFactory() { }
public static Object provider() {
throw new RuntimeException("Should not be called");
}
}

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* Not a provider factory because the class is not public.
*/
class ProviderFactory {
ProviderFactory() { }
public static Service provider() {
throw new RuntimeException("Should not be called");
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
public interface Service { }

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* Not a provider factory because the static provider() method is not public.
*/
public class ProviderFactory {
ProviderFactory() { }
static Service provider() {
throw new RuntimeException("Should not be called");
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
public interface Service { }

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* A provider factory that defines a public static provider method that returns
* null.
*/
public class ProviderFactory {
ProviderFactory() { }
public static Service provider() {
return null;
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
public interface Service { }

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* A provider factory that throws an exception.
*/
public class ProviderFactory {
ProviderFactory() { }
public static Service provider() {
throw new RuntimeException();
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
public interface Service { }

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* A provider class with a non-public constructor
*/
public class Provider implements Service {
Provider() { }
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
public interface Service { }

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* A provider class that is not a subtype of Service.
*/
public class Provider {
Provider() { }
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* Provider class not public.
*/
class Provider implements Service {
public Provider() { }
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
public interface Service { }

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* A provider class with a constructor throws an exception.
*/
public class Provider {
public Provider() {
throw new RuntimeException();
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
public interface Service { }

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2016, 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.
*
* 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.
*/
public class BarProvider { }

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2005, 2012, 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.
*
* 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.
*/
//
import java.io.*;
import java.util.*;
public class Basic {
private static PrintStream out = System.err;
private static <T> Set<T> setOf(Iterable<T> it) {
Set<T> s = new HashSet<T>();
for (T t : it)
s.add(t);
return s;
}
private static <T> void checkEquals(Set<T> s1, Set<T> s2, boolean eq) {
if (s1.equals(s2) != eq)
throw new RuntimeException(String.format("%b %s : %s",
eq, s1, s2));
}
abstract static class TestLoader {
String name;
TestLoader(String name) { this.name = name; }
abstract ServiceLoader<FooService> load();
}
static TestLoader tcclLoader = new TestLoader("Thread context class loader") {
ServiceLoader<FooService> load() {
return ServiceLoader.load(FooService.class);
}
};
static TestLoader systemClLoader = new TestLoader("System class loader") {
ServiceLoader<FooService> load() {
return ServiceLoader.load(FooService.class, ClassLoader.getSystemClassLoader());
}
};
static TestLoader nullClLoader = new TestLoader("null (defer to system class loader)") {
ServiceLoader<FooService> load() {
return ServiceLoader.load(FooService.class, null);
}
};
public static void main(String[] args) {
for (TestLoader tl : Arrays.asList(tcclLoader, systemClLoader, nullClLoader)) {
test(tl);
}
}
static void test(TestLoader tl) {
ServiceLoader<FooService> sl = tl.load();
out.format("%s: %s%n", tl.name, sl);
// Providers are cached
Set<FooService> ps = setOf(sl);
checkEquals(ps, setOf(sl), true);
// The cache can be flushed and reloaded
sl.reload();
checkEquals(ps, setOf(sl), false);
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2005, 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.
*
* 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.
*/
public class FooProvider1 extends FooService { }

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2005, 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.
*
* 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.
*/
public class FooProvider2 extends FooService { }

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2005, 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.
*
* 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.
*/
public class FooProvider3 extends FooService { }

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2005, 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.
*
* 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.
*/
public abstract class FooService { }

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2005, 2006, 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.
*
* 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.
*/
//
import java.io.*;
import java.util.*;
public class Load {
private static PrintStream out = System.err;
public static void main(String[] args) throws Exception {
boolean installedOnly = false;
List<String> expected = new ArrayList<String>(Arrays.asList(args));
if (!expected.isEmpty() && expected.get(0).equals("-i")) {
expected.remove(0);
installedOnly = true;
}
if (expected.isEmpty())
throw new Exception("usage: Load [-i] ( fail | provider-class-name )*");
ServiceLoader<FooService> sl = (installedOnly
? ServiceLoader.loadInstalled(FooService.class)
: ServiceLoader.load(FooService.class));
out.format("%s%n", sl);
Iterator<FooService> sli = sl.iterator();
Iterator<String> ei = expected.iterator();
for (;; ei.remove()) {
FooService fp = null;
try {
if (!sli.hasNext())
break;
fp = sli.next();
} catch (ServiceConfigurationError x) {
if (ei.next().equals("fail")) {
out.format("Failed as expected: %s%n", x);
continue;
}
throw x;
}
String ec = ei.next();
if (!fp.getClass().getName().equals(ec))
throw new
Exception(String.format("Wrong provider %s; expected %s",
fp.getClass().getName(), ec));
out.format("Provider found: %s%n", fp.getClass().getName());
}
if (ei.hasNext())
throw new Exception("Missing providers: " + expected);
}
}

View file

@ -0,0 +1,156 @@
/*
* Copyright (c) 2018, 2026, 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.
*
* 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.
*/
/*
* @test
* @bug 4640520 6354623 7198496
* @summary Unit test for java.util.ServiceLoader
* @library /test/lib
* @build jdk.test.lib.process.*
* jdk.test.lib.util.JarUtils
* Basic Load FooService FooProvider1 FooProvider2 FooProvider3 BarProvider
* @run junit ServiceLoaderBasicTest
*/
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import jdk.test.lib.JDKToolFinder;
import jdk.test.lib.Utils;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.util.JarUtils;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.util.Arrays.asList;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
public class ServiceLoaderBasicTest {
private static final String METAINFO = "META-INF/services/FooService";
private static final Path XTEST_CONFIG = Path.of("x.test").resolve(METAINFO);
private static final Path XMETA_CONFIG = Path.of("x.meta").resolve(METAINFO);
private static final Path P2JAR = Path.of("p2.jar");
private static final Path P2DUPJAR = Path.of("p2dup.jar");
private static final Path P3JAR = Path.of("x.ext", "p3.jar");
private static final String XTEST = File.pathSeparator + "x.test";
private static final String XMETA = File.pathSeparator + "x.meta";
private static final String P2 = File.pathSeparator + P2JAR.toString();
private static final String P2DUP = File.pathSeparator + P2DUPJAR.toString();
private static final String P3 = File.pathSeparator + P3JAR.toString();
private static final String XTEST_CP = Utils.TEST_CLASS_PATH + XTEST;
private static final String P2_CP = Utils.TEST_CLASS_PATH + P2;
private static final String P2DUP_CP = P2_CP + P2DUP;
private static final String P3P2_CP = Utils.TEST_CLASS_PATH + P3 + P2;
private static final String XTESTP2_CP = XTEST_CP + P2;
private static final String P3XTEST_CP = Utils.TEST_CLASS_PATH + P3 + XTEST;
private static final String P3XTESTP2_CP = P3XTEST_CP + P2;
private static final String XMETA_CP = Utils.TEST_CLASS_PATH + XMETA;
private static final String XMETAXTEST_CP = XMETA_CP + XTEST;
private static final String XTESTXMETA_CP = XTEST_CP + XMETA;
private static final String XTESTXMETAP2_CP = XTESTXMETA_CP + P2;
@BeforeAll
public static void initialize() throws Exception {
createProviderConfig(XTEST_CONFIG, "FooProvider1");
createProviderConfig(XMETA_CONFIG, "FooProvider42");
createJar(P2JAR, "FooProvider2", List.of("FooProvider2"));
createJar(P3JAR, "FooProvider3", List.of("FooProvider3", "FooService"));
Files.copy(P2JAR, P2DUPJAR, REPLACE_EXISTING);
}
private static Object[][] testCases() {
return new Object[][]{
// CLI options, Test, Runtime arguments
// Success cases
{List.of("-cp", XTESTP2_CP, "Basic")},
{List.of("-cp", XTEST_CP, "Load", "FooProvider1")},
{List.of("-cp", P2_CP, "Load", "FooProvider2")},
{List.of("-cp", P2DUP_CP, "Load", "FooProvider2")},
{List.of("-cp", P3P2_CP, "Load", "FooProvider3", "FooProvider2")},
{List.of("-cp", XTESTP2_CP, "Load", "FooProvider1", "FooProvider2")},
{List.of("-cp", P3XTEST_CP, "Load", "FooProvider3", "FooProvider1")},
{List.of("-cp", P3XTESTP2_CP, "Load", "FooProvider3",
"FooProvider1",
"FooProvider2")},
// Failures followed by successes
{List.of("-cp", XTESTXMETA_CP, "Load", "FooProvider1", "fail")},
{List.of("-cp", XMETAXTEST_CP, "Load", "fail", "FooProvider1")},
{List.of("-cp", XTESTXMETAP2_CP, "Load", "FooProvider1", "fail", "FooProvider2")}
};
}
@ParameterizedTest
@MethodSource("testCases")
public void testProvider(List<String> args) throws Throwable {
runJava(args);
}
@ParameterizedTest // negative test cases
@ValueSource(strings = { "blah blah", "9234", "X!", "BarProvider", "FooProvider42" })
public void testBadProvider(String providerName) throws Throwable {
Files.write(XMETA_CONFIG, providerName.getBytes());
runJava(List.of("-cp", XMETA_CP, "Load", "fail"));
}
private void runJava(List<String> opts) throws Throwable {
List<String> cmds = new ArrayList<>();
cmds.add(JDKToolFinder.getJDKTool("java"));
cmds.addAll(asList(Utils.getTestJavaOpts()));
cmds.addAll(opts);
ProcessTools.executeCommand(cmds.stream()
.filter(t -> !t.isEmpty())
.toArray(String[]::new))
.shouldHaveExitValue(0);
}
private static void createProviderConfig(Path config, String providerName) throws Exception {
Files.createDirectories(config.getParent());
Files.write(config, providerName.getBytes(), CREATE);
}
private static void createJar(Path jar, String provider, List<String> files) throws Exception {
Path xdir = Path.of(provider);
createProviderConfig(xdir.resolve(METAINFO), provider);
for (String f : files) {
Path source = Path.of(Utils.TEST_CLASSES, f + ".class");
Path target = xdir.resolve(source.getFileName());
Files.copy(source, target, REPLACE_EXISTING);
}
JarUtils.createJarFile(jar, xdir);
}
}

View file

@ -0,0 +1 @@
org.pear.PearScriptEngineFactory

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2014, 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.
*
* 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 org.pear;
import java.io.Reader;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
public class PearScript implements ScriptEngine {
@Override
public Object eval(String script, ScriptContext context) {
throw new RuntimeException();
}
@Override
public Object eval(Reader reader , ScriptContext context) {
throw new RuntimeException();
}
@Override
public Object eval(String script) {
throw new RuntimeException();
}
@Override
public Object eval(Reader reader) {
throw new RuntimeException();
}
@Override
public Object eval(String script, Bindings n) {
throw new RuntimeException();
}
@Override
public Object eval(Reader reader , Bindings n) {
throw new RuntimeException();
}
@Override
public void put(String key, Object value) {
throw new RuntimeException();
}
@Override
public Object get(String key) {
throw new RuntimeException();
}
@Override
public Bindings getBindings(int scope) {
throw new RuntimeException();
}
@Override
public void setBindings(Bindings bindings, int scope) {
throw new RuntimeException();
}
@Override
public Bindings createBindings() {
throw new RuntimeException();
}
@Override
public ScriptContext getContext() {
throw new RuntimeException();
}
@Override
public void setContext(ScriptContext context) {
throw new RuntimeException();
}
@Override
public ScriptEngineFactory getFactory() {
throw new RuntimeException();
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2014, 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.
*
* 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 org.pear;
import java.util.Arrays;
import java.util.List;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
public class PearScriptEngineFactory implements ScriptEngineFactory {
public PearScriptEngineFactory() { }
public static PearScriptEngineFactory provider() {
throw new RuntimeException("Should not be called");
}
@Override
public String getEngineName() {
return "PearScriptEngine";
}
@Override
public String getEngineVersion() {
return "1.0";
}
@Override
public List<String> getExtensions() {
return Arrays.asList("pear");
}
@Override
public List<String> getMimeTypes() {
return Arrays.asList("application/x-pearscript");
}
@Override
public List<String> getNames() {
return Arrays.asList("PearScript");
}
@Override
public String getLanguageName() {
return "PearScript";
}
@Override
public String getLanguageVersion() {
return "1.0";
}
@Override
public Object getParameter(String key) {
return null;
}
@Override
public String getMethodCallSyntax(String obj, String m, String... args) {
throw new RuntimeException();
}
@Override
public String getOutputStatement(String toDisplay) {
throw new RuntimeException();
}
@Override
public String getProgram(String... statements) {
throw new RuntimeException();
}
@Override
public ScriptEngine getScriptEngine() {
return new PearScript();
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
/**
* @test
* @build test/*
* @run main/othervm test/p.Main
* @summary Basic test of ServiceLoader to ensure that static provider methods
* are explicitly declared and not inherited from super classes
*/

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
import p.Main.*;
module test {
exports p;
uses S;
provides S with P1, P2, P3;
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2017, 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.
*
* 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 p;
import java.util.List;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
/**
* Basic test of ServiceLoader with a provider interface and 3 provider
* implementations.
*
* The provider interface (test.Main.Provider) defines a static factory method
* name "provider" that locates a provider implementation. At least one of the
* provider implementations does not define a static "provider" method.
*/
public class Main {
public static void main(String[] args) {
List<S> providers = ServiceLoader.load(S.class).stream()
.map(ServiceLoader.Provider::get)
.collect(Collectors.toList());
if (providers.size() != 3)
throw new RuntimeException("Expected 3 providers");
}
/**
* Service type
*/
public static interface S {
}
/**
* Base implementation, its static provider method should never be called
*/
public static class BaseProvider implements S {
protected BaseProvider() { }
public static S provider() {
throw new RuntimeException("Should not get here");
}
}
/**
* Provider implementation with public constructor.
*/
public static class P1 extends BaseProvider {
public P1() { }
}
/**
* Provider implementation with static factory method.
*/
public static class P2 extends BaseProvider {
private P2() { }
public static P2 provider() {
return new P2();
}
}
/**
* Provider implementation with static factory method and public
* constructor.
*/
public static class P3 extends BaseProvider {
public P3() {
throw new RuntimeException("Should not get here");
}
private P3(int x) { }
public static S provider() {
return new P3(0);
}
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2016, 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.
*
* 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.
*/
module bananascript {
requires java.scripting;
provides javax.script.ScriptEngineFactory
with org.banana.BananaScriptEngineFactory;
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2014, 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.
*
* 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 org.banana;
import java.io.Reader;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
public class BananaScript implements ScriptEngine {
@Override
public Object eval(String script, ScriptContext context) {
throw new RuntimeException();
}
@Override
public Object eval(Reader reader , ScriptContext context) {
throw new RuntimeException();
}
@Override
public Object eval(String script) {
throw new RuntimeException();
}
@Override
public Object eval(Reader reader) {
throw new RuntimeException();
}
@Override
public Object eval(String script, Bindings n) {
throw new RuntimeException();
}
@Override
public Object eval(Reader reader , Bindings n) {
throw new RuntimeException();
}
@Override
public void put(String key, Object value) {
throw new RuntimeException();
}
@Override
public Object get(String key) {
throw new RuntimeException();
}
@Override
public Bindings getBindings(int scope) {
throw new RuntimeException();
}
@Override
public void setBindings(Bindings bindings, int scope) {
throw new RuntimeException();
}
@Override
public Bindings createBindings() {
throw new RuntimeException();
}
@Override
public ScriptContext getContext() {
throw new RuntimeException();
}
@Override
public void setContext(ScriptContext context) {
throw new RuntimeException();
}
@Override
public ScriptEngineFactory getFactory() {
throw new RuntimeException();
}
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2014, 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.
*
* 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 org.banana;
import java.util.Arrays;
import java.util.List;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
public class BananaScriptEngineFactory implements ScriptEngineFactory {
static final BananaScriptEngineFactory INSTANCE = new BananaScriptEngineFactory(null);
public BananaScriptEngineFactory() {
throw new RuntimeException("Should not be called");
}
private BananaScriptEngineFactory(Void param) { }
public static BananaScriptEngineFactory provider() {
return INSTANCE;
}
@Override
public String getEngineName() {
return "BananaScriptEngine";
}
@Override
public String getEngineVersion() {
return "1.0";
}
@Override
public List<String> getExtensions() {
return Arrays.asList("banana");
}
@Override
public List<String> getMimeTypes() {
return Arrays.asList("application/x-bananascript");
}
@Override
public List<String> getNames() {
return Arrays.asList("BananaScript");
}
@Override
public String getLanguageName() {
return "BananaScript";
}
@Override
public String getLanguageVersion() {
return "1.0";
}
@Override
public Object getParameter(String key) {
return null;
}
@Override
public String getMethodCallSyntax(String obj, String m, String... args) {
throw new RuntimeException();
}
@Override
public String getOutputStatement(String toDisplay) {
throw new RuntimeException();
}
@Override
public String getProgram(String... statements) {
throw new RuntimeException();
}
@Override
public ScriptEngine getScriptEngine() {
return new BananaScript();
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
module p1 {
requires s1;
provides p.S with q.P;
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2017, 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.
*
* 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 q;
import p.S;
public class P implements S { }

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
module p2 {
requires s2;
provides p.S with q.P;
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2017, 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.
*
* 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 q;
import p.S;
public class P implements S { }

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
module s1 {
exports p;
uses p.S;
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, 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.
*
* 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 p;
public interface S { }

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
module s2 {
exports p;
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, 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.
*
* 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 p;
public interface S { }

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2016, 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.
*
* 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.
*/
/**
* Test module that provides an implementation of p.Service via a
* provider factory class.
*/
module test1 {
exports p;
provides p.Service with p.ProviderFactory;
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* Provider factory
*/
public class ProviderFactory {
ProviderFactory() { }
private static final Service INSTANCE = new Service() { };
public static Service provider() {
return INSTANCE;
}
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* Service type
*/
public interface Service { }

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2016, 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.
*
* 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.
*/
/**
* Test module that provides an implementation of p.Service.
*/
module test2 {
exports p;
provides p.Service with p.Provider;
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* Provider type
*/
public class Provider implements Service {
public Provider() { }
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016, 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.
*
* 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 p;
/**
* Service type
*/
public interface Service { }

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
/**
* @test
* @modules java.scripting
* @build test/*
* @run main/othervm test/p.Main
* @summary Basic test of ServiceLoader.load from named modules that does
* does delcare the use
*/

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2017, 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.
*
* 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.
*/
module test {
exports p;
requires java.scripting;
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2017, 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.
*
* 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 p;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import javax.script.ScriptEngineFactory;
public class Main {
public static void main(String[] args) {
Module thisModule = Main.class.getModule();
assertTrue(thisModule.isNamed());
// this module does not declare that it uses ScriptEngineFactory
assertFalse(thisModule.canUse(ScriptEngineFactory.class));
try {
ServiceLoader.load(ScriptEngineFactory.class);
assertTrue(false);
} catch (ServiceConfigurationError expected) { }
// invoke addUses and retry
thisModule.addUses(ScriptEngineFactory.class);
ServiceLoader.load(ScriptEngineFactory.class).findFirst();
}
static void assertFalse(boolean value) {
if (value) throw new RuntimeException();
}
static void assertTrue(boolean value) {
if (!value) throw new RuntimeException();
}
}