Search in sources :

Example 1 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class ClassDiscovery method discover.

/**
 * Does the class discovery for this particular URL. This should only be called by doDiscovery. Other internal
 * methods should call doDiscovery, which handles looking through the dirtyURLs.
 */
private synchronized void discover(URL rootLocation) {
    long start = System.currentTimeMillis();
    if (debug) {
        StreamUtils.GetSystemOut().println("Beginning discovery of " + rootLocation);
    }
    try {
        // If the ClassDiscoveryCache is set, just use this.
        if (classDiscoveryCache != null) {
            ClassDiscoveryURLCache cduc = classDiscoveryCache.getURLCache(rootLocation);
            preCaches.put(rootLocation, cduc);
        }
        String url;
        try {
            url = URLDecoder.decode(rootLocation.toString(), "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            // apparently this should never happen, but we have to catch it anyway
            url = null;
        }
        if (url == null) {
            url = GetClassContainer(ClassDiscovery.class).toString();
        }
        final File rootLocationFile;
        if (!classCache.containsKey(rootLocation)) {
            classCache.put(rootLocation, Collections.synchronizedSet(new HashSet<>()));
        } else {
            classCache.get(rootLocation).clear();
        }
        final Set<ClassMirror<?>> mirrors = classCache.get(rootLocation);
        if (preCaches.containsKey(rootLocation)) {
            if (debug) {
                StreamUtils.GetSystemOut().println("Precache already contains this URL, so using it");
            }
            // No need, already got a cache for this url
            mirrors.addAll(preCaches.get(rootLocation).getClasses());
            return;
        }
        if (debug) {
            StreamUtils.GetSystemOut().println("Precache does not contain data for this URL, so scanning now.");
        }
        url = url.replaceFirst("^jar:", "");
        if (url.endsWith("!/")) {
            url = StringUtils.replaceLast(url, "!/", "");
        }
        if (url.startsWith("file:") && !url.endsWith(".jar")) {
            final AtomicInteger id = new AtomicInteger(0);
            // ExecutorService service = Executors.newFixedThreadPool(10, new ThreadFactory() {
            // @Override
            // public Thread newThread(Runnable r) {
            // return new Thread(r, "ClassDiscovery-Async-" + id.incrementAndGet());
            // }
            // });
            // Remove file: from the front
            String root = url.substring(5);
            rootLocationFile = new File(root);
            List<File> fileList = new ArrayList<>();
            descend(new File(root), fileList);
            // to all of them. We have to first remove the "front" part
            for (File f : fileList) {
                String file = f.toString();
                if (!file.matches(".*\\$(?:\\d)*\\.class") && file.endsWith(".class")) {
                    InputStream stream = null;
                    try {
                        stream = FileUtil.readAsStream(new File(rootLocationFile, f.getAbsolutePath().replaceFirst(Pattern.quote(new File(root).getAbsolutePath() + File.separator), "")));
                        ClassReader reader = new ClassReader(stream);
                        ClassMirrorVisitor mirrorVisitor = new ClassMirrorVisitor();
                        reader.accept(mirrorVisitor, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
                        mirrors.add(mirrorVisitor.getMirror(new URL(url)));
                    } catch (IOException ex) {
                        Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        if (stream != null) {
                            try {
                                stream.close();
                            } catch (IOException ex) {
                                Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    }
                }
            }
        // service.shutdown();
        // try {
        // //Doesn't look like 0 is an option, so we'll just wait a day.
        // service.awaitTermination(1, TimeUnit.DAYS);
        // } catch (InterruptedException ex) {
        // Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
        // }
        } else if (url.startsWith("file:") && url.endsWith(".jar")) {
            // We are running from a jar
            url = url.replaceFirst("file:", "");
            rootLocationFile = new File(url);
            ZipIterator zi = new ZipIterator(rootLocationFile);
            try {
                zi.iterate(new ZipIterator.ZipIteratorCallback() {

                    @Override
                    public void handle(String filename, InputStream in) {
                        if (!filename.matches(".*\\$(?:\\d)*\\.class") && filename.endsWith(".class")) {
                            try {
                                ClassReader reader = new ClassReader(in);
                                ClassMirrorVisitor mirrorVisitor = new ClassMirrorVisitor();
                                reader.accept(mirrorVisitor, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
                                mirrors.add(mirrorVisitor.getMirror(rootLocationFile.toURI().toURL()));
                            } catch (IOException ex) {
                                Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    }
                }, progressIterator);
            } catch (IOException ex) {
                Logger.getLogger(ClassDiscovery.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            throw new RuntimeException("Unknown url type: " + rootLocation);
        }
    } catch (RuntimeException e) {
        e.printStackTrace(System.err);
    } finally {
        if (debug) {
            StreamUtils.GetSystemOut().println("Scans finished for " + rootLocation + ", taking " + (System.currentTimeMillis() - start) + " ms.");
        }
    }
}
Also used : ZipIterator(com.laytonsmith.PureUtilities.ZipIterator) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ClassMirrorVisitor(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirrorVisitor) IOException(java.io.IOException) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) URL(java.net.URL) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ClassReader(org.objectweb.asm.ClassReader) File(java.io.File) HashSet(java.util.HashSet)

Example 2 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class AnnotationChecks method checkForTypeInTypeofClasses.

public static void checkForTypeInTypeofClasses() throws Exception {
    Set<ClassMirror<?>> classes = ClassDiscovery.getDefaultInstance().getClassesWithAnnotation(typeof.class);
    Set<String> errors = new HashSet<>();
    for (ClassMirror<?> clazz : classes) {
        try {
            // Make sure that TYPE has the same type as the typeof annotation
            CClassType TYPE = (CClassType) ReflectionUtils.get(clazz.loadClass(), "TYPE");
            if (TYPE == null) {
                errors.add("TYPE is null? " + clazz.getClassName());
                continue;
            }
            if (!TYPE.val().equals(clazz.getAnnotation(typeof.class).getValue("value"))) {
                errors.add(clazz.getClassName() + "'s TYPE value is different than the typeof annotation on it");
            }
        } catch (ReflectionUtils.ReflectionException ex) {
            errors.add(clazz.getClassName() + " needs to add the following:\n\t@SuppressWarnings(\"FieldNameHidesFieldInSuperclass\")\n" + "\tpublic static final CClassType TYPE = CClassType.get(\"" + clazz.getAnnotation(typeof.class).getValue("value") + "\");");
        }
    }
    if (!errors.isEmpty()) {
        throw new Exception("\n" + StringUtils.Join(errors, "\n"));
    }
}
Also used : CClassType(com.laytonsmith.core.constructs.CClassType) ReflectionUtils(com.laytonsmith.PureUtilities.Common.ReflectionUtils) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) com.laytonsmith.annotations.typeof(com.laytonsmith.annotations.typeof) HashSet(java.util.HashSet)

Example 3 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class CheckOverrides method setup.

private static void setup() {
    if (methods == null) {
        methods = new HashMap<>();
        List<ClassMirror<?>> classes = ClassDiscovery.getDefaultInstance().getKnownClasses(ClassDiscovery.GetClassContainer(CheckOverrides.class));
        for (ClassMirror cm : classes) {
            Class c = cm.loadClass(CheckOverrides.class.getClassLoader(), false);
            if (c.isInterface()) {
                continue;
            }
            Set<Method> mm = getPotentiallyOverridingMethods(c);
            if (!mm.isEmpty()) {
                methods.put(c, mm);
            }
        }
    }
}
Also used : Method(java.lang.reflect.Method) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror)

Example 4 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class ExtensionManager method Cache.

public static void Cache(File extCache, Class... extraClasses) {
    // We will only cache on Windows, as Linux doesn't natively lock
    // files that are in use. Windows prevents any modification, making
    // it harder for server owners on Windows to update the jars.
    boolean onWindows = (OSUtils.GetOS() == OSUtils.OS.WINDOWS);
    if (!onWindows) {
        return;
    }
    // Create the directory if it doesn't exist.
    extCache.mkdirs();
    // cleanup wasn't successful on the last run.
    for (File f : extCache.listFiles()) {
        try {
            Files.delete(f.toPath());
        } catch (IOException ex) {
            Static.getLogger().log(Level.WARNING, "[CommandHelper] Could not delete loose file " + f.getAbsolutePath() + ": " + ex.getMessage());
        }
    }
    // The cache, cd and dcl here will just be thrown away.
    // They are only used here for the purposes of discovering what a given
    // jar has to offer.
    ClassDiscoveryCache cache = new ClassDiscoveryCache(CommandHelperFileLocations.getDefault().getCacheDirectory());
    cache.setLogger(Static.getLogger());
    DynamicClassLoader dcl = new DynamicClassLoader();
    ClassDiscovery cd = new ClassDiscovery();
    cd.setClassDiscoveryCache(cache);
    cd.addDiscoveryLocation(ClassDiscovery.GetClassContainer(ExtensionManager.class));
    for (Class klazz : extraClasses) {
        cd.addDiscoveryLocation(ClassDiscovery.GetClassContainer(klazz));
    }
    // Look in the given locations for jars, add them to our class discovery.
    List<File> toProcess = new ArrayList<>();
    for (File location : locations) {
        toProcess.addAll(getFiles(location));
    }
    // Load the files into the discovery mechanism.
    for (File file : toProcess) {
        if (!file.canRead()) {
            continue;
        }
        URL jar;
        try {
            jar = file.toURI().toURL();
        } catch (MalformedURLException ex) {
            Static.getLogger().log(Level.SEVERE, null, ex);
            continue;
        }
        dcl.addJar(jar);
        cd.addDiscoveryLocation(jar);
    }
    cd.setDefaultClassLoader(dcl);
    // Loop thru the found lifecycles, copy them to the cache using the name
    // given in the lifecycle. If more than one jar has the same internal
    // name, the filename will be given a number.
    Set<File> done = new HashSet<>();
    Map<String, Integer> namecount = new HashMap<>();
    // use their internal name.
    for (ClassMirror<? extends AbstractExtension> extmirror : cd.getClassesWithAnnotationThatExtend(MSExtension.class, AbstractExtension.class)) {
        if (extmirror.equals(new ClassMirror<>(AbstractExtension.class))) {
            continue;
        }
        AnnotationMirror plug = extmirror.getAnnotation(MSExtension.class);
        URL plugURL = extmirror.getContainer();
        // Get the internal name that this extension exposes.
        if (plugURL != null && plugURL.getPath().endsWith(".jar")) {
            File f;
            try {
                f = new File(URLDecoder.decode(plugURL.getFile(), "UTF8"));
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(ExtensionManager.class.getName()).log(Level.SEVERE, null, ex);
                continue;
            }
            // Skip extensions that originate from commandhelpercore.
            if (plugURL.equals(ClassDiscovery.GetClassContainer(ExtensionManager.class))) {
                done.add(f);
                continue;
            }
            // Skip files already processed.
            if (done.contains(f)) {
                CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.WARNING, f.getAbsolutePath() + " contains more than one extension" + " descriptor. Bug someone about it!", Target.UNKNOWN);
                continue;
            }
            done.add(f);
            String name = plug.getValue("value").toString();
            // lets track and rename them using a number scheme.
            if (namecount.containsKey(name.toLowerCase())) {
                int i = namecount.get(name.toLowerCase());
                name += "-" + i;
                namecount.put(name.toLowerCase(), i++);
                CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.WARNING, f.getAbsolutePath() + " contains a duplicate internally" + " named extension (" + name + "). Bug someone" + " about it!", Target.UNKNOWN);
            } else {
                namecount.put(name.toLowerCase(), 1);
            }
            // Rename the jar to use the plugin's internal name and
            // copy it into the cache.
            File newFile = new File(extCache, name.toLowerCase() + ".jar");
            try {
                Files.copy(f.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException ex) {
                Static.getLogger().log(Level.SEVERE, "Could not copy '" + f.getName() + "' to cache: " + ex.getMessage());
            }
        }
    }
    Set<ClassMirror<?>> classes = cd.getClassesWithAnnotation(api.class);
    // Now process @api annotated extensions, ignoring ones already processed.
    for (ClassMirror klass : classes) {
        URL plugURL = klass.getContainer();
        if (plugURL != null && plugURL.getPath().endsWith(".jar")) {
            File f;
            try {
                f = new File(URLDecoder.decode(plugURL.getFile(), "UTF8"));
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(ExtensionManager.class.getName()).log(Level.SEVERE, null, ex);
                continue;
            }
            // Skip files already processed.
            if (done.contains(f)) {
                continue;
            }
            // No special processing needed.
            if (cd.doesClassExtend(klass, Event.class) || cd.doesClassExtend(klass, Function.class)) {
                // We're processing it here instead of above, complain about it.
                CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.WARNING, f.getAbsolutePath() + " is an old-style extension!" + " Bug the author to update it to the new extension system!", Target.UNKNOWN);
                // Only process this file once.
                done.add(f);
                File newFile = new File(extCache, "oldstyle-" + f.getName());
                try {
                    Files.copy(f.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                } catch (IOException ex) {
                    Static.getLogger().log(Level.SEVERE, "Could not copy '" + f.getName() + "' to cache: " + ex.getMessage());
                }
            }
        }
    }
    // Shut down the original dcl to "unlock" the processed jars.
    // The cache and cd instances will just fall into oblivion.
    dcl.destroy();
    // Explicit call. Without this, jar files won't actually get unlocked on
    // Windows. Of course, this is hit and miss, but that's fine; we tried.
    System.gc();
}
Also used : DynamicClassLoader(com.laytonsmith.PureUtilities.ClassLoading.DynamicClassLoader) MalformedURLException(java.net.MalformedURLException) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) URL(java.net.URL) CFunction(com.laytonsmith.core.constructs.CFunction) Function(com.laytonsmith.core.functions.Function) HashSet(java.util.HashSet) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) ClassDiscovery(com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery) AnnotationMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.AnnotationMirror) Event(com.laytonsmith.core.events.Event) File(java.io.File) ClassDiscoveryCache(com.laytonsmith.PureUtilities.ClassLoading.ClassDiscoveryCache)

Example 5 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class ExtensionManager method Initialize.

/**
 * Initializes the extension manager. This operation is not necessarily required, and must be guaranteed to not run
 * more than once per ClassDiscovery object.
 *
 * @param cd the ClassDiscovery to use for loading files.
 */
public static void Initialize(ClassDiscovery cd) {
    extensions.clear();
    // Look in the extension folder for jars, add them to our class discover,
    // then initialize everything
    List<File> toProcess = new ArrayList<>();
    // Grab files from the cache if on Windows. Otherwise just load
    // directly from the stored locations.
    boolean onWindows = (OSUtils.GetOS() == OSUtils.OS.WINDOWS);
    if (onWindows) {
        toProcess.addAll(getFiles(CommandHelperFileLocations.getDefault().getExtensionCacheDirectory()));
    } else {
        for (File location : locations) {
            toProcess.addAll(getFiles(location));
        }
    }
    DynamicClassLoader dcl = new DynamicClassLoader();
    cd.setDefaultClassLoader(dcl);
    for (File f : toProcess) {
        if (f.getName().endsWith(".jar")) {
            try {
                // First, load it with our custom class loader
                URL jar = f.toURI().toURL();
                dcl.addJar(jar);
                cd.addDiscoveryLocation(jar);
                CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.DEBUG, "Loaded " + f.getAbsolutePath(), Target.UNKNOWN);
            } catch (MalformedURLException ex) {
                Static.getLogger().log(Level.SEVERE, null, ex);
            }
        }
    }
    // one found defines the internal name.
    for (ClassMirror<? extends AbstractExtension> extmirror : cd.getClassesWithAnnotationThatExtend(MSExtension.class, AbstractExtension.class)) {
        if (extmirror.equals(new ClassMirror<>(AbstractExtension.class))) {
            continue;
        }
        Extension ext;
        URL url = extmirror.getContainer();
        Class<? extends AbstractExtension> extcls;
        if (extmirror.getModifiers().isAbstract()) {
            Static.getLogger().log(Level.SEVERE, "Probably won't be able to" + " instantiate " + extmirror.getClassName() + ": The" + " class is marked as abstract! Will try anyway.");
        }
        try {
            extcls = extmirror.loadClass(dcl, true);
        } catch (Throwable ex) {
            // May throw anything, and kill the loading process.
            // Lets prevent that!
            Static.getLogger().log(Level.SEVERE, "Could not load class '" + extmirror.getClassName() + "'");
            ex.printStackTrace();
            continue;
        }
        try {
            ext = extcls.newInstance();
        } catch (InstantiationException | IllegalAccessException ex) {
            // Error, but skip this one, don't throw an exception ourselves, just log it.
            Static.getLogger().log(Level.SEVERE, "Could not instantiate " + extcls.getName() + ": " + ex.getMessage());
            continue;
        }
        ExtensionTracker trk = extensions.get(url);
        if (trk == null) {
            trk = new ExtensionTracker(url, cd, dcl);
            extensions.put(url, trk);
        }
        // use it.
        if (trk.identifier == null) {
            trk.identifier = ext.getName();
            try {
                trk.version = ext.getVersion();
            } catch (AbstractMethodError ex) {
                // getVersion() was added later. This is a temporary fix
                // to allow extension authors some time to update.
                // TODO: Remove this soon.
                trk.version = new SimpleVersion("0.0.0");
            }
        }
        trk.allExtensions.add(ext);
    }
    // Lets store info about the functions and events extensions have.
    // This will aide in gracefully unloading stuff later.
    Set<ClassMirror<?>> classes = cd.getClassesWithAnnotation(api.class);
    // Temp tracking for loading messages later on.
    List<String> events = new ArrayList<>();
    List<String> functions = new ArrayList<>();
    // and store the instances in their trackers.
    for (ClassMirror klass : classes) {
        URL url = klass.getContainer();
        if (cd.doesClassExtend(klass, Event.class) || cd.doesClassExtend(klass, Function.class)) {
            Class c;
            try {
                c = klass.loadClass(dcl, true);
            } catch (Throwable ex) {
                // May throw anything, and kill the loading process.
                // Lets prevent that!
                Static.getLogger().log(Level.SEVERE, "Could not load class '" + klass.getClassName() + "'");
                ex.printStackTrace();
                continue;
            }
            ExtensionTracker trk = extensions.get(url);
            if (trk == null) {
                trk = new ExtensionTracker(url, cd, dcl);
                extensions.put(url, trk);
            }
            // Instantiate, register and store.
            try {
                if (Event.class.isAssignableFrom(c)) {
                    Class<Event> cls = (Class<Event>) c;
                    if (klass.getModifiers().isAbstract()) {
                        // Abstract? Looks like they accidently @api'd
                        // a cheater class. We can't be sure that it is fully
                        // defined, so complain to the console.
                        CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.ERROR, "Class " + c.getName() + " in " + url + " is" + " marked as an event but is also abstract." + " Bugs might occur! Bug someone about this!", Target.UNKNOWN);
                    }
                    Event e = cls.newInstance();
                    events.add(e.getName());
                    trk.registerEvent(e);
                } else if (Function.class.isAssignableFrom(c)) {
                    Class<Function> cls = (Class<Function>) c;
                    if (klass.getModifiers().isAbstract()) {
                        // Abstract? Looks like they accidently @api'd
                        // a cheater class. We can't be sure that it is fully
                        // defined, so complain to the console.
                        CHLog.GetLogger().Log(CHLog.Tags.EXTENSIONS, LogLevel.ERROR, "Class " + c.getName() + " in " + url + " is" + " marked as a function but is also abstract." + " Bugs might occur! Bug someone about this!", Target.UNKNOWN);
                    }
                    Function f = cls.newInstance();
                    functions.add(f.getName());
                    trk.registerFunction(f);
                }
            } catch (InstantiationException ex) {
                Static.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
            } catch (IllegalAccessException ex) {
                Static.getLogger().log(Level.SEVERE, null, ex);
            }
        }
    }
    // Lets print out the details to the console, if we are in debug mode.
    try {
        if (Prefs.DebugMode()) {
            Collections.sort(events);
            String eventString = StringUtils.Join(events, ", ", ", and ", " and ");
            Collections.sort(functions);
            String functionString = StringUtils.Join(functions, ", ", ", and ", " and ");
            StreamUtils.GetSystemOut().println(Implementation.GetServerType().getBranding() + ": Loaded the following functions: " + functionString.trim());
            StreamUtils.GetSystemOut().println(Implementation.GetServerType().getBranding() + ": Loaded " + functions.size() + " function" + (functions.size() == 1 ? "." : "s."));
            StreamUtils.GetSystemOut().println(Implementation.GetServerType().getBranding() + ": Loaded the following events: " + eventString.trim());
            StreamUtils.GetSystemOut().println(Implementation.GetServerType().getBranding() + ": Loaded " + events.size() + " event" + (events.size() == 1 ? "." : "s."));
        }
    } catch (Throwable e) {
    // Prefs weren't loaded, probably caused by running tests.
    }
}
Also used : DynamicClassLoader(com.laytonsmith.PureUtilities.ClassLoading.DynamicClassLoader) MalformedURLException(java.net.MalformedURLException) ArrayList(java.util.ArrayList) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) URL(java.net.URL) CFunction(com.laytonsmith.core.constructs.CFunction) Function(com.laytonsmith.core.functions.Function) SimpleVersion(com.laytonsmith.PureUtilities.SimpleVersion) Event(com.laytonsmith.core.events.Event) File(java.io.File)

Aggregations

ClassMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror)9 HashSet (java.util.HashSet)6 ArrayList (java.util.ArrayList)5 URL (java.net.URL)4 File (java.io.File)3 Method (java.lang.reflect.Method)3 DynamicClassLoader (com.laytonsmith.PureUtilities.ClassLoading.DynamicClassLoader)2 CFunction (com.laytonsmith.core.constructs.CFunction)2 Event (com.laytonsmith.core.events.Event)2 Function (com.laytonsmith.core.functions.Function)2 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 MalformedURLException (java.net.MalformedURLException)2 ClassDiscovery (com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery)1 ClassDiscoveryCache (com.laytonsmith.PureUtilities.ClassLoading.ClassDiscoveryCache)1 AnnotationMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.AnnotationMirror)1 ClassMirrorVisitor (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirrorVisitor)1 FieldMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.FieldMirror)1 MethodMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.MethodMirror)1 ReflectionUtils (com.laytonsmith.PureUtilities.Common.ReflectionUtils)1