ClassLoader返回含多余第二个感叹号的路径问题排查
解决ClassLoader获取资源路径多感叹号的问题
我碰到过不少类似的场景,你遇到的这个问题是因为应用容器处理WAR包时,错误地把WEB-INF/classes(实际是普通目录)当成归档文件解析了,导致生成的资源路径里多了一个多余的感叹号。下面给你几个实用的解决办法:
1. 手动修正路径字符串
如果你确实需要拿到资源的路径字符串,可以直接对返回的URL进行字符串处理,移除那个多余的感叹号:
String ePath = "rewrite/common/RenameFunctor.groovy"; URL resourceUrl = ThClType.class.getClassLoader().getResource(ePath); if (resourceUrl != null) { String fPath = resourceUrl.toString(); // 替换掉错误的双感叹号部分 fPath = fPath.replace("!/WEB-INF/classes!/", "!/WEB-INF/classes/"); // 现在fPath就是符合预期的路径了 }
2. 优先使用getResourceAsStream读取资源
其实大多数场景下,我们不需要直接获取资源的路径,而是直接读取资源内容。这种情况下,用getResourceAsStream()会更可靠,完全避开路径解析的坑:
String ePath = "rewrite/common/RenameFunctor.groovy"; try (InputStream inputStream = ThClType.class.getClassLoader().getResourceAsStream(ePath)) { if (inputStream != null) { // 这里可以直接读取资源,比如处理Groovy文件 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { // 按需求处理文件内容 } } else { // 资源不存在的处理逻辑 System.err.println("Resource not found: " + ePath); } } catch (IOException e) { e.printStackTrace(); }
补充说明
正常情况下,WAR包内资源的正确路径格式应该是jar:file:/xxx.war!/WEB-INF/classes/rewrite/common/RenameFunctor.groovy——WEB-INF/classes是WAR包内的目录,不是独立的归档文件,所以不该有第二个感叹号。这个问题通常是容器的ClassLoader实现细节导致的,上面的两种方案都能有效解决。
内容的提问来源于stack exchange,提问作者Ben Barden
相关产品推荐
相关产品推荐

