Могу ли я получить URLConnection для файла в JAR в неразорванном WAR? - PullRequest
3 голосов
/ 04 июля 2011

У меня есть несколько файлов ресурсов, которые находятся в classpath моего веб-приложения (внутри JAR, если это имеет значение). Я знаю, что могу получить доступ к содержимому этих ресурсов, позвонив, например, по адресу SomeClassLoader.getResourceAsStream( "/samples/myscript.txt" ). В прошлом я проверял это в файлах в разобранном виде и в нераскрытом виде WAR.

Однако, чтобы интегрироваться с некоторыми другими существующими классами в моем приложении, мне необходимо предоставить объект URLConnection для этого файла. Я проверил и подтвердил, что вызов getResource("/samples/myscript.txt").openConnection() работает в разнесенных WAR (кроме того, отладка показала, что в результате получается file:/// URL-адрес взорванного файла).

Вопрос: будет ли этот метод работать на неразорвавшихся («упакованных?») WARs?

(В настоящее время у меня нет легкого доступа к серверу, который разворачивает войны, не разбирая их, поэтому я и спрашиваю, а не просто пробую его. Кроме того, некоторые серверы (например, Jetty, Tomcat - даже с unpackWARs="false") разрешает неразорвавшиеся развертывания, но за кулисами они распаковывают войну, фактически ведут себя как взорванное развертывание - и, очевидно, работают правильно. Я думаю, что серверами, которые доставляли мне проблемы в прошлом, были Websphere и Weblogic).

Ответы [ 2 ]

2 голосов
/ 04 июля 2011

Я не верю в это. Для этого вам нужно будет использовать JarUrlConnection для URL-адреса JAR, базовый URL которого был другим URL-адресом JAR. Если я попробую это, я получу:

java.net.MalformedURLException: no !/ in spec

«spec» - это то, что JarUrlConnection называет путем, который ссылается на файл внутри JAR. Похоже, что для URL, такого как jar:jar:file:///outer.jar!/inner.jar!/myscript.txt, он отсекает спецификацию на сначала восклицательном знаке, а затем отклоняет inner.jar!/myscript.txt в качестве спецификации. На самом деле, мы бы хотели, чтобы он отрубил спецификацию на последнем восклицательном пути, развернув внутренний URL (который относится к внешнему JAR!), Чтобы использовать его в качестве основы. Несчастная. Я никак не могу обойти это.

0 голосов
/ 22 февраля 2018

Что следует отметить в связи с предпринимаемой операцией: запись в архиве, которая сама является записью архива, имеет два уровня упаковки и, возможно, имеет два уровня сжатия. Любая попытка получить доступ к данным записи, оставляя промежуточный архив как запись в самом внешнем архиве, должна была бы распаковать промежуточный архив перед извлечением записи.

Для доступа к дважды вложенному архиву используются два основных метода и один продвинутый метод: во-первых, чаще всего промежуточный архив извлекается во временный файл. Во-вторых, время от времени можно просматривать записи промежуточного архива, но это очень медленно и не рекомендуется, за исключением очень ограниченных обстоятельств. В-третьих, продвинутым методом было бы не сжимать промежуточный архив, а затем создавать смещенный файл с указателями на область самого внешнего архива на промежуточный архив. Я не уверен, что это где-то сделано, но это позволит избежать накладных расходов на другие два метода.

В любом случае, существуют значительные дополнительные шаги, необходимые для доступа к дважды вложенной записи, что довольно много для простого обработчика протокола.

Обратите внимание, что это общая проблема для архивов приложений JavaEE, которые определены как многоуровневые архивы: EAR -> (JAR | WAR | RAR), WAR -> JAR и RAR -> JAR. JavaEE создает три уровня вложенных архивов.

...