use of org.lanternpowered.launch.LanternClassLoader in project LanternServer by LanternPowered.
the class AssetRepositoryJsonDeserializer method deserialize.
@Override
public AssetRepository deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final MultiAssetRepository repository = new MultiAssetRepository();
// The class loader asset repository will always be present,
// this cannot be overridden, but the assets themselves can
// be overridden like the minecraft resource pack system
final ClassLoaderAssetRepository classLoaderAssetRepository = new ClassLoaderAssetRepository(this.pluginManager);
repository.add(classLoaderAssetRepository);
final LanternClassLoader classLoader = LanternClassLoader.get();
final Consumer<URL> consumer = url -> {
final Path path = PathUtils.toPath(url);
if (Files.isDirectory(path) && Files.exists(path.resolve("data-packs.info"))) {
Lantern.getLogger().debug("Registered a data pack asset repository: " + path);
repository.add(new PacksAssetRepository(this.pluginManager, path));
} else {
classLoaderAssetRepository.addRepository(path);
}
};
classLoader.getBaseURLs().forEach(consumer);
classLoader.addBaseURLTracker(consumer);
final JsonArray array = json.getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
final JsonObject obj = array.get(i).getAsJsonObject();
final String type = obj.get("type").getAsString().toLowerCase(Locale.ENGLISH);
Path path;
switch(type) {
// Currently only directory asset repositories
case "dir":
case "directory":
path = Paths.get(obj.get("path").getAsString());
Lantern.getLogger().debug("Registered a directory asset repository: " + path);
repository.add(new DirectoryAssetRepository(this.pluginManager, path));
break;
// Also support a directory with data/asset packs
case "packs":
path = Paths.get(obj.get("path").getAsString());
Lantern.getLogger().debug("Registered a data pack asset repository: " + path);
repository.add(new PacksAssetRepository(this.pluginManager, path));
break;
default:
throw new JsonParseException("Unknown repository type: " + type);
}
if (!Files.exists(path)) {
try {
Files.createDirectories(path);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return repository;
}
use of org.lanternpowered.launch.LanternClassLoader in project LanternServer by LanternPowered.
the class LanternServerLaunch method main.
public void main(String[] args) {
final LanternClassLoader classLoader = LanternClassLoader.get();
// Exclude the ASM library
classLoader.addTransformerExclusion(Exclusion.forPackage("org.objectweb.asm"));
classLoader.addTransformerExclusion(Exclusion.forPackage("org.lanternpowered.server.transformer"));
classLoader.addTransformerExclusion(Exclusion.forClass("org.lanternpowered.server.util.BytecodeUtils"));
classLoader.addTransformer(new FinalFieldClassTransformer());
classLoader.addTransformer(new FastValueContainerClassTransformer());
// Get the default logger
final Logger logger = LoggerFactory.getLogger(InternalPluginsInfo.Implementation.IDENTIFIER);
try {
// Create the shared option parser
final OptionParser optionParser = new OptionParser();
optionParser.allowsUnrecognizedOptions();
final OptionSpec<Void> version = optionParser.acceptsAll(Arrays.asList("version", "v"), "Display the Lantern version");
if (optionParser.parse(args).has(version)) {
final Package pack = Platform.class.getPackage();
logger.info(pack.getImplementationTitle() + ' ' + pack.getImplementationVersion());
logger.info(pack.getSpecificationTitle() + ' ' + pack.getSpecificationVersion());
return;
}
final OptionSpec<Void> help = optionParser.acceptsAll(Arrays.asList("help", "h", "?"), "Show this help text").forHelp();
// Initialize the injector
final LanternModule module = new LanternModule(logger, args, optionParser);
final Injector injector = Guice.createInjector(Stage.DEVELOPMENT, module);
logger.info("Instantiated the Injector in {} mode.", Environment.get().name().toLowerCase());
// Create the server instance
final LanternServer lanternServer = injector.getInstance(LanternServer.class);
// Initialize and start the server
lanternServer.initialize();
try {
final Field field = OptionParser.class.getDeclaredField("allowsUnrecognizedOptions");
field.setAccessible(true);
field.set(optionParser, false);
optionParser.parse(args);
} catch (OptionException e) {
logger.warn("Something went wrong while parsing options", e);
} catch (Exception e) {
logger.error("Unexpected error", e);
}
// annotations will be detected
if (optionParser.parse(args).has(help)) {
if (System.console() != null) {
// Terminal is (very likely) supported, use the terminal width provided by jline
final Terminal terminal = TerminalConsoleAppender.getTerminal();
if (terminal != null) {
optionParser.formatHelpWith(new BuiltinHelpFormatter(terminal.getWidth(), 3));
}
}
optionParser.printHelpOn(System.err);
return;
}
lanternServer.start();
} catch (Throwable t) {
logger.error("Error during server startup.", t);
System.exit(1);
}
}
use of org.lanternpowered.launch.LanternClassLoader in project LanternServer by LanternPowered.
the class LanternPluginManager method loadPlugin.
private void loadPlugin(PluginCandidate candidate) {
final String id = candidate.getId();
final LanternClassLoader classLoader = LanternClassLoader.get();
if (candidate.getSource().isPresent()) {
try {
classLoader.addBaseURL(candidate.getSource().get().toUri().toURL());
} catch (MalformedURLException e) {
throw new RuntimeException("Failed to add plugin '" + id + "' from " + candidate.getDisplaySource() + " to classpath", e);
}
}
final PluginMetadata metadata = candidate.getMetadata();
checkNotNull(metadata, "metadata");
final String name = firstNonNull(metadata.getName(), id);
final String version = firstNonNull(metadata.getVersion(), "unknown");
try {
final Class<?> pluginClass = Class.forName(candidate.getPluginClass());
final PluginContainer container = new LanternPluginContainer(id, this.injector, pluginClass, metadata, candidate.getSource().orElse(null));
registerPlugin(container);
registerPluginInstance(container);
this.eventManager.registerListeners(container, container.getInstance().get());
this.logger.info("Loaded plugin: {} {} (from {})", name, version, candidate.getDisplaySource());
} catch (Throwable e) {
this.logger.error("Failed to load plugin: {} {} (from {})", name, version, candidate.getDisplaySource(), e);
}
}
use of org.lanternpowered.launch.LanternClassLoader in project LanternServer by LanternPowered.
the class FastValueContainerCheckerClassVisitor method isCompositeValueStore0.
private static int isCompositeValueStore0(String className) {
// directly return true
if (className.equals(COMPOSITE_VALUE_STORE_NAME)) {
return 1;
} else if (className.equals(I_COMPOSITE_VALUE_STORE_NAME)) {
return 2;
// Don't process java packages
} else if (className.startsWith("java.")) {
return 0;
}
final LanternClassLoader classLoader = LanternClassLoader.get();
// If the class is already loaded, we might as well use it
final Class<?> c = classLoader.getLoadedClass(className.replace('/', '.')).orElse(null);
if (c != null) {
return ICompositeValueStore.class.isAssignableFrom(c) ? 2 : CompositeValueStore.class.isAssignableFrom(c) ? 1 : 0;
}
try {
// Read the bytecode of the class we need to analyze
final byte[] byteCode = classLoader.readByteCode(className);
// Also check for interfaces, super classes, etc.
final ClassReader classReader = new ClassReader(byteCode);
final FastValueContainerCheckerClassVisitor classVisitor = new FastValueContainerCheckerClassVisitor(null, false);
classReader.accept(classVisitor, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
return classVisitor.result;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
Aggregations