Search in sources :

Example 1 with VanillaPluginPlatform

use of org.spongepowered.vanilla.applaunch.plugin.VanillaPluginPlatform in project SpongeCommon by SpongePowered.

the class VanillaPluginManager method loadPlugins.

@SuppressWarnings("unchecked")
public void loadPlugins(final VanillaPluginPlatform platform) {
    this.locatedResources.putAll(platform.getResources());
    final Map<PluginCandidate<PluginResource>, PluginLanguageService<PluginResource>> pluginLanguageLookup = new HashMap<>();
    final Map<PluginLanguageService<PluginResource>, PluginLoader<PluginResource, PluginContainer>> pluginLoaders = new HashMap<>();
    // Initialise the plugin language loaders.
    for (final Map.Entry<PluginLanguageService<PluginResource>, List<PluginCandidate<PluginResource>>> candidate : platform.getCandidates().entrySet()) {
        final PluginLanguageService<PluginResource> languageService = candidate.getKey();
        final String loaderClass = languageService.pluginLoader();
        try {
            pluginLoaders.put(languageService, (PluginLoader<PluginResource, PluginContainer>) Class.forName(loaderClass).getConstructor().newInstance());
        } catch (final InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        candidate.getValue().forEach(x -> pluginLanguageLookup.put(x, languageService));
    }
    // Priority to platform plugins that will already exist here -- meaning the resolver will act upon them first
    // and if someone decides to give a plugin an ID that is the same as a platform plugin, the resolver will effectively
    // reject it.
    final Set<PluginCandidate<PluginResource>> resources = new LinkedHashSet<>();
    pluginLanguageLookup.keySet().stream().filter(x -> this.plugins.containsKey(x.metadata().id())).forEach(resources::add);
    resources.addAll(pluginLanguageLookup.keySet());
    final ResolutionResult<PluginResource> resolutionResult = DependencyResolver.resolveAndSortCandidates(resources, platform.logger());
    final Map<PluginCandidate<PluginResource>, String> failedInstances = new HashMap<>();
    final Map<PluginCandidate<PluginResource>, String> consequentialFailedInstances = new HashMap<>();
    final ClassLoader launchClassloader = VanillaLaunch.instance().getClass().getClassLoader();
    for (final PluginCandidate<PluginResource> candidate : resolutionResult.sortedSuccesses()) {
        final PluginContainer plugin = this.plugins.get(candidate.metadata().id());
        if (plugin != null) {
            if (plugin instanceof VanillaDummyPluginContainer) {
                continue;
            }
            // If we get here, we screwed up - duplicate IDs should have been detected earlier.
            // Place it in the resolution result... it'll then get picked up in the big error message
            resolutionResult.duplicateIds().add(candidate.metadata().id());
            // but this is our screw up, let's also make a big point of it
            final PrettyPrinter prettyPrinter = new PrettyPrinter(120).add("ATTEMPTED TO CREATE PLUGIN WITH DUPLICATE PLUGIN ID").centre().hr().addWrapped("Sponge attempted to create a second plugin with ID '%s'. This is not allowed - all plugins must have a unique " + "ID. Usually, Sponge will catch this earlier -- but in this case Sponge has validated two plugins with " + "the same ID. Please report this error to Sponge.", candidate.metadata().id()).add().add("Technical Details:").add("Plugins to load:", 4);
            resolutionResult.sortedSuccesses().forEach(x -> prettyPrinter.add("*" + x.metadata().id(), 4));
            prettyPrinter.add().add("Detected Duplicate IDs:", 4);
            resolutionResult.duplicateIds().forEach(x -> prettyPrinter.add("*" + x, 4));
            prettyPrinter.log(platform.logger(), Level.ERROR);
            continue;
        }
        // This should work fine, we're sorted so all deps should be in place at this stage.
        if (this.stillValid(candidate, consequentialFailedInstances)) {
            final PluginLanguageService<PluginResource> languageService = pluginLanguageLookup.get(candidate);
            final PluginLoader<PluginResource, PluginContainer> pluginLoader = pluginLoaders.get(languageService);
            try {
                final PluginContainer container = pluginLoader.loadPlugin(platform.getStandardEnvironment(), candidate, launchClassloader);
                this.addPlugin(container);
                this.containerToResource.put(container, candidate.resource());
            } catch (final InvalidPluginException e) {
                failedInstances.put(candidate, "Failed to construct: see stacktrace(s) above this message for details.");
                e.printStackTrace();
            }
        }
    }
    resolutionResult.printErrorsIfAny(failedInstances, consequentialFailedInstances, platform.logger());
    platform.logger().info("Loaded plugin(s): {}", this.sortedPlugins.stream().map(p -> p.metadata().id()).collect(Collectors.toList()));
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SpongePluginManager(org.spongepowered.common.launch.plugin.SpongePluginManager) PluginLanguageService(org.spongepowered.plugin.PluginLanguageService) PluginCandidate(org.spongepowered.plugin.PluginCandidate) Level(org.apache.logging.log4j.Level) PrettyPrinter(org.spongepowered.common.util.PrettyPrinter) HashMap(java.util.HashMap) DependencyResolver(org.spongepowered.vanilla.launch.plugin.resolver.DependencyResolver) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Object2ObjectOpenHashMap(it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) PluginLoader(org.spongepowered.plugin.PluginLoader) Map(java.util.Map) LinkedHashSet(java.util.LinkedHashSet) IdentityHashMap(java.util.IdentityHashMap) ResolutionResult(org.spongepowered.vanilla.launch.plugin.resolver.ResolutionResult) Collection(java.util.Collection) Set(java.util.Set) InvalidPluginException(org.spongepowered.plugin.InvalidPluginException) Collectors(java.util.stream.Collectors) InvocationTargetException(java.lang.reflect.InvocationTargetException) Objects(java.util.Objects) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) PluginContainer(org.spongepowered.plugin.PluginContainer) PluginDependency(org.spongepowered.plugin.metadata.model.PluginDependency) VanillaPluginPlatform(org.spongepowered.vanilla.applaunch.plugin.VanillaPluginPlatform) Optional(java.util.Optional) PluginResource(org.spongepowered.plugin.PluginResource) Collections(java.util.Collections) Singleton(com.google.inject.Singleton) VanillaLaunch(org.spongepowered.vanilla.launch.VanillaLaunch) HashMap(java.util.HashMap) Object2ObjectOpenHashMap(it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) IdentityHashMap(java.util.IdentityHashMap) PluginLanguageService(org.spongepowered.plugin.PluginLanguageService) PrettyPrinter(org.spongepowered.common.util.PrettyPrinter) InvalidPluginException(org.spongepowered.plugin.InvalidPluginException) PluginResource(org.spongepowered.plugin.PluginResource) ArrayList(java.util.ArrayList) List(java.util.List) PluginLoader(org.spongepowered.plugin.PluginLoader) PluginContainer(org.spongepowered.plugin.PluginContainer) PluginCandidate(org.spongepowered.plugin.PluginCandidate) InvocationTargetException(java.lang.reflect.InvocationTargetException) HashMap(java.util.HashMap) Object2ObjectOpenHashMap(it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap)

Example 2 with VanillaPluginPlatform

use of org.spongepowered.vanilla.applaunch.plugin.VanillaPluginPlatform in project SpongeCommon by SpongePowered.

the class AbstractVanillaLaunchHandler method configureTransformationClassLoader.

@Override
public void configureTransformationClassLoader(final ITransformingClassLoaderBuilder builder) {
    // Specifically requested to be available on the launch loader
    final VanillaPluginPlatform platform = AppLaunch.pluginPlatform();
    for (final Path path : platform.getStandardEnvironment().blackboard().getOrCreate(VanillaPluginPlatform.EXTRA_TRANSFORMABLE_PATHS, () -> Collections.emptyList())) {
        builder.addTransformationPath(path);
    }
    // todo: we might be able to eliminate this at some point, but that causes complications
    for (final URL url : Java9ClassLoaderUtil.getSystemClassPathURLs()) {
        try {
            final URI uri = url.toURI();
            if (!this.isTransformable(uri)) {
                this.logger.debug("Non-transformable system classpath entry: {}", uri);
                continue;
            }
            builder.addTransformationPath(Paths.get(uri));
            this.logger.debug("Transformable system classpath entry: {}", uri);
        } catch (final URISyntaxException | IOException ex) {
            this.logger.error("Failed to add {} to transformation path", url, ex);
        }
    }
    builder.setResourceEnumeratorLocator(this.getResourceLocator());
    builder.setManifestLocator(this.getManifestLocator());
}
Also used : Path(java.nio.file.Path) VanillaPluginPlatform(org.spongepowered.vanilla.applaunch.plugin.VanillaPluginPlatform) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) URI(java.net.URI) URL(java.net.URL)

Aggregations

VanillaPluginPlatform (org.spongepowered.vanilla.applaunch.plugin.VanillaPluginPlatform)2 Singleton (com.google.inject.Singleton)1 Object2ObjectOpenHashMap (it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)1 IOException (java.io.IOException)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 URL (java.net.URL)1 Path (java.nio.file.Path)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 IdentityHashMap (java.util.IdentityHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1