- 浏览: 66603 次
- 性别:
- 来自: 杭州
最新评论
-
meimei_123abc:
你好,可以把这个完整的代码给我发一个学习下吗,刚开始接触这一块 ...
在JNI中调用本地带结构体参数的函数 -
yangdong:
sorry,之后一直没再碰过 JNI,没法再写了。
在JNI中调用本地带结构体参数的函数 -
ihopethatwell:
楼主,能写一个传递数组的结构体?
在JNI中调用本地带结构体参数的函数 -
yangdong:
谢谢。我只是追求形似,所以找不到对应的写法。
Stream in Clojure -
jamesqiu:
Clojure的lazy-cat和Scala的Stream实现 ...
Stream in Clojure
Java 中缺乏内建的类路径扫描机制。但是这个机制对于做框架的人来说很常用。下面的工具类从类路径下面的文件或者 JAR 路径中扫描包,可以实现我们需要的功能。实现是基于 Spring 3.1.11.RELEASE 版的 PathMatchingResourcePatternResolver 修改的。去掉了原版中 ANT * 号匹配的功能。依赖 Google Guava, Apache Commons Collections 4, Apache Commons Lang。
这个实现的大概思路是
1. 先根据包名构建一个路径("." 换成 "/")
2. 用类加载器去加载这个路径对应的资源,得到一个 URL
3. 如果 URL 对应的是 JAR,扫描 JAR(非递归扫描)
4. 如果 URL 是文件系统,扫描文件系统(递归扫描)
3. 4., 一个递归一个非递归,主要原因是 JAR 对应的 API 返回的文件列表是展开的,所以我们不需要递归展开了。
比如有意思的是 2. 这一步。如果路径是空字符串 "",那么
1. 在 maven 下或者 IDE 下直接运行。得到的 URL 在文件系统下是 classes、test-classes 这些
2. 用 java -jar xxx.jar 运行。得到的 URL 是空的。但如果不传空字符串,传 com.xxx.app 就可以加载到资源
所以这个工具类的使用需要注意一点。如果你想让这个工具类在打成 JAR 包之后还能正常用,那么参数 basePackages 这里至少添上一个 com.xxx.app 之类的东西。
这个实现的大概思路是
1. 先根据包名构建一个路径("." 换成 "/")
2. 用类加载器去加载这个路径对应的资源,得到一个 URL
3. 如果 URL 对应的是 JAR,扫描 JAR(非递归扫描)
4. 如果 URL 是文件系统,扫描文件系统(递归扫描)
3. 4., 一个递归一个非递归,主要原因是 JAR 对应的 API 返回的文件列表是展开的,所以我们不需要递归展开了。
比如有意思的是 2. 这一步。如果路径是空字符串 "",那么
1. 在 maven 下或者 IDE 下直接运行。得到的 URL 在文件系统下是 classes、test-classes 这些
2. 用 java -jar xxx.jar 运行。得到的 URL 是空的。但如果不传空字符串,传 com.xxx.app 就可以加载到资源
所以这个工具类的使用需要注意一点。如果你想让这个工具类在打成 JAR 包之后还能正常用,那么参数 basePackages 这里至少添上一个 com.xxx.app 之类的东西。
import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.apache.commons.collections4.EnumerationUtils; import org.apache.commons.lang.StringUtils; import java.io.File; import java.io.IOException; import java.net.*; import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * 反射工具。实现是基于 Spring 3.1.11.RELEASE 版的 PathMatchingResourcePatternResolver 修改的。 * * @author fanshen * @since 2015/7/7 */ public class ReflectionUtils { private ReflectionUtils() { } /** * URL protocol for an entry from a jar file: "jar" */ private static final String URL_PROTOCOL_JAR = "jar"; /** * URL protocol for an entry from a zip file: "zip" */ private static final String URL_PROTOCOL_ZIP = "zip"; /** * URL protocol for an entry from a WebSphere jar file: "wsjar" */ private static final String URL_PROTOCOL_WSJAR = "wsjar"; /** * URL protocol for an entry from a JBoss jar file: "vfszip" */ private static final String URL_PROTOCOL_VFSZIP = "vfszip"; /** * URL protocol for an entry from an OC4J jar file: "code-source" */ private static final String URL_PROTOCOL_CODE_SOURCE = "code-source"; /** * Separator between JAR URL and file path within the JAR */ private static final String JAR_URL_SEPARATOR = "!/"; /** * URL prefix for loading from the file system: "file:" */ private static final String FILE_URL_PREFIX = "file:"; /** * 文件夹隔离符。 */ private static final String FOLDER_SEPARATOR = "/"; /** * 递归地在类路径中以指定的类加载器获取 dirPath 指定的目录下面所有的资源。cl 可为空,为空时取系统类加载器。 * 返回值一定不为 null。 */ public static ClassPathResource[] getClassPathResources(String dirPath, ClassLoader cl) throws IOException { if (cl == null) { cl = Thread.currentThread().getContextClassLoader(); } URL[] roots = getRoots(dirPath, cl); Set<ClassPathResource> result = new LinkedHashSet<ClassPathResource>(16); for (URL root : roots) { if (isJarResource(root)) { result.addAll(doFindPathMatchingJarResources(root)); } else { result.addAll(doFindPathMatchingFileResources(root, dirPath)); } } return result.toArray(new ClassPathResource[result.size()]); } /** * 获取指定 basePackages 下面所有能用 classLoaders 加载的类。 * * @param basePackages 这些包下面的类会被扫描 * @param classLoaders 用来加载 basePackages 下面类的类加载器 * @return 能够扫描到的类 */ public static Class<?>[] getAllClassPathClasses(String[] basePackages, ClassLoader... classLoaders) throws IOException { if (classLoaders.length <= 0) { classLoaders = new ClassLoader[] {Thread.currentThread().getContextClassLoader()}; } List<Class<?>> classes = Lists.newArrayListWithCapacity(100); for (ClassLoader classLoader : classLoaders) { for (String basePackage : basePackages) { classes.addAll(Lists.newArrayList(ReflectionUtils.getClasses(basePackage, classLoader))); } } return classes.toArray(new Class[classes.size()]); } /** * 使用 cl 指定的类加载器递归加载 packageName 指定的包名下面的所有的类。不会返回 null。 * cl 为空时使用系统类加载器。返回值一定不为 null。返回值中不包含类路径中的内部类。 */ public static Class<?>[] getClasses(String packageName, ClassLoader cl) throws IOException { if (cl == null) { cl = Thread.currentThread().getContextClassLoader(); } ClassPathResource[] resources = getClassPathResources(StringUtils.replace(packageName, ".", "/"), cl); List<Class<?>> result = Lists.newArrayList(); for (ClassPathResource resource : resources) { String urlPath = resource.getUrl().getPath(); if (!urlPath.endsWith(".class") || urlPath.contains("$")) { continue; } Class<?> cls = resolveClass(cl, resource); if (cls != null) { result.add(cls); } } return result.toArray(new Class[result.size()]); } private static Class<?> resolveClass(ClassLoader cl, ClassPathResource resource) { String className = resolveClassName(resource); try { return cl.loadClass(className); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } private static String resolveClassName(ClassPathResource resource) { String path = resource.getClassPathPath(); String className = path.substring(0, path.length() - ".class".length()); className = StringUtils.replace(className, "/", "."); return className; } private static URL[] getRoots(String dirPath, ClassLoader cl) throws IOException { Enumeration<URL> resources = cl.getResources(dirPath); List<URL> resourceUrls = EnumerationUtils.toList(resources); return resourceUrls.toArray(new URL[resourceUrls.size()]); } private static Collection<ClassPathResource> doFindPathMatchingFileResources(URL rootUrl, String dirPath) throws IOException { String filePath = rootUrl.getFile(); File file = new File(filePath); File rootDir = file.getAbsoluteFile(); return doFindMatchingFileSystemResources(rootDir, dirPath); } private static Collection<ClassPathResource> doFindMatchingFileSystemResources(File rootDir, String dirPath) throws IOException { Set<File> allFiles = Sets.newLinkedHashSet(); retrieveAllFiles(rootDir, allFiles); String classPathRoot = parseClassPathRoot(rootDir, dirPath); Set<ClassPathResource> result = new LinkedHashSet<ClassPathResource>(allFiles.size()); for (File file : allFiles) { String absolutePath = file.getAbsolutePath(); URL url = new URL("file:///" + absolutePath); String classPathPath = absolutePath.substring(classPathRoot.length()); classPathPath = StringUtils.replace(classPathPath, "\\", "/"); result.add(new ClassPathResource(url, classPathPath)); } return result; } private static String parseClassPathRoot(File rootDir, String dirPath) { String absolutePath = rootDir.getAbsolutePath(); absolutePath = StringUtils.replace(absolutePath, "\\", "/"); int lastIndex = absolutePath.lastIndexOf(dirPath); String result = absolutePath.substring(0, lastIndex); if (!result.endsWith("/")) { result = result + "/"; } return result; } private static void retrieveAllFiles(File dir, Set<File> allFiles) { File[] subFiles = dir.listFiles(); assert subFiles != null; allFiles.addAll(Arrays.asList(subFiles)); for (File subFile : subFiles) { if (subFile.isDirectory()) { retrieveAllFiles(subFile, allFiles); } } } private static Collection<ClassPathResource> doFindPathMatchingJarResources(URL rootUrl) throws IOException { URLConnection con = rootUrl.openConnection(); JarFile jarFile; String rootEntryPath; boolean newJarFile = false; if (con instanceof JarURLConnection) { // Should usually be the case for traditional JAR files. JarURLConnection jarCon = (JarURLConnection) con; jarCon.setUseCaches(true); jarFile = jarCon.getJarFile(); JarEntry jarEntry = jarCon.getJarEntry(); rootEntryPath = (jarEntry != null ? jarEntry.getName() : ""); } else { // No JarURLConnection -> need to resort to URL file parsing. // We'll assume URLs of the format "jar:path!/entry", with the protocol // being arbitrary as long as following the entry format. // We'll also handle paths with and without leading "file:" prefix. String urlFile = rootUrl.getFile(); int separatorIndex = urlFile.indexOf(JAR_URL_SEPARATOR); if (separatorIndex != -1) { String jarFileUrl = urlFile.substring(0, separatorIndex); rootEntryPath = urlFile.substring(separatorIndex + JAR_URL_SEPARATOR.length()); jarFile = getJarFile(jarFileUrl); } else { jarFile = new JarFile(urlFile); rootEntryPath = ""; } newJarFile = true; } try { if (!"".equals(rootEntryPath) && !rootEntryPath.endsWith("/")) { // Root entry path must end with slash to allow for proper matching. // The Sun JRE does not return a slash here, but BEA JRockit does. rootEntryPath = rootEntryPath + "/"; } Set<ClassPathResource> result = new LinkedHashSet<ClassPathResource>(8); for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) { JarEntry entry = entries.nextElement(); String entryPath = entry.getName(); if (entryPath.startsWith(rootEntryPath)) { String relativePath = entryPath.substring(rootEntryPath.length()); String rootPath = rootUrl.getPath(); rootPath = rootPath.endsWith("/") ? rootPath : rootPath + "/"; String newPath = applyRelativePath(rootPath, relativePath); String classPathPath = applyRelativePath(rootEntryPath, relativePath); result.add(new ClassPathResource(new URL(newPath), classPathPath)); } } return result; } finally { // Close jar file, but only if freshly obtained - // not from JarURLConnection, which might cache the file reference. if (newJarFile) { jarFile.close(); } } } /** * Apply the given relative path to the given path, * assuming standard Java folder separation (i.e. "/" separators). * * @param path the path to start from (usually a full file path) * @param relativePath the relative path to apply * (relative to the full file path above) * @return the full file path that results from applying the relative path */ private static String applyRelativePath(String path, String relativePath) { int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); if (separatorIndex != -1) { String newPath = path.substring(0, separatorIndex); if (!relativePath.startsWith(FOLDER_SEPARATOR)) { newPath += FOLDER_SEPARATOR; } return newPath + relativePath; } else { return relativePath; } } /** * Resolve the given jar file URL into a JarFile object. */ private static JarFile getJarFile(String jarFileUrl) throws IOException { if (jarFileUrl.startsWith(FILE_URL_PREFIX)) { try { return new JarFile(toURI(jarFileUrl).getSchemeSpecificPart()); } catch (URISyntaxException ex) { // Fallback for URLs that are not valid URIs (should hardly ever happen). return new JarFile(jarFileUrl.substring(FILE_URL_PREFIX.length())); } } else { return new JarFile(jarFileUrl); } } /** * Create a URI instance for the given location String, * replacing spaces with "%20" URI encoding first. * * @param location the location String to convert into a URI instance * @return the URI instance * @throws URISyntaxException if the location wasn't a valid URI */ private static URI toURI(String location) throws URISyntaxException { return new URI(StringUtils.replace(location, " ", "%20")); } private static boolean isJarResource(URL url) { String protocol = url.getProtocol(); return (URL_PROTOCOL_JAR.equals(protocol) || URL_PROTOCOL_ZIP.equals(protocol) || URL_PROTOCOL_VFSZIP.equals(protocol) || URL_PROTOCOL_WSJAR.equals(protocol) || (URL_PROTOCOL_CODE_SOURCE.equals(protocol) && url.getPath().contains(JAR_URL_SEPARATOR))); } /** * 类路径资源。 */ public static class ClassPathResource { /** * 此资源对应的 URL 对象。 */ private URL url; /** * 类路径下的路径。特点是这个路径字符串去掉了类路径的“根”部分。 */ private String classPathPath; /** * ctor. */ public ClassPathResource(URL url, String classPathPath) { this.url = url; this.classPathPath = classPathPath; } public URL getUrl() { return url; } public String getClassPathPath() { return classPathPath; } } }
发表评论
-
JParsec中如何在parser规则里引用lexer规则
2015-07-15 15:06 1573Java 的 Parser combinator 中最有名应该 ... -
Java 下面如何模拟友元
2011-02-16 02:13 5461Java 没有像 C++ 一样的友元。但是友元我认为是非常有用 ... -
精巧的状态机实现片段
2010-02-21 22:47 1193public enum SniperState { ... -
Inspiration from Clojure
2010-02-08 18:46 827http://www.infoq.com/presentati ... -
动态分类计数器
2010-01-10 00:30 1613昨天的工作遇到一个需求:要求根据用户 ID(Long 型)记录 ... -
Java 中文排序
2010-01-06 19:55 881在网上找到的最简单实用的方法: java.text.Coll ... -
多层类结构的对象相等性
2009-09-14 22:59 1029在 Effective Java 中,Joshua Bloch ... -
Maven 中直接依赖怎样影响间接依赖
2009-07-05 21:03 3405相信学 Maven 的都看过 Maven 的官网文档的 Int ... -
FutureTask.isDone() 的返回问题
2009-05-30 06:41 6556FutureTask.isDone() 方法在 c ... -
获取文本控件的输出流
2009-04-22 23:08 1510在 Swing 中,文本控件没有输出流!所谓的文本控件这里指派 ... -
在JNI中调用本地带结构体参数的函数
2008-07-27 16:28 10285说起JNI,《The Java Native Interfac ...
相关推荐
ClassGraph是一款强大的Java工具,专为开发者设计,用于执行高效、快速且并行的类路径扫描。这款开源库提供了一种灵活的方式,帮助开发者轻松地探索、分析和管理应用程序的类结构。它不仅适用于常规的类扫描任务,还...
ClassGraph是一款强大的开源Java工具,它作为一个快速、超轻量级的类路径扫描器、模块扫描仪和注释处理器,广泛应用于各种Java开发场景。这个工具由Luke Daley开发,旨在提供灵活、高效且功能丰富的类扫描解决方案。...
ClassGraph是适用于Java,Scala,Kotlin和其他JVM语言的超快速并行化类路径扫描器和模块扫描器。 ClassGraph在Oracle Code One 2018上获得了Duke's Choice奖(该奖项是对Java生态系统中最有用和/或最具创新性的...
【Java毕业设计】毕业设计——基于Java的漏洞扫描系统 在IT行业中,Java是一种广泛应用的编程语言,尤其在企业级应用开发中占有重要地位。基于Java的漏洞扫描系统是网络安全领域的一个重要课题,旨在帮助企业和组织...
《深入理解Java类路径扫描器:ClassGraph》 在Java开发中,类路径(Classpath)的管理和扫描是一项基础但至关重要的任务。它涉及到程序如何找到并加载运行所需的类文件。传统的类路径扫描通常依赖于Java的反射机制...
该项目为Java语言开发的Controller类路径扫描工具,包含32个文件,涵盖24个Java源文件、2个属性文件、1个Git忽略文件、1个JAR包文件、1个Markdown文件和1个Maven构建文件。该工具能够自动扫描项目中的Controller类,...
在Java中,通常会创建一个Scanner类来封装扫描仪的接口调用,包括设置扫描参数(如分辨率、色彩模式等)、启动扫描、获取扫描图像等方法。这些方法通过JNI或JNA与扫描仪驱动进行交互。 其次,描述中提到需要在...
1. `.classpath`:这是Eclipse IDE的一个配置文件,它包含了项目所需的类路径信息,用于编译和运行Java程序。 2. `README.md`:这是一个Markdown格式的文件,通常包含项目简介、使用方法、安装步骤等信息,是理解...
在Eclipse这样的集成开发环境中,我们需要将这个文件添加到项目的类路径中,或者通过系统环境变量指定路径,确保Java能够正确调用OpenCV的函数。 实现“全能扫描王”功能的关键步骤包括以下几个部分: 1. **图像...
注意,`getName()`返回的是类文件的完整路径,而`substring()`和`replace()`方法则用于转换成Java中的包名和类名格式。 在给定的测试用例中,使用了一个名为`ClassScanner`的类来扫描特定包下的所有类。`...
在给定的场景中,我们需要实现的功能是遍历指定包路径下的所有类,获取它们的属性信息,包括属性的注解和注释,并以表格形式输出。 首先,我们需要通过`Package.getPackage(String name)`方法获取指定包名的Package...
这个过程通常涉及到类路径扫描和反射技术。以下将详细介绍这一知识点。 首先,我们需要理解Java的类路径(ClassPath)。类路径是Java虚拟机(JVM)寻找类文件的路径,它决定了JVM如何查找和加载类。通过遍历类路径...
2. **文件I/O操作**: 使用`java.io`包中的`File`类可以获取文件路径,创建和操作文件。在扫描图片时,我们需要创建`File`对象来指定图片的路径,然后使用`exists()`检查文件是否存在,`isFile()`确认是文件而非目录...
总的来说,"java类查找小工具"是Java开发者不可或缺的辅助工具之一,它能够帮助我们更有效地管理和理解项目依赖,提升开发效率,解决与类路径相关的问题。通过掌握这类工具的使用,可以进一步提升我们的Java编程技能...
**IDEA阿里巴巴Java编码规约扫描插件** 阿里巴巴Java编码规约扫描插件是专为IntelliJ IDEA(IDEA)开发的一款辅助工具,旨在帮助Java开发者遵循阿里巴巴制定的Java编程规范,提升代码质量和可读性。这款插件提供...
在Java编程中,工具类(Util Class)是包含各种实用函数的静态类,它们提供了一种简化常见任务的方法。在给定的`UtilClass`中,我们有五个主要的工具类:`StringUtil`、`FileUtil`、`ConnectDB`、`DateUtil`和`...
这通常涉及到下载JTwain的jar文件,并将其添加到项目的类路径中。对于Maven或Gradle等构建工具,可以在pom.xml或build.gradle文件中配置依赖。确保正确地引入库后,就可以在Java代码中导入必要的包并开始编写扫描仪...
3. 限制反序列化权限:只允许受信任的类进行反序列化,通过配置白名单或黑名单来限制反序列化的类路径。 4. 应用安全更新:及时修复已知的反序列化漏洞,如CVE公告中列出的那些。 5. 定期进行安全审计和渗透测试:...
在Java中,可以使用File类来表示文件和文件夹,然后使用递归函数来实现文件夹下所有文件的扫描。 在上面的代码中,我们定义了一个FolderFileScanner类,该类中有两个静态方法:scanFilesWithRecursion和...
4. **模块系统**:Java 9引入的模块系统,模块化开发的优势及如何配置模块路径。 5. **泛型**:泛型的语法,类型擦除,通配符,以及泛型的边界。 6. **并发编程**:并发工具类,如Semaphore、CyclicBarrier、...