PageRenderTime 65ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/container/src/main/java/com/atlassian/labs/remoteapps/container/Container.java

https://bitbucket.org/jpendleton_atlassian/remoteapps-plugin
Java | 469 lines | 420 code | 42 blank | 7 comment | 18 complexity | 77ee67f966456ca5dd86e2024d867b0f MD5 | raw file
  1. package com.atlassian.labs.remoteapps.container;
  2. import com.atlassian.activeobjects.spi.DataSourceProvider;
  3. import com.atlassian.event.api.EventPublisher;
  4. import com.atlassian.jira.rest.client.p3.*;
  5. import com.atlassian.labs.remoteapps.api.service.EmailSender;
  6. import com.atlassian.labs.remoteapps.api.service.confluence.*;
  7. import com.atlassian.labs.remoteapps.api.service.http.HostXmlRpcClient;
  8. import com.atlassian.labs.remoteapps.api.service.http.HttpClient;
  9. import com.atlassian.labs.remoteapps.container.service.ContainerEmailSender;
  10. import com.atlassian.labs.remoteapps.container.service.plugins.NoOpWebResourceManager;
  11. import com.atlassian.labs.remoteapps.container.service.sal.*;
  12. import com.atlassian.labs.remoteapps.host.common.HostProperties;
  13. import com.atlassian.labs.remoteapps.host.common.descriptor.DescriptorPermissionsReader;
  14. import com.atlassian.labs.remoteapps.host.common.descriptor.PolyglotDescriptorAccessor;
  15. import com.atlassian.labs.remoteapps.host.common.descriptor.DescriptorAccessor;
  16. import com.atlassian.labs.remoteapps.api.service.HttpResourceMounter;
  17. import com.atlassian.labs.remoteapps.api.service.RequestContext;
  18. import com.atlassian.labs.remoteapps.api.service.SignedRequestHandler;
  19. import com.atlassian.labs.remoteapps.api.service.http.HostHttpClient;
  20. import com.atlassian.labs.remoteapps.host.common.service.confluence.*;
  21. import com.atlassian.labs.remoteapps.host.common.service.http.*;
  22. import com.atlassian.labs.remoteapps.host.common.service.RequestContextServiceFactory;
  23. import com.atlassian.labs.remoteapps.container.ao.RemoteAppsDataSourceProviderServiceFactory;
  24. import com.atlassian.labs.remoteapps.container.internal.EnvironmentFactory;
  25. import com.atlassian.labs.remoteapps.container.internal.properties.ResourcePropertiesLoader;
  26. import com.atlassian.labs.remoteapps.container.service.ContainerEventPublisher;
  27. import com.atlassian.labs.remoteapps.container.service.ContainerHttpResourceMounterServiceFactory;
  28. import com.atlassian.labs.remoteapps.container.service.OAuthSignedRequestHandlerServiceFactory;
  29. import com.atlassian.labs.remoteapps.container.service.event.RemoteAppsEventPublisher;
  30. import com.atlassian.labs.remoteapps.container.util.ZipWriter;
  31. import com.atlassian.labs.remoteapps.host.common.service.jira.*;
  32. import com.atlassian.labs.remoteapps.host.common.util.BundleLocator;
  33. import com.atlassian.labs.remoteapps.host.common.util.BundleUtil;
  34. import com.atlassian.plugin.DefaultModuleDescriptorFactory;
  35. import com.atlassian.plugin.PluginAccessor;
  36. import com.atlassian.plugin.PluginController;
  37. import com.atlassian.plugin.event.PluginEventManager;
  38. import com.atlassian.plugin.event.impl.DefaultPluginEventManager;
  39. import com.atlassian.plugin.hostcontainer.DefaultHostContainer;
  40. import com.atlassian.plugin.loaders.*;
  41. import com.atlassian.plugin.loaders.classloading.Scanner;
  42. import com.atlassian.plugin.manager.DefaultPluginManager;
  43. import com.atlassian.plugin.manager.store.MemoryPluginPersistentStateStore;
  44. import com.atlassian.plugin.module.ClassPrefixModuleFactory;
  45. import com.atlassian.plugin.module.ModuleFactory;
  46. import com.atlassian.plugin.module.PrefixDelegatingModuleFactory;
  47. import com.atlassian.plugin.osgi.container.OsgiContainerManager;
  48. import com.atlassian.plugin.osgi.container.OsgiPersistentCache;
  49. import com.atlassian.plugin.osgi.container.felix.FelixOsgiContainerManager;
  50. import com.atlassian.plugin.osgi.container.impl.DefaultOsgiPersistentCache;
  51. import com.atlassian.plugin.osgi.container.impl.DefaultPackageScannerConfiguration;
  52. import com.atlassian.plugin.osgi.factory.OsgiBundleFactory;
  53. import com.atlassian.plugin.osgi.factory.OsgiPluginFactory;
  54. import com.atlassian.plugin.osgi.hostcomponents.ComponentRegistrar;
  55. import com.atlassian.plugin.osgi.hostcomponents.ContextClassLoaderStrategy;
  56. import com.atlassian.plugin.osgi.hostcomponents.HostComponentProvider;
  57. import com.atlassian.plugin.osgi.module.BeanPrefixModuleFactory;
  58. import com.atlassian.plugin.webresource.WebResourceManager;
  59. import com.atlassian.sal.api.ApplicationProperties;
  60. import com.atlassian.sal.api.message.I18nResolver;
  61. import com.atlassian.sal.api.message.LocaleResolver;
  62. import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
  63. import com.atlassian.sal.api.transaction.TransactionTemplate;
  64. import com.atlassian.sal.core.transaction.NoOpTransactionTemplate;
  65. import com.google.common.collect.ImmutableList;
  66. import com.google.common.collect.ImmutableMap;
  67. import com.google.common.collect.ImmutableSet;
  68. import com.google.common.collect.Iterables;
  69. import org.osgi.framework.Bundle;
  70. import org.slf4j.Logger;
  71. import org.slf4j.LoggerFactory;
  72. import java.io.File;
  73. import java.io.FileNotFoundException;
  74. import java.io.IOException;
  75. import java.net.Socket;
  76. import java.net.URI;
  77. import java.net.UnknownHostException;
  78. import java.util.List;
  79. import java.util.Map;
  80. import java.util.Set;
  81. import static com.atlassian.labs.remoteapps.container.util.AppRegister.registerApp;
  82. import static com.google.common.collect.Lists.newArrayList;
  83. import static com.google.common.collect.Maps.newHashMap;
  84. import static com.google.common.collect.Sets.newHashSet;
  85. import static java.util.Arrays.asList;
  86. public final class Container
  87. {
  88. private static final Logger log = LoggerFactory.getLogger(Container.class);
  89. public static final Set<URI> AUTOREGISTER_HOSTS = ImmutableSet.of(
  90. URI.create("http://localhost:1990/confluence"),
  91. URI.create("http://localhost:2990/jira"),
  92. URI.create("http://localhost:5990/refapp"));
  93. private final DefaultPluginManager pluginManager;
  94. private final HttpServer httpServer;
  95. private DescriptorAccessor descriptorAccessor;
  96. private AppReloader appReloader;
  97. public Container(HttpServer server, String[] apps) throws FileNotFoundException
  98. {
  99. this.httpServer = server;
  100. HostProperties hostProperties = new ContainerHostProperties();
  101. // todo: this should use the plugin api, but it doesn't allow setting of plugin loaders right now
  102. final DefaultPackageScannerConfiguration scannerConfig = new DefaultPackageScannerConfiguration(determineVersion());
  103. final List<String> scannedPackageIncludes = scannerConfig.getPackageIncludes();
  104. Iterables.removeAll(scannedPackageIncludes, ImmutableList.builder()
  105. .add("com.opensymphony.*")
  106. .add("org.jfree.*")
  107. .add("org.joda.*")
  108. .add("org.ofbiz.*")
  109. .add("org.quartz")
  110. .add("org.quartz.*")
  111. .add("org.tuckey.web.filters.urlrewrite.*")
  112. .add("org.xml.*")
  113. .add("org.w3c.*")
  114. .add("webwork.*")
  115. .build());
  116. scannerConfig.setPackageIncludes(ImmutableList.<String>builder()
  117. .addAll(scannedPackageIncludes)
  118. .add("com.atlassian.activeobjects.spi*")
  119. .add("com.atlassian.jira.rest.client.p3")
  120. .add("com.atlassian.jira.rest.client.domain")
  121. .add("com.atlassian.event.api*")
  122. .add("com.atlassian.plugin*")
  123. .add("com.atlassian.sal*")
  124. .add("com.atlassian.xmlrpc*")
  125. .add("com.atlassian.security.random*")
  126. .add("com.atlassian.fugue*")
  127. .add("com.atlassian.mail*")
  128. .add("com.google.common.*")
  129. .add("com.samskivert.*")
  130. .add("javax.servlet*")
  131. .add("javax.ws.rs*")
  132. .add("net.oauth*")
  133. .add("com.sun.mail.handlers")
  134. .add("org.apache.commons.codec*")
  135. .add("org.apache.log4j*")
  136. .add("org.bouncycastle*")
  137. .add("org.dom4j*")
  138. .add("org.eclipse.jetty.*")
  139. .add("org.jruby*")
  140. .add("org.json")
  141. .add("org.mozilla.javascript*")
  142. .add("org.slf4j*")
  143. .add("org.apache.log4j")
  144. .add("org.yaml*")
  145. .add("javax.inject")
  146. .add("redstone.xmlrpc")
  147. .build());
  148. scannerConfig.setPackageVersions(ImmutableMap.<String, String>builder()
  149. .put("com.atlassian.activeobjects.spi", getVersionFromMavenMetadata("com.atlassian.activeobjects", "activeobjects-spi", "0.19.4"))
  150. .put("com.atlassian.event.api*", getVersionFromMavenMetadata("com.atlassian.event", "atlassian-event", "2.2.0-m1"))
  151. .put("com.atlassian.plugin*", getVersionFromMavenMetadata("com.atlassian.plugins", "atlassian-plugins-core", "2.13.0-m2"))
  152. .put("com.atlassian.sal.api*", getVersionFromMavenMetadata("com.atlassian.sal", "sal-api", "2.7.0"))
  153. .put("com.atlassian.security.random*", getVersionFromMavenMetadata("com.atlassian.security", "atlassian-secure-random", "1.0"))
  154. .put("com.google.common.*", getVersionFromMavenMetadata("com.google.guava", "guava", "1"))
  155. .put("javax.servlet", "2.5")
  156. .put("javax.servlet.http", "2.5")
  157. .put("javax.inject", "1")
  158. .put("org.apache.commons.codec*", "1.3")
  159. .put("org.apache.commons.collections*", "3.2")
  160. .put("org.apache.commons.lang*", getVersionFromMavenMetadata("commons-lang", "commons-lang", "2.4"))
  161. .put("org.slf4j*", getVersionFromMavenMetadata("org.slf4j", "slf4j-api", "1.6.4"))
  162. .put("org.apache.log4j", getVersionFromMavenMetadata("log4j", "log4j", "1.2.16"))
  163. .put("org.dom4j*", getVersionFromMavenMetadata("dom4j", "dom4j", "1.4"))
  164. .build());
  165. scannerConfig.setPackageExcludes(ImmutableList.<String>builder()
  166. .addAll(scannerConfig.getPackageExcludes())
  167. .add("com.atlassian.activeobjects*")
  168. .add("com.atlassian.dbexporter*")
  169. .build());
  170. OsgiPersistentCache osgiCache = new DefaultOsgiPersistentCache(mkdir(".cache/osgi"));
  171. Map<Class<?>, Object> hostComponents = newHashMap();
  172. PluginEventManager pluginEventManager = new DefaultPluginEventManager();
  173. final OsgiContainerManager osgiContainerManager = new FelixOsgiContainerManager(
  174. osgiCache,
  175. scannerConfig,
  176. new ContainerHostComponentProvider(hostComponents),
  177. pluginEventManager);
  178. OsgiBundleFactory bundleFactory = new OsgiBundleFactory(osgiContainerManager, pluginEventManager);
  179. OsgiPluginFactory osgiPluginDeployer = new OsgiPluginFactory(
  180. PluginAccessor.Descriptor.FILENAME,
  181. ImmutableSet.of("remoteapp"),
  182. osgiCache,
  183. osgiContainerManager,
  184. pluginEventManager);
  185. final Scanner scanner;
  186. if (apps.length == 0)
  187. {
  188. File appDir = mkdir("apps");
  189. scanner = new DirectoryScanner(appDir);
  190. }
  191. else
  192. {
  193. List<File> files = newArrayList();
  194. for (String app : apps)
  195. {
  196. File appFile = new File(app);
  197. try
  198. {
  199. appFile = appFile.getCanonicalFile();
  200. }
  201. catch (IOException e)
  202. {
  203. throw new RuntimeException("Unable to determine canonical path", e);
  204. }
  205. if (!appFile.exists())
  206. {
  207. throw new FileNotFoundException("App '" + app + "' not found");
  208. }
  209. if (appFile.isDirectory())
  210. {
  211. System.setProperty("plugin.resource.directories", appFile.getAbsolutePath());
  212. descriptorAccessor = new PolyglotDescriptorAccessor(appFile);
  213. File appAsZip = zipAppDirectory(descriptorAccessor, appFile);
  214. files.add(appAsZip);
  215. }
  216. else
  217. {
  218. files.add(appFile);
  219. }
  220. }
  221. scanner = new FileListScanner(files);
  222. }
  223. final PluginLoader bundledPluginLoader = new BundledPluginLoader(this.getClass().getResource("/bundled-plugins.zip"), new File(".cache/bundled"), asList(osgiPluginDeployer, bundleFactory), pluginEventManager);
  224. final PluginLoader appPluginLoader = new ScanningPluginLoader(scanner, asList(osgiPluginDeployer, bundleFactory), pluginEventManager);
  225. final DefaultHostContainer hostContainer = new DefaultHostContainer();
  226. pluginManager = new DefaultPluginManager(
  227. new MemoryPluginPersistentStateStore(),
  228. asList(bundledPluginLoader, appPluginLoader),
  229. new DefaultModuleDescriptorFactory(hostContainer),
  230. pluginEventManager
  231. );
  232. final RemoteAppsPluginSettingsFactory pluginSettingsFactory = new RemoteAppsPluginSettingsFactory();
  233. hostComponents.put(PluginSettingsFactory.class, pluginSettingsFactory);
  234. final RemoteAppsApplicationPropertiesServiceFactory applicationPropertiesServiceFactory = new RemoteAppsApplicationPropertiesServiceFactory(server);
  235. hostComponents.put(ApplicationProperties.class, applicationPropertiesServiceFactory);
  236. hostComponents.put(EventPublisher.class, new RemoteAppsEventPublisher());
  237. final EnvironmentFactory environmentFactory = new EnvironmentFactory(pluginSettingsFactory, pluginManager);
  238. final OAuthSignedRequestHandlerServiceFactory oAuthSignedRequestHandlerServiceFactory = new OAuthSignedRequestHandlerServiceFactory(environmentFactory, httpServer);
  239. final RequestContextServiceFactory requestContextServiceFactory = new RequestContextServiceFactory(oAuthSignedRequestHandlerServiceFactory);
  240. final ContainerHttpResourceMounterServiceFactory containerHttpResourceMounterServiceFactory = new ContainerHttpResourceMounterServiceFactory(pluginManager, httpServer, oAuthSignedRequestHandlerServiceFactory, environmentFactory, requestContextServiceFactory);
  241. final RequestKiller requestKiller = new RequestKiller();
  242. final ContainerEventPublisher containerEventPublisher = new ContainerEventPublisher();
  243. final DefaultHttpClient httpClient = new DefaultHttpClient(requestKiller, containerEventPublisher);
  244. final HostHttpClientServiceFactory hostHttpClientServiceFactory = new HostHttpClientServiceFactory(httpClient, requestContextServiceFactory, oAuthSignedRequestHandlerServiceFactory);
  245. hostComponents.put(SignedRequestHandler.class, oAuthSignedRequestHandlerServiceFactory);
  246. hostComponents.put(HttpResourceMounter.class, containerHttpResourceMounterServiceFactory);
  247. hostComponents.put(PluginAccessor.class, pluginManager);
  248. hostComponents.put(PluginController.class, pluginManager);
  249. hostComponents.put(PluginEventManager.class, pluginEventManager);
  250. hostComponents.put(ModuleFactory.class, new PrefixDelegatingModuleFactory(ImmutableSet.of(new ClassPrefixModuleFactory(hostContainer), new BeanPrefixModuleFactory())));
  251. hostComponents.put(RequestContext.class, requestContextServiceFactory);
  252. hostComponents.put(HttpClient.class, httpClient);
  253. hostComponents.put(HostHttpClient.class, hostHttpClientServiceFactory);
  254. final HostXmlRpcClientServiceFactory hostXmlRpcClientHostServiceFactory = new HostXmlRpcClientServiceFactory(hostHttpClientServiceFactory);
  255. hostComponents.put(HostXmlRpcClient.class, hostXmlRpcClientHostServiceFactory);
  256. hostComponents.put(EmailSender.class, new HostHttpClientConsumerServiceFactory<EmailSender>(hostHttpClientServiceFactory, ContainerEmailSender.class));
  257. hostComponents.put(LocaleResolver.class, new ContainerLocaleResolver());
  258. hostComponents.put(I18nResolver.class, new ContainerI18nResolver(pluginManager, pluginEventManager, new ResourceBundleResolverImpl()));
  259. hostComponents.put(WebResourceManager.class, new NoOpWebResourceManager());
  260. hostComponents.put(DataSourceProvider.class, new RemoteAppsDataSourceProviderServiceFactory(applicationPropertiesServiceFactory));
  261. hostComponents.put(TransactionTemplate.class, new NoOpTransactionTemplate());
  262. // jira services
  263. hostComponents.put(JiraComponentClient.class, new JiraComponentClientServiceFactory(hostHttpClientServiceFactory));
  264. hostComponents.put(JiraProjectClient.class, new JiraProjectClientServiceFactory(hostHttpClientServiceFactory));
  265. hostComponents.put(JiraVersionClient.class, new JiraVersionClientServiceFactory(hostHttpClientServiceFactory));
  266. JiraMetadataClientServiceFactory metadataFactory = new JiraMetadataClientServiceFactory(hostHttpClientServiceFactory);
  267. hostComponents.put(JiraMetadataClient.class, metadataFactory);
  268. hostComponents.put(JiraIssueClient.class, new JiraIssueClientServiceFactory(hostHttpClientServiceFactory, requestContextServiceFactory, metadataFactory));
  269. hostComponents.put(JiraSearchClient.class, new JiraSearchClientServiceFactory(hostHttpClientServiceFactory));
  270. hostComponents.put(JiraUserClient.class, new JiraUserClientServiceFactory(hostHttpClientServiceFactory));
  271. DescriptorPermissionsReader permissionsReader = createPermissionsReaderForProduct(osgiContainerManager, "confluence");
  272. // confluence services
  273. hostComponents.put(ConfluenceSpaceClient.class, new ConfluenceSpaceClientServiceFactory(hostHttpClientServiceFactory, hostXmlRpcClientHostServiceFactory,
  274. permissionsReader, pluginManager, requestContextServiceFactory));
  275. hostComponents.put(ConfluencePageClient.class, new ConfluencePageClientServiceFactory(hostHttpClientServiceFactory, hostXmlRpcClientHostServiceFactory,
  276. permissionsReader, pluginManager, requestContextServiceFactory));
  277. hostComponents.put(ConfluenceAdminClient.class, new ConfluenceAdminClientServiceFactory(hostHttpClientServiceFactory, hostXmlRpcClientHostServiceFactory,
  278. permissionsReader, pluginManager, requestContextServiceFactory));
  279. hostComponents.put(ConfluenceBlogClient.class, new ConfluenceBlogClientServiceFactory(hostHttpClientServiceFactory, hostXmlRpcClientHostServiceFactory,
  280. permissionsReader, pluginManager, requestContextServiceFactory));
  281. hostComponents.put(ConfluenceLabelClient.class, new ConfluenceLabelClientServiceFactory(hostHttpClientServiceFactory, hostXmlRpcClientHostServiceFactory,
  282. permissionsReader, pluginManager, requestContextServiceFactory));
  283. hostComponents.put(ConfluenceNotificationClient.class, new ConfluenceNotificationClientServiceFactory(hostHttpClientServiceFactory, hostXmlRpcClientHostServiceFactory,
  284. permissionsReader, pluginManager, requestContextServiceFactory));
  285. hostComponents.put(ConfluenceUserClient.class, new ConfluenceUserClientServiceFactory(hostHttpClientServiceFactory, hostXmlRpcClientHostServiceFactory,
  286. permissionsReader, pluginManager, requestContextServiceFactory));
  287. hostComponents.put(ConfluenceAttachmentClient.class, new ConfluenceAttachmentClientServiceFactory(hostHttpClientServiceFactory, hostXmlRpcClientHostServiceFactory,
  288. permissionsReader, pluginManager, requestContextServiceFactory));
  289. }
  290. private DescriptorPermissionsReader createPermissionsReaderForProduct(final OsgiContainerManager osgiContainerManager, final String productKey)
  291. {
  292. return new DescriptorPermissionsReader(new HostProperties()
  293. {
  294. @Override
  295. public String getKey()
  296. {
  297. return productKey;
  298. }
  299. }, new BundleLocator()
  300. {
  301. @Override
  302. public Bundle getBundle(String pluginKey)
  303. {
  304. return BundleUtil.findBundleForPlugin(osgiContainerManager.getBundles()[0].getBundleContext(), pluginKey);
  305. }
  306. });
  307. }
  308. private String getVersionFromMavenMetadata(String groupId, String artifactId, String defaultValue)
  309. {
  310. final String resource = "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties";
  311. final String version = new ResourcePropertiesLoader(resource).load().get("version");
  312. if (version == null)
  313. {
  314. log.warn("Could not read version from maven metadata for {}:{} will use default {}", new Object[]{groupId, artifactId, defaultValue});
  315. return defaultValue;
  316. }
  317. log.debug("Version found from maven metadata for {}:{} is {}", new Object[]{groupId, artifactId, version});
  318. return version;
  319. }
  320. private File zipAppDirectory(DescriptorAccessor descriptorAccessor, File appFile)
  321. {
  322. try
  323. {
  324. return ZipWriter.zipAppIntoPluginJar(descriptorAccessor, appFile);
  325. }
  326. catch (IOException e)
  327. {
  328. throw new IllegalArgumentException("Unable to zip up app: " + appFile.getPath(), e);
  329. }
  330. }
  331. public void start() throws IOException
  332. {
  333. pluginManager.init();
  334. Set<URI> foundHosts = findHostProducts();
  335. if (descriptorAccessor != null)
  336. {
  337. final String appKey = descriptorAccessor.getKey();
  338. appReloader = new AppReloader(descriptorAccessor, httpServer.getLocalMountBaseUrl(appKey), foundHosts);
  339. }
  340. else
  341. {
  342. for (URI host : foundHosts)
  343. {
  344. for (String appKey : httpServer.getContextNames())
  345. {
  346. registerApp(host, appKey, httpServer.getLocalMountBaseUrl(appKey));
  347. }
  348. }
  349. }
  350. }
  351. private Set<URI> findHostProducts()
  352. {
  353. Set<URI> found = newHashSet();
  354. for (URI host : AUTOREGISTER_HOSTS)
  355. {
  356. Socket socket = null;
  357. try
  358. {
  359. log.debug("Scanning for host at " + host);
  360. socket = new Socket(host.getHost(), host.getPort());
  361. found.add(host);
  362. }
  363. catch (UnknownHostException e)
  364. {
  365. throw new RuntimeException("Not possible", e);
  366. }
  367. catch (IOException e)
  368. {
  369. // ignore, and try another
  370. }
  371. finally
  372. {
  373. try
  374. {
  375. if (socket != null)
  376. {
  377. socket.close();
  378. }
  379. }
  380. catch (IOException e)
  381. {
  382. // ignore
  383. }
  384. }
  385. }
  386. return found;
  387. }
  388. public void stop()
  389. {
  390. pluginManager.shutdown();
  391. if (appReloader != null)
  392. {
  393. appReloader.shutdown();
  394. }
  395. }
  396. private File mkdir(String path)
  397. {
  398. File file = new File(path);
  399. if (!file.exists())
  400. {
  401. file.mkdirs();
  402. }
  403. return file;
  404. }
  405. private String determineVersion()
  406. {
  407. return "1";
  408. }
  409. private static class ContainerHostComponentProvider implements HostComponentProvider
  410. {
  411. private final Map<Class<?>, Object> requiredServices;
  412. public ContainerHostComponentProvider(Map<Class<?>, Object> requiredServices)
  413. {
  414. this.requiredServices = requiredServices;
  415. }
  416. public void provide(ComponentRegistrar registrar)
  417. {
  418. for (Map.Entry<Class<?>, Object> entry : requiredServices.entrySet())
  419. {
  420. // register with the plugin ccl strategy to avoid
  421. // the ccl-switching proxy that breaks with ServiceFactory
  422. registrar.register(entry.getKey()).forInstance(entry.getValue()).withContextClassLoaderStrategy(
  423. ContextClassLoaderStrategy.USE_PLUGIN);
  424. }
  425. }
  426. }
  427. }