Проблема
При попытке доступа к ресурсу из каталога веб-приложения WEB-INF/lib (а именно к jar-библиотеке), по URL полученному из ServletContext-а не получается создать объект класса JarFile. На данный момент проверено под Tomcat 7.x (позже проверю под OAS и WLS)
Решение
Для того, чтобы ресурс мог потом быть доступен через JarFile (например для чтения описания readme.txt из файла внутри jar-а), необходимо использовать хак :
- Добавить к строке, полученного url-а ресурса "jar:" впереди и "!\" позади.
- Использовать url.openConnection()
Пример
// получить список ресурсов в WEB-INF/lib
Set<String> jarLibPaths = servletContext.getResourcePaths("/WEB-INF/lib");
for (String jarPath : jarLibPaths) {
// так будет неправильное преобразование типа ClassCastException, т.к. открытое соединение не JarURLConnection
// URL urlBad = servletContext.getResource(jarPath);
// JarURLConnection conn = (JarURLConnection) urlBad.openConnection();
// так будет FileNotFoundException
// URL urlBad2 = servletContext.getResource(jarPath);
// JarFile jarFile = new JarFile(urlBad2.getFile());
// JarFile jarFile = new JarFile(urlBad2.toString()); // та же проблема
// URL urlBad3 = new URL("jar:" + servletContext.getResource(jarPath).toString() + "!/");
// JarFile jarFile = new JarFile(urlBad3.getFile()); // снова ошибка
// а так всё будет работать
URL urlOk =
new URL("jar:" + servletContext.getResource(jarPath).toString() + "!/");
JarURLConnection conn = (JarURLConnection) urlOk.openConnection();
JarFile jarFile = conn.getJarFile();
}