private static <T> T findServiceProvider(final Class<T> type) throws DatatypeConfigurationException { try { return AccessController.doPrivileged(new PrivilegedAction<T>() { public T run() { final ServiceLoader<T> serviceLoader = ServiceLoader.load(type); final Iterator<T> iterator = serviceLoader.iterator(); if (iterator.hasNext()) { return iterator.next(); } else { return null; } } }); } catch(ServiceConfigurationError e) { final DatatypeConfigurationException error = new DatatypeConfigurationException( "Provider for " + type + " cannot be found", e); throw error; } }
private static AsynchronousChannelProvider loadProviderAsService() { ServiceLoader<AsynchronousChannelProvider> sl = ServiceLoader.load(AsynchronousChannelProvider.class, ClassLoader.getSystemClassLoader()); Iterator<AsynchronousChannelProvider> i = sl.iterator(); for (;;) { try { return (i.hasNext()) ? i.next() : null; } catch (ServiceConfigurationError sce) { if (sce.getCause() instanceof SecurityException) { // Ignore the security exception, try the next provider continue; } throw sce; } } }
private static Map<String, HandlerBuilder> loadBuilders(final ClassLoader classLoader) { ServiceLoader<HandlerBuilder> loader = ServiceLoader.load(HandlerBuilder.class, classLoader); final Map<String, HandlerBuilder> ret = new HashMap<>(); for (HandlerBuilder builder : loader) { if (ret.containsKey(builder.name())) { if (ret.get(builder.name()).getClass() != builder.getClass()) { throw UndertowMessages.MESSAGES.moreThanOneHandlerWithName(builder.name(), builder.getClass(), ret.get(builder.name()).getClass()); } } else { ret.put(builder.name(), builder); } } return ret; }
/** * Load {@link BeanPropertyPostProcessor}s from <code>META-INF/services</code> extensions. * @param classLoader ClassLoader to use * @return {@link BeanPropertyPostProcessor}s list, empty if none found */ private void init(final ClassLoader classLoader) { LOGGER.debug(() -> "Load BeanPropertyPostProcessors for classloader [" + classLoader + "] using ServiceLoader with service name: " + BeanPropertyPostProcessor.class.getName()); Iterable<BeanPropertyPostProcessor> postProcessors = AccessController .doPrivileged(new PrivilegedAction<Iterable<BeanPropertyPostProcessor>>() { @Override public Iterable<BeanPropertyPostProcessor> run() { return ServiceLoader.load(BeanPropertyPostProcessor.class, classLoader); } }); postProcessors.forEach(pr -> { propertyPostProcessors.add(pr); LOGGER.debug(() -> "Loaded and registered BeanPropertyPostProcessor [" + pr + "] for classloader [" + classLoader + "]"); }); // sort by priority Collections.sort(propertyPostProcessors, PRIORITY_COMPARATOR); }
@Test public void validateServiceIsLocatableViaServiceLoader() { ServiceLoader<Processor> loader = ServiceLoader.<Processor> load(Processor.class); Iterator<Processor> iter = loader.iterator(); boolean pubJmsPresent = false; boolean consumeJmsPresent = false; while (iter.hasNext()) { Processor p = iter.next(); if (p.getClass().getSimpleName().equals(PublishJMS.class.getSimpleName())) { pubJmsPresent = true; } else if (p.getClass().getSimpleName().equals(ConsumeJMS.class.getSimpleName())) { consumeJmsPresent = true; } } assertTrue(pubJmsPresent); assertTrue(consumeJmsPresent); }
public static void main(String[] args) { ServiceLoader<Analysis> analyses = ServiceLoader.load(Analysis.class); // analyses.stream().map(ServiceLoader.Provider::get).forEach(analyzer -> System.out.println(analyzer.getName())); Set<Analysis> collect = analyses.stream() .filter(p -> isAnno(p.type())) .map(ServiceLoader.Provider::get).collect(Collectors.toSet()); Person nao = new Person(0, 0); Person miniperson = new Person(10, 0); Person minperson = new Person(1001, 0); Person minxperson = new Person(1001, 11); Person maxperson = new Person(100000, 11); Person maxxperson = new Person(100000, 26); Person poorperson = new Person(100000, 0); collect.forEach(p->System.out.println(p.analyze(maxxperson))); }
/** * コンストラクタ * * @param connectionSupplier コネクションサプライヤ * @param loadPath SQLファイルの読み込みルートパス */ private DefaultSqlConfig(final ConnectionSupplier connectionSupplier, final String loadPath) { super(); this.connectionSupplier = connectionSupplier; this.sqlManager = new SqlManagerImpl(loadPath); this.sqlFilterManager = new SqlFilterManagerImpl(); this.sqlContextFactory = new SqlContextFactoryImpl(); this.entityHandler = new DefaultEntityHandler(); this.dialect = StreamSupport.stream(ServiceLoader.load(Dialect.class).spliterator(), false).filter(d -> d.accept(connectionSupplier)).findFirst().orElseGet(DefaultDialect::new); this.sqlAgentFactory = new SqlAgentFactoryImpl(this); initialize(); }
/** * Looks for all "META-INF/services/[className]" files and * create one instance for each class name found inside this file. */ private <T> List<T> findServices(Class<T> clazz) { final List<T> result = new ArrayList<>(); final boolean debug = getDebugPropertyValue(); try { // TCCL allows user plugins to be loaded even if xjc is in jdk // We have to use our SecureLoader to obtain it because we are trying to avoid SecurityException final ClassLoader tccl = SecureLoader.getContextClassLoader(); final ServiceLoader<T> sl = ServiceLoader.load(clazz, tccl); for (T t : sl) result.add(t); } catch (Throwable e) { // ignore any error StringWriter w = new StringWriter(); e.printStackTrace(new PrintWriter(w)); pluginLoadFailure = w.toString(); if (debug) System.out.println(pluginLoadFailure); } return result; }
@BeforeClass(alwaysRun=true) public static void loadTokenParser() throws Exception { System.out.printf("TokenValidationTest.initClass\n"); publicKey = TokenUtils.readPublicKey("/publicKey.pem"); if(publicKey == null) { throw new IllegalStateException("Failed to load /publicKey.pem resource"); } // Load the ITokenParser via the ServiceLoader ServiceLoader<ITokenParser> serviceLoader = ServiceLoader.load(ITokenParser.class); if(serviceLoader.iterator().hasNext() == false) { // Try to obtain ITokenParser via CDI tokenParser = CDI.current().select(ITokenParser.class).get(); if(tokenParser == null) { throw new IllegalStateException(String.format("An %s service provider or producer is required", ITokenParser.class.getName())); } } else { tokenParser = serviceLoader.iterator().next(); if (tokenParser == null) { throw new IllegalStateException(String.format("Service provider for %s produced a null parser", ITokenParser.class.getName())); } } System.out.printf("Using ITokenParser: %s\n", tokenParser); }
/** * 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")); }
@Override public LoggingBackend run() { final Iterator<LoggerFinder> iterator = ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader()) .iterator(); if (iterator.hasNext()) { return LoggingBackend.CUSTOM; // Custom Logger Provider is registered } // No custom logger provider: we will be using the default // backend. final Iterator<DefaultLoggerFinder> iterator2 = ServiceLoader.loadInstalled(DefaultLoggerFinder.class) .iterator(); if (iterator2.hasNext()) { // LoggingProviderImpl is registered. The default // implementation is java.util.logging String cname = System.getProperty("java.util.logging.config.class"); String fname = System.getProperty("java.util.logging.config.file"); return (cname != null || fname != null) ? LoggingBackend.JUL_WITH_CONFIG : LoggingBackend.JUL_DEFAULT; } else { // SimpleConsoleLogger is used return LoggingBackend.NONE; } }
/** * The plugins accessible in the current context. * * @param pluginsLayer * @return The list of plugins. */ private static <T extends Plugin> List<T> getPlugins(Class<T> clazz, ModuleLayer pluginsLayer) { Objects.requireNonNull(pluginsLayer); List<T> factories = new ArrayList<>(); try { Iterator<T> providers = ServiceLoader.load(pluginsLayer, clazz).iterator(); while (providers.hasNext()) { factories.add(providers.next()); } registeredPlugins.values().stream().forEach((fact) -> { if (clazz.isInstance(fact)) { @SuppressWarnings("unchecked") T trans = (T) fact; factories.add(trans); } }); return factories; } catch (Exception ex) { throw new PluginException(ex); } }
private void registerInstalledProviders() { /* We need to load installed providers from the system classpath (typically the <code>lib/ext</code> directory in in the Java installation directory) in the privileged mode in order to be able read corresponding jar files even if file read capability is restricted (like the applet context case). */ PrivilegedAction doRegistration = new PrivilegedAction() { public Object run() { Iterator categories = getCategories(); while (categories.hasNext()) { Class<IIOServiceProvider> c = (Class)categories.next(); for (IIOServiceProvider p : ServiceLoader.loadInstalled(c)) { registerServiceProvider(p); } } return this; } }; AccessController.doPrivileged(doRegistration); }
/** * 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; } } }
public static ObjectMapper createObjectMapper() { final YAMLFactory yamlFactory = new YAMLFactory() .configure(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID, false) .configure(YAMLGenerator.Feature.MINIMIZE_QUOTES, true) .configure(YAMLGenerator.Feature.ALWAYS_QUOTE_NUMBERS_AS_STRINGS, true) .configure(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID, false); ObjectMapper mapper = new ObjectMapper(yamlFactory) .registerModule(new Jdk8Module()) .setSerializationInclusion(JsonInclude.Include.NON_EMPTY) .enable(SerializationFeature.INDENT_OUTPUT) .disable(SerializationFeature.WRITE_NULL_MAP_VALUES); for (Step step : ServiceLoader.load(Step.class, YamlHelpers.class.getClassLoader())) { mapper.registerSubtypes(new NamedType(step.getClass(), step.getKind())); } return mapper; }
@Test public void test() { ServiceLoader<ClientModuleFactory> loader = ServiceLoader.load(ClientModuleFactory.class); Iterator<ClientModuleFactory> iterator = loader.iterator(); Set<Class> moduleClasses = new HashSet<>(); while (iterator.hasNext()) { ClientModuleFactory moduleFactory = iterator.next(); Module module = moduleFactory.create(); moduleClasses.add(module.getClass()); } Assert.assertEquals(2, moduleClasses.size()); Assert.assertTrue(moduleClasses.contains(ValidationModule.class)); Assert.assertTrue(moduleClasses.contains(MetaModule.class)); }
@Test public void test() { ServiceLoader<ClientModuleFactory> loader = ServiceLoader.load(ClientModuleFactory.class); Iterator<ClientModuleFactory> iterator = loader.iterator(); Set<Class> moduleClasses = new HashSet<>(); while (iterator.hasNext()) { ClientModuleFactory moduleFactory = iterator.next(); Module module = moduleFactory.create(); moduleClasses.add(module.getClass()); } Assert.assertEquals(2, moduleClasses.size()); Assert.assertTrue(moduleClasses.contains(JpaModule.class)); Assert.assertTrue(moduleClasses.contains(MetaModule.class)); }
private void doInvoke(String path) { ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { JarLoader jarLoader = new JarLoader(new String[]{path}); Thread.currentThread().setContextClassLoader(jarLoader); Iterator<Hook> hookIt = ServiceLoader.load(Hook.class).iterator(); if (!hookIt.hasNext()) { LOG.warn("No hook defined under path: " + path); } else { Hook hook = hookIt.next(); LOG.info("Invoke hook [{}], path: {}", hook.getName(), path); hook.invoke(conf, msg); } } catch (Exception e) { LOG.error("Exception when invoke hook", e); throw DataXException.asDataXException( CommonErrorCode.HOOK_INTERNAL_ERROR, "Exception when invoke hook", e); } finally { Thread.currentThread().setContextClassLoader(oldClassLoader); } }
private static FaultToleranceProviderResolver loadSpi(ClassLoader cl) { if (cl == null) { return null; } // start from the root CL and go back down to the TCCL FaultToleranceProviderResolver instance = loadSpi(cl.getParent()); if (instance == null) { ServiceLoader<FaultToleranceProviderResolver> sl = ServiceLoader.load(FaultToleranceProviderResolver.class, cl); for (FaultToleranceProviderResolver spi : sl) { if (instance != null) { throw new IllegalStateException("Multiple FaultToleranceResolverProvider implementations found: " + spi.getClass().getName() + " and " + instance.getClass().getName()); } else { instance = spi; } } } return instance; }
/** * Use the ServiceLoader mechanism to load the default RowSetFactory * @return default RowSetFactory Implementation */ static private RowSetFactory loadViaServiceLoader() throws SQLException { RowSetFactory theFactory = null; try { trace("***in loadViaServiceLoader():"); for (RowSetFactory factory : ServiceLoader.load(javax.sql.rowset.RowSetFactory.class)) { trace(" Loading done by the java.util.ServiceLoader :" + factory.getClass().getName()); theFactory = factory; break; } } catch (ServiceConfigurationError e) { throw new SQLException( "RowSetFactory: Error locating RowSetFactory using Service " + "Loader API: " + e, e); } return theFactory; }
/** * Creates an instance of {@link BatchEmitter} using one of available {@link BatchEmitterFactory} services. A check * for compatibility of given {@link ClientObjectFactory} with available services is performed. * <p> * NOTE: Currently the first found and compatible {@link BatchEmitterFactory} is selected as the {@link * BatchEmitter} provider. This is subject to change after new config features are added in future releases ( * priority-based selection will be available to provide more flexible extension capabilities). * * @param batchSize number of elements in a current batch that should trigger a delivery, regardless of * the delivery interval value * @param deliveryInterval number of millis between two time-triggered deliveries, regardless of the batch size * value * @param clientObjectFactory client-specific objects provider * @param failoverPolicy sink for failed batch items * @return T configured {@link BatchEmitter} */ public BatchEmitter createInstance(int batchSize, int deliveryInterval, ClientObjectFactory clientObjectFactory, FailoverPolicy failoverPolicy) { ServiceLoader<BatchEmitterFactory> loader = ServiceLoader.load(BatchEmitterFactory.class); Iterator<BatchEmitterFactory> it = loader.iterator(); while (it.hasNext()) { BatchEmitterFactory factory = it.next(); LOG.info("BatchEmitterFactory class found {}", factory); if (factory.accepts(clientObjectFactory.getClass())) { LOG.info("Using {} as BatchEmitterFactoryProvider", factory); return factory.createInstance(batchSize, deliveryInterval, clientObjectFactory, failoverPolicy); } } throw new ConfigurationException(String.format("No compatible BatchEmitter implementations for %s found", clientObjectFactory.getClass())); }
private void registerInstalledProviders() { /* We need to load installed providers in the privileged mode in order to be able read corresponding jar files even if file read capability is restricted (like the applet context case). */ PrivilegedAction<Object> doRegistration = new PrivilegedAction<Object>() { public Object run() { Iterator<Class<?>> categories = getCategories(); while (categories.hasNext()) { @SuppressWarnings("unchecked") Class<IIOServiceProvider> c = (Class<IIOServiceProvider>)categories.next(); for (IIOServiceProvider p : ServiceLoader.loadInstalled(c)) { registerServiceProvider(p); } } return this; } }; AccessController.doPrivileged(doRegistration); }
private static boolean loadProviderAsService() { Iterator<HttpServerProvider> i = ServiceLoader.load(HttpServerProvider.class, ClassLoader.getSystemClassLoader()) .iterator(); for (;;) { try { if (!i.hasNext()) return false; provider = i.next(); return true; } catch (ServiceConfigurationError sce) { if (sce.getCause() instanceof SecurityException) { // Ignore the security exception, try the next provider continue; } throw sce; } } }
static <P, T extends Exception> P firstByServiceLoader(Class<P> spiClass, Logger logger, ExceptionHandler<T> handler) throws T { logger.log(Level.FINE, "Using java.util.ServiceLoader to find {0}", spiClass.getName()); // service discovery try { ServiceLoader<P> serviceLoader = ServiceLoader.load(spiClass); for (P impl : serviceLoader) { logger.fine("ServiceProvider loading Facility used; returning object [" + impl.getClass().getName() + "]"); return impl; } } catch (Throwable t) { throw handler.createException(t, "Error while searching for service [" + spiClass.getName() + "]"); } return null; }
private void initializeInputMethodLocatorList() { synchronized (javaInputMethodLocatorList) { javaInputMethodLocatorList.clear(); try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { public Object run() { for (InputMethodDescriptor descriptor : ServiceLoader.loadInstalled(InputMethodDescriptor.class)) { ClassLoader cl = descriptor.getClass().getClassLoader(); javaInputMethodLocatorList.add(new InputMethodLocator(descriptor, cl, null)); } return null; } }); } catch (PrivilegedActionException e) { e.printStackTrace(); } javaInputMethodCount = javaInputMethodLocatorList.size(); } if (hasMultipleInputMethods()) { // initialize preferences if (userRoot == null) { userRoot = getUserRoot(); } } else { // indicate to clients not to offer the menu triggerMenuString = null; } }
public static FileHandler getXmlSteps(Class<? extends FileHandler> aClass) { ServiceLoader<? extends FileHandler> loader = ServiceLoader.load(aClass); for (FileHandler provider : loader) { if (provider.accept(aClass)) { return provider; } } return new XmlProvider(); }
private void checkIdentifiersValid(ServiceLoader<ArchUnitExtension> extensions) { for (ArchUnitExtension extension : extensions) { if (extension.getUniqueIdentifier().contains(".")) { throwLoadingException(extension, "Extension identifier '%s' must not contain '.'", extension.getUniqueIdentifier()); } } }
/** * @param options a space separated set of option value settings with each option setting in a * {@code -Dgraal.<name>=<value>} format but without the leading {@code -Dgraal.}. * Ignored if null. */ public static EconomicMap<OptionKey<?>, Object> parseOptions(String options) { if (options != null) { EconomicMap<String, String> optionSettings = EconomicMap.create(); for (String optionSetting : options.split("\\s+|#")) { OptionsParser.parseOptionSettingTo(optionSetting, optionSettings); } EconomicMap<OptionKey<?>, Object> values = OptionValues.newOptionMap(); ServiceLoader<OptionDescriptors> loader = ServiceLoader.load(OptionDescriptors.class, OptionDescriptors.class.getClassLoader()); OptionsParser.parseOptions(optionSettings, values, loader); return values; } return EconomicMap.create(); }
public static BookService getInstance(){ ServiceLoader<BookServiceProvider> sl = ServiceLoader.load(BookServiceProvider.class); Iterator<BookServiceProvider> iter = sl.iterator(); if (!iter.hasNext()) throw new RuntimeException("No service providers found!"); BookServiceProvider provider = null; while(iter.hasNext()){ provider = iter.next(); System.out.println(provider.getClass()); } return provider.getBookService(); }
/** * get target service.if target services are array,only random access to a service. */ public static <T> T getTargetService(Class<T> serviceType) { ServiceLoader<T> loader = ServiceLoader.load(serviceType); for (T service : loader) { LOGGER.info("get the SPI service success, the extend service is: {}", service.getClass()); return service; } LOGGER.info("Can not get the SPI service, the interface type is: {}", serviceType.toString()); return null; }
public static <S> S loadFirst(Class<S> clazz) { final ServiceLoader<S> loader = loadAll(clazz); final Iterator<S> iterator = loader.iterator(); if (!iterator.hasNext()) { throw new IllegalStateException(String.format( "No implementation defined in /META-INF/services/%s, please check whether the file exists and has the right implementation class!", clazz.getName())); } return iterator.next(); }
public DockerUnitRunner(Class<?> klass) throws InitializationError { super(klass); ServiceLoader<DiscoveryProviderFactory> loader = ServiceLoader.load(DiscoveryProviderFactory.class); List<DiscoveryProviderFactory> implementations = new ArrayList<>(); loader.forEach(impl -> { logger.info("Found discovery provider factory of type " + impl.getClass().getSimpleName()); implementations.add(impl); }); if(implementations.size() > 0) { logger.info("Using discovery provider factory " + implementations.get(0).getClass().getSimpleName()); discoveryProvider = implementations.get(0).getProvider(); } else { throw new InitializationError("No discovery provider factory found. Aborting test."); } }
private void addRemoteExceptionHandler(Router router) { RemoteLogger remoteLogger = StreamSupport.stream(ServiceLoader.load(RemoteLogger.class).spliterator(), false) .filter(logger -> logger.getClass().getName().equals(config.getString(REMOTE_LOGGER))) .findFirst().orElseGet(DefaultRemoteLogger::new); router.route("/service/remoteLogging") .handler(new RemoteLoggingHandler(remoteLogger)); }
public static PageSteps getPageSteps() { ServiceLoader<PageSteps> loader = ServiceLoader.load(PageSteps.class); for (PageSteps steps : loader) { if (steps.accept()) { return steps; } } return new BasePageSteps(); }
/** * Loads service implementations using Java {@link ServiceLoader}. * * @param serviceClass service interface. * @param <T> service. * @return service implementations. */ public static <T> List<T> loadServices(Class<T> serviceClass) { Iterator<T> iterator = ServiceLoader.load(serviceClass).iterator(); List<T> result = new ArrayList<>(); while (iterator.hasNext()) { result.add(iterator.next()); } return result; }
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(names1, names2); }
private static List<FileTypeDetector> loadInstalledDetectors() { return AccessController .doPrivileged(new PrivilegedAction<List<FileTypeDetector>>() { @Override public List<FileTypeDetector> run() { List<FileTypeDetector> list = new ArrayList<>(); ServiceLoader<FileTypeDetector> loader = ServiceLoader .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader()); for (FileTypeDetector detector: loader) { list.add(detector); } return list; }}); }
/** * Returns the available chronologies. * <p> * Each returned {@code Chronology} is available for use in the system. * The set of chronologies includes the system chronologies and * any chronologies provided by the application via ServiceLoader * configuration. * * @return the independent, modifiable set of the available chronology IDs, not null */ static Set<Chronology> getAvailableChronologies() { initCache(); // force initialization HashSet<Chronology> chronos = new HashSet<>(CHRONOS_BY_ID.values()); /// Add in Chronologies from the ServiceLoader configuration @SuppressWarnings("rawtypes") ServiceLoader<Chronology> loader = ServiceLoader.load(Chronology.class); for (Chronology chrono : loader) { chronos.add(chrono); } return chronos; }
private int runShellServiceLoader(String... args) { ServiceLoader<Tool> sl = ServiceLoader.load(Tool.class); for (Tool provider : sl) { if (provider.name().equals("jshell")) { return provider.run(cmdInStream, cmdout, cmderr, args); } } throw new AssertionError("Repl tool not found by ServiceLoader: " + sl); }