package io.lumify.core.bootstrap.lib; import io.lumify.core.config.Configuration; import io.lumify.core.exception.LumifyException; import io.lumify.core.util.ClassUtil; import io.lumify.core.util.LumifyLogger; import io.lumify.core.util.LumifyLoggerFactory; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.List; public abstract class LibLoader { private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(LibLoader.class); private static List<File> loadedLibFiles = new ArrayList<>(); public abstract void loadLibs(Configuration configuration); protected static void addLibDirectory(File directory) { if (!directory.exists()) { throw new LumifyException(String.format("Could not add lib directory %s. Directory not found.", directory.getAbsolutePath())); } if (!directory.isDirectory()) { throw new LumifyException(String.format("Could not add lib directory %s. Not a directory.", directory.getAbsolutePath())); } File[] files = directory.listFiles(); if (files == null) { throw new LumifyException(String.format("Could not list files of directory %s", directory.getAbsolutePath())); } for (File f : files) { if (f.getName().startsWith(".") || f.isHidden()) { continue; } if (f.isDirectory()) { addLibDirectory(f); continue; } if (f.getName().toLowerCase().endsWith(".jar")) { addLibFile(f); } } } protected static void addLibFile(File f) { if (!f.exists()) { throw new LumifyException(String.format("Could not add lib %s. File not found.", f.getAbsolutePath())); } if (!f.isFile()) { throw new LumifyException(String.format("Could not add lib %s. Not a file.", f.getAbsolutePath())); } for (File loadedLibFile : loadedLibFiles) { if (loadedLibFile.getName().equals(f.getName())) { LOGGER.info("Skipping %s. File with same name already loaded from %s", f.getAbsolutePath(), loadedLibFile.getAbsolutePath()); return; } } LOGGER.info("adding lib: %s", f.getAbsolutePath()); loadedLibFiles.add(f); ClassLoader classLoader = LibLoader.class.getClassLoader(); while (classLoader != null) { if (tryAddUrl(classLoader, f)) { return; } classLoader = classLoader.getParent(); } if (tryAddUrl(ClassLoader.getSystemClassLoader(), f)) { return; } throw new LumifyException("Could not add file to classloader"); } private static boolean tryAddUrl(ClassLoader classLoader, File f) { Class<? extends ClassLoader> classLoaderClass = classLoader.getClass(); try { Class[] parameters = new Class[]{URL.class}; Method method = ClassUtil.findMethod(classLoaderClass, "addURL", parameters); if (method == null) { LOGGER.debug("Could not find addURL on classloader: %s", classLoaderClass.getName()); return false; } method.setAccessible(true); method.invoke(classLoader, f.toURI().toURL()); LOGGER.debug("added %s to classLoader %s", f.getAbsolutePath(), classLoader.getClass().getName()); return true; } catch (Throwable t) { LOGGER.error("Error, could not add URL " + f.getAbsolutePath() + " to classloader: " + classLoaderClass.getName(), t); return false; } } public static List<File> getLoadedLibFiles() { return loadedLibFiles; } }