JDK11下从系统类加载器读取指定包类返回空数组求助
解决思路
替换类加载器
ClassLoader.getSystemClassLoader()在服务器环境中可能无法访问应用内部的资源,改用当前上下文的类加载器:// 方式1:当前类的类加载器 InputStream stream = YourCurrentClass.class.getClassLoader().getResourceAsStream(packageName.replaceAll("[.]", "/")); // 方式2:线程上下文类加载器(更适配复杂部署场景) InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(packageName.replaceAll("[.]", "/"));检查大小写一致性
Linux是大小写敏感系统,确认服务器上的包路径、class文件名与代码中传入的packageName("foo")大小写完全匹配,避免本地大小写不敏感导致的隐性问题。适配Jar包部署场景
如果服务器上是Jar包运行,getResourceAsStream无法读取Jar内的目录结构,需要改用JarFile遍历:public static Set<Class> getClassesFromPackage(String packageName) throws IOException, ClassNotFoundException { Set<Class> classes = new HashSet<>(); String packagePath = packageName.replace(".", "/") + "/"; // 获取当前类所在的Jar包路径 URL codeSource = YourCurrentClass.class.getProtectionDomain().getCodeSource().getLocation(); String jarPath = URLDecoder.decode(codeSource.getPath(), StandardCharsets.UTF_8.name()); try (JarFile jarFile = new JarFile(jarPath)) { Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String entryName = entry.getName(); // 过滤目标包下的class文件 if (entryName.startsWith(packagePath) && entryName.endsWith(".class") && !entry.isDirectory()) { // 转换为类全名 String className = entryName.replace("/", ".").substring(0, entryName.length() - 6); classes.add(Class.forName(className)); } } } return classes; }开启Debug日志排查
服务器可能未开启Debug级别的日志输出,调整日志配置(如Logback/Log4j),将当前类的日志级别设为DEBUG,查看stream是否为空、读取到的行内容是什么,定位问题环节。验证服务器上的Class文件存在性
- 若为解压部署:检查应用类路径下(如
WEB-INF/classes/)是否存在foo/Test.class; - 若为Jar包部署:执行
jar tvf your-app.jar | grep foo命令,确认Jar包内包含目标class文件。
- 若为解压部署:检查应用类路径下(如
内容的提问来源于stack exchange,提问作者alessandro ferrucci
相关产品推荐
相关产品推荐

