以jar的方式扫描包下的所有Class文件<br>
328571
private void doScanPackageClassesByJar(String basePackage, URL url,
                                           final boolean recursive, Set<Class<?>> classes) {
        String package2Path = basePackage.replace('.', '/');
        JarFile jar;
        try {
            jar = ((JarURLConnection) url.openConnection()).getJarFile();
            Enumeration<JarEntry> entries = jar.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String name = entry.getName();
                if (!name.startsWith(package2Path) || entry.isDirectory()) {
                    continue;
                }

                // 判断是否递归搜索子包
                if (!recursive
                        && name.lastIndexOf('/') != package2Path.length()) {
                    continue;
                }
                // 判断是否过滤 inner class
                if (this.excludeInner && name.indexOf('$') != -1) {
                    continue;
                }
                String classSimpleName = name.substring(name.lastIndexOf('/') + 1);
                // 判定是否符合过滤条件
                if (this.filterClassName(classSimpleName)) {
                    String className = name.replace('/', '.');
                    className = className.substring(0, className.length() - 6);
                    try {
                        classes.add(Thread.currentThread().getContextClassLoader().loadClass(className));
                    } catch (ClassNotFoundException e) {
                        throw new LtsRuntimeException(e);
                    }
                }
            }
        } catch (IOException e) {
            throw new LtsRuntimeException(e);
        }
    }
24290
public List<Class<?>> scanByFilter(String pack, List<ClassFilter> filters) {
        LOGGER.debug("开始扫描包{}下的所有类的集合", pack);
        // 第一个class类的集合
        List<Class<?>> classes = new ArrayList<>();
        // 获取包的名字 并进行替换
        String packageDirName = pack.replace('.', '/');
        // 定义一个枚举的集合 并进行循环来处理这个目录下的things
        Enumeration<URL> dirs;
        try {
            dirs = ClassUtils.getDefaultClassLoader().getResources(packageDirName);
        } catch (IOException e) {
            LOGGER.error("扫描包{}资源出错", packageDirName);
            throw new RuntimeException(e);
        }
        // 循环迭代下去
        while (dirs.hasMoreElements()) {
            try {
                // 获取下一个元素
                URL url = dirs.nextElement();
                // 得到协议的名称
                String protocol = url.getProtocol();
                // 如果是以文件的形式保存在服务器上
                if ("file".equals(protocol)) {
                    LOGGER.debug("file类型扫描");
                    // 获取包的物理路径
                    String filePath = URLDecoder.decode(url.getFile(),
                        Charset.defaultCharset().name());
                    // 以文件的方式扫描整个包下的文件 并添加到集合中
                    classes.addAll(findAndAddClassesInPackageByFile(pack, filePath, true));
                } else if ("jar".equals(protocol)) {
                    JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
                    classes
                        .addAll(findAndAddClassesInPackageByFile(jar, packageDirName, pack, true));
                }
            } catch (Throwable e) {
                LOGGER.debug("扫描{}时出错", pack, e);
            }
        }

        if (!filters.isEmpty()) {
            LOGGER.debug("扫描完毕，扫描出来的Class集合为：{}，发现过滤器，使用过滤器过滤", classes);
            classes = classes.stream().filter(clazz -> filter(clazz, filters))
                .collect(Collectors.toList());
            LOGGER.debug("过滤后的Class为：{}", classes);
        }

        return classes;
    }
365498
private void findFiles(File directory) throws IOException, ClassNotFoundException {

        File[] files = directory.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(".class");
            }
        });

        if (files != null) {
            for (File file : files) {
                int current = currentDirectoryPath.length();
                String fileName = file.getCanonicalPath().substring(++current);
                String className = fileName.replace(File.separatorChar, '.').substring(0, fileName.length() - 6);
                tryClass(className);
            }
        }
    }
1339478
protected final void loadAllClassByDir(String scriptLibDir) throws Exception {
		List<File> jarFiles = findJarFile(scriptLibDir);
		loadAllClass(jarFiles);
	}
862557
private static List<String> loadClasspathResource(String resource, ResourceLoader resourceLoader, String resourcePaths) throws IOException{
        List<String> result = new ArrayList<>();
        LOGGER.info("类路径资源："+resource);
        Enumeration<URL> ps = AutoDetector.class.getClassLoader().getResources(resource);
        while(ps.hasMoreElements()) {
            URL url=ps.nextElement();
            LOGGER.info("类路径资源URL："+url);
            if(url.getFile().contains(".jar!")){
                //加载jar资源
                result.addAll(load("classpath:"+resource));
                continue;
            }
            File file=new File(url.getFile());
            boolean dir = file.isDirectory();
            if(dir){
                //处理目录
                result.addAll(loadAndWatchDir(file.toPath(), resourceLoader, resourcePaths));
            }else{
                //处理文件
                result.addAll(load(file.getAbsolutePath()));
                //监控文件
                watchFile(file, resourceLoader, resourcePaths);
            }
        }
        return result;
    }
1075731
private void addJarClasses(final Path location) {
        try (final JarFile jarFile = new JarFile(location.toFile())) {
            final Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                final JarEntry entry = entries.nextElement();
                final String entryName = entry.getName();
                if (entryName.endsWith(".class"))
                    classes.add(toQualifiedClassName(entryName));
            }
        } catch (IOException e) {
            throw new IllegalArgumentException("Could not read jar-file '" + location + "', reason: " + e.getMessage());
        }
    }
64532
private ScriptClassLoader loadClassByLoader() throws Exception 
	{
		ScriptClassLoader newClassLoader = new ScriptClassLoader();
		Set<Class<?>> allClass = newClassLoader.findedClass;
		Set<Class<?>> fileClass=new HashSet<>();
		for(DirClassFile dcf:scriptSource.getDirClassFiles())
		{
			File file=new File(dcf.getRootDir().getFile());
			if(!file.exists())
			{
				continue;
			}
			newClassLoader.addURL(dcf.getRootDir());
			for(String className:dcf.getClassNames())
			{
				Class<?> clazz=newClassLoader.loadClass(className);
				if(clazz!=null)
				{
					fileClass.add(clazz);
				}
			}
		}
		Set<Class<?>> urlClass=new HashSet<>();
		for(URLClassFile ucf:scriptSource.getUrlClassFiles())
		{
			newClassLoader.addURL(ucf.getURL());
			Class<?> clazz=newClassLoader.loadClass(ucf.getClassName());
			if(clazz!=null)
			{
				urlClass.add(clazz);
			}
		}
		Set<Class<?>> jarClass=new HashSet<>();
		for(URL jar:scriptSource.getJars())
		{
			JarFile jarFile=null;
			try {
				File file=new File(jar.getFile());
				if(!file.exists())
				{
					continue;
				}
				jarFile=new JarFile(jar.getFile());
				Map<String, JarEntry>  map=FileUtil.findClassByJar(jarFile);
				if(!map.isEmpty())
				{
					newClassLoader.addURL(jar);
					for(String className:map.keySet())
					{
						Class<?> clazz=newClassLoader.loadClass(className);
						if(clazz!=null)
						{
							jarClass.add(clazz);
						}
					}
				}
			} finally {
				if(jarFile!=null)
				{
					jarFile.close();
				}
			}
		}
		allClass.addAll(fileClass);
		allClass.addAll(urlClass);
		allClass.addAll(jarClass);
		_log.debug("classloader init complete,allClass:"+allClass.size()+",fileClass:" + fileClass.size() + ",urlClass:" + urlClass.size() + ",jarClass:" + jarClass.size());
		return newClassLoader;
	}
1146733
public Set<Class<?>> findAndAddClassesInPackageByFile(String packageName, String packagePath,
                                                          final boolean recursive) {
        LOGGER.debug("扫描包{}下、目录{}下的所有class", packageName, packagePath);
        Set<Class<?>> classes = new LinkedHashSet<>();
        // 获取此包的目录 建立一个File
        File dir = new File(packagePath);
        // 如果不存在或者 也不是目录就直接返回
        if (!dir.exists() || !dir.isDirectory()) {
            LOGGER.debug("用户定义包名 " + packageName + " 下没有任何文件");
            return Collections.emptySet();
        }
        // 如果存在 就获取包下的所有文件 包括目录
        File[] dirfiles = dir.listFiles(file -> (recursive && file.isDirectory())
                                                || (file.getName().endsWith("" + "" + ".class")));

        if (dirfiles == null || dirfiles.length == 0) {
            return Collections.emptySet();
        }

        // 循环所有文件
        for (File file : dirfiles) {
            // 如果是目录 则继续扫描
            if (file.isDirectory()) {
                classes.addAll(findAndAddClassesInPackageByFile(packageName + "/" + file.getName(),
                    file.getAbsolutePath(), recursive));
            } else {
                // 如果是java类文件 去掉后面的.class 只留下类名
                String className = file.getName().substring(0, file.getName().length() - 6);
                try {
                    packageName = packageName.replaceAll("/", ".");
                    className = packageName + '.' + className;
                    classes.add(classLoader.loadClass(className));
                } catch (Throwable e) {
                    LOGGER.error("添加用户自定义视图类错误 找不到此类的.class文件", e);
                }
            }
        }
        return classes;
    }
156367
@Override
    public synchronized void onFileCreate(File file) {
        final Set<DetectedWebJar> listOfDetectedWebJarLib = isWebJar(file);
        if (listOfDetectedWebJarLib != null) {
            JarFile jar = null;
            try {
                jar = new JarFile(file);
                List<FileWebJarLib> installed = new ArrayList<>();
                for (DetectedWebJar detected : listOfDetectedWebJarLib) {
                    FileWebJarLib lib = expand(detected, jar);
                    if (lib != null) {
                        libs.add(lib);
                        installed.add(lib);
                        LOGGER.info("{} unpacked to {}", lib.name, lib.root.getAbsolutePath());
                    }
                }
                controller.addWebJarLibs(installed);
            } catch (IOException e) {
                LOGGER.error("Cannot open the jar file {}", file.getAbsolutePath(), e);
            } finally {
                IOUtils.closeQuietly(jar);
            }

        }
    }
975469
private void doScanPackageClassesByFile(Set<Class<?>> classes,
                                            String packageName, String packagePath, boolean recursive) {
        File dir = new File(packagePath);
        if (!dir.exists() || !dir.isDirectory()) {
            return;
        }
        final boolean fileRecursive = recursive;
        File[] dirfiles = dir.listFiles(new FileFilter() {
            // 自定义文件过滤规则
            public boolean accept(File file) {
                if (file.isDirectory()) {
                    return fileRecursive;
                }
                String filename = file.getName();
                return !(excludeInner && filename.indexOf('$') != -1) && filterClassName(filename);
            }
        });
        for (File file : dirfiles) {
            if (file.isDirectory()) {
                doScanPackageClassesByFile(classes, packageName + "."
                        + file.getName(), file.getAbsolutePath(), recursive);
            } else {
                String className = file.getName().substring(0,
                        file.getName().length() - 6);
                try {
                    classes.add(Thread.currentThread().getContextClassLoader()
                            .loadClass(packageName + '.' + className));

                } catch (ClassNotFoundException e) {
                    throw new LtsRuntimeException(e);
                }
            }
        }
    }
714118
private void jarDir(File dirOrFile2jar, JarOutputStream jos, String path)
		throws IOException {
		if (mVerbose) {
			System.out.println("checking " + dirOrFile2jar);
		}
		if (dirOrFile2jar.isDirectory()) {
			String[] dirList = dirOrFile2jar.list();
			String subPath = (path == null) ? "" : (path + dirOrFile2jar.getName() + SEP);
			if (path != null) {
				JarEntry je = new JarEntry(subPath);
				je.setTime(dirOrFile2jar.lastModified());
				jos.putNextEntry(je);
				jos.flush();
				jos.closeEntry();
			}
			for (int i = 0; i < dirList.length; i++) {
				File f = new File(dirOrFile2jar, dirList[i]);
				jarDir(f, jos, subPath);
			}
		} else if (dirOrFile2jar.exists()) {
			if (dirOrFile2jar.getCanonicalPath().equals(mDestJarName)) {
				if (mVerbose) {
					System.out.println("skipping " + dirOrFile2jar.getPath());
				}
				return;
			}

			if (mVerbose) {
				System.out.println("adding " + dirOrFile2jar.getPath());
			}
			FileInputStream fis = new FileInputStream(dirOrFile2jar);
			try {
				JarEntry entry = new JarEntry(path + dirOrFile2jar.getName());
				entry.setTime(dirOrFile2jar.lastModified());
				jos.putNextEntry(entry);
				while ((mByteCount = fis.read(mBuffer)) != -1) {
					jos.write(mBuffer, 0, mByteCount);
					if (mVerbose) {
						System.out.println("wrote " + mByteCount + " bytes");
					}
				}
				jos.flush();
				jos.closeEntry();
			} catch (IOException ioe) {
				throw ioe;
			} finally {
				fis.close();
			}
		}
	}
961565
public static List<Class<?>> getComponentClasses(URL jar) throws IOException {
        JarInputStream jarFile = new JarInputStream(jar.openStream());
        URLClassLoader cl = new URLClassLoader(new URL[]{jar}, Thread.currentThread().getContextClassLoader());
        List<Class<?>> idx = new ArrayList<Class<?>>();

        JarEntry jarEntry = jarFile.getNextJarEntry();
        while (jarEntry != null) {
            String classname = jarEntry.getName();
//            System.out.println(classname);
            if (classname.endsWith(".class")) {
                classname = classname.substring(0, classname.indexOf(".class")).replace('/', '.');
                try {
                    Class<?> c = Class.forName(classname, false, cl);
                    for (Method method : c.getMethods()) {
                        if ((method.getAnnotation(Execute.class)) != null) {
                            idx.add(c);
                            break;
                        }
                    }
                } catch (ClassNotFoundException ex) {
                    ex.printStackTrace();
                }
            }
            jarEntry = jarFile.getNextJarEntry();
        }
        jarFile.close();
        return idx;
    }
853837
private void scan(List<File> files, List<T> factories) {
    for (File jar : files) {
      try {
        URL extensionURL = jar.toURI().toURL();
        String jarPath = extensionURL.toString();

        ClassLoader extensionsClassLoader = new ExtensionsClassLoader(new URL[] {extensionURL},
            ClassLoader.getSystemClassLoader());
        ServiceLoader<T> extensionServiceLoader =
            ServiceLoader.load(mFactoryClass, extensionsClassLoader);
        for (T factory : extensionServiceLoader) {
          LOG.debug("Discovered a factory implementation {} - {} in jar {}", factory.getClass(),
              factory, jarPath);
          register(factory, factories);
        }
      } catch (Throwable t) {
        LOG.warn("Failed to load jar {}: {}", jar, t.toString());
      }
    }
  }
205184
public Set<Class<?>> scan() {
		for (URL url : ResourceUtil.getResourceIter(this.packagePath)) {
			switch (url.getProtocol()) {
			case "file":
				scanFile(new File(URLUtil.decode(url.getFile(), this.charset.name())), null);
				break;
			case "jar":
				scanJar(URLUtil.getJarFile(url));
				break;
			}
		}
		
		if(CollUtil.isEmpty(this.classes)) {
			scanJavaClassPaths();
		}
		
		return Collections.unmodifiableSet(this.classes);
	}
1318842
public static List<String> listFileNames(String path) throws IORuntimeException {
		if (path == null) {
			return null;
		}
		List<String> paths = new ArrayList<String>();

		int index = path.lastIndexOf(FileUtil.JAR_PATH_EXT);
		if (index == -1) {
			// 普通目录路径
			File[] files = ls(path);
			for (File file : files) {
				if (file.isFile()) {
					paths.add(file.getName());
				}
			}
		} else {
			// jar文件
			path = getAbsolutePath(path);
			if (false == StrUtil.endWith(path, UNIX_SEPARATOR)) {
				path = path + UNIX_SEPARATOR;
			}
			// jar文件中的路径
			index = index + FileUtil.JAR_FILE_EXT.length();
			JarFile jarFile = null;
			try {
				jarFile = new JarFile(path.substring(0, index));
				final String subPath = path.substring(index + 2);
				for (JarEntry entry : Collections.list(jarFile.entries())) {
					final String name = entry.getName();
					if (name.startsWith(subPath)) {
						final String nameSuffix = StrUtil.removePrefix(name, subPath);
						if (false == StrUtil.contains(nameSuffix, UNIX_SEPARATOR)) {
							paths.add(nameSuffix);
						}
					}
				}
			} catch (IOException e) {
				throw new IORuntimeException(StrUtil.format("Can not read file path of [{}]", path), e);
			} finally {
				IoUtil.close(jarFile);
			}
		}
		return paths;
	}
1370966
private URL findJarForResource(URL url) {
        // 如果URL的文件部分本身是一个URL，那么该URL可能指向JAR
        try {
            long startTime = System.currentTimeMillis();
            while (true) {
                url = new URL(url.getFile());
                if (System.currentTimeMillis() - startTime > MAX_LIMIT) {
                    break;
                }
            }
        } catch (MalformedURLException expected) {
            // This will happen at some point and serves as a break in the loop
        }

        // Look for the .jar extension and chop off everything after that
        StringBuilder jarUrl = new StringBuilder(url.toExternalForm());
        int index = jarUrl.lastIndexOf(".jar");
        if (index >= 0) {
            jarUrl.setLength(index + 4);
        } else {
            return null;
        }

        // Try to open and test it
        try {
            URL testUrl = new URL(jarUrl.toString());
            if (this.isJar(testUrl)) {
                return testUrl;
            }

            // WebLogic fix: check if the URL's file exists in the filesystem.
            jarUrl.replace(0, jarUrl.length(), testUrl.getFile());
            File file = new File(jarUrl.toString());

            // File name might be URL-encoded
            if (!file.exists()) {
                file = new File(URLEncoder.encode(jarUrl.toString(), "UTF-8"));
            }

            if (file.exists()) {
                testUrl = file.toURI().toURL();
                if (isJar(testUrl)) {
                    return testUrl;
                }
            }
        } catch (MalformedURLException e) {
            log.warn("Invalid JAR URL: " + jarUrl);
        } catch (UnsupportedEncodingException e) {
            throw new ZealotException("Unsupported encoding?  UTF-8?  That's unpossible.");
        }

        return null;
    }
1288141
static String [] searchJarFSForClasses( URL url ) throws IOException {
        try {
            try {
                FileSystems.newFileSystem(url.toURI(), new HashMap<>());
            } catch (FileSystemAlreadyExistsException e) { /* ignore */ }

            Path path = FileSystems.getFileSystem(url.toURI()).getPath("/");

            return Files.walk(path).map(Path::toString)
                    .filter(BshClassPath::isClassFileName)
                    .map(BshClassPath::canonicalizeClassName)
                    .toArray(String[]::new);
        } catch (URISyntaxException e) { /* ignore */ }
        return new String[0];
    }