Изменить исполняемый JAR-файл

Привет, друзья, Stack Overflow. У меня есть простая проблема, которая, я боюсь, не имеет простого решения, и мне нужен совет, как действовать дальше. Я разрабатываю приложение Java, упакованное как исполняемый файл JAR, но для этого требуется изменить часть содержимого файла JAR во время выполнения. На этом этапе я столкнулся с проблемой, потому что некоторые ОС блокируют файл, предотвращая запись в него.

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

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

  1. Скажите Java, чтобы разблокировать файл JAR для записи (это не кажется возможным, но это было бы самым простым решением)
  2. Скопируйте исполняемые файлы классов во временный файл при запуске приложения, используйте загрузчик классов для загрузки этих файлов и выгрузки из исходного файла JAR. что исходный JAR больше не используется, поэтому разблокируйте его)
  3. Поместите второй исполняемый файл JAR внутрь первого, при запуске извлеките внутреннюю банку во временный файл, вызовите новый процесс Java, используя скопированный внутренний файл JAR, и передайте ему расположение внешнего файла JAR, первый процесс завершается, второй процесс изменяет внешний файл jar. unincumbered. (Это будет работать, но я не уверен, что существует независимый от платформы способ вызова одного Java-приложения другим)

Я знаю, что это странный вопрос, но любая помощь будет оценена по достоинству.


person PinkyNoBrain    schedule 17.03.2010    source источник
comment
Можете ли вы указать, почему вам нужно изменить файл jar во время выполнения?   -  person Poindexter    schedule 17.03.2010
comment
@pinkynobrain вы думаете в стиле муравья старой школы, я предлагаю вам прочитать бесплатную электронную книгу maven на примере, вы увидите, что то, что вы предлагаете, не имеет смысла .. Я не пытаюсь вас обидеть, просто пытаюсь вам помочь. , разве мы все не были там   -  person ant    schedule 17.03.2010
comment
Чего вы пытаетесь добиться - самообновляющегося приложения?   -  person matt b    schedule 17.03.2010
comment
@ c0mrade, что ты имеешь в виду?   -  person matt b    schedule 17.03.2010
comment
В JAR-файле объединено несколько файлов, содержащих информацию о пользователе. Пользователь добавляет информацию во время выполнения программы, и ее необходимо добавить в JAR-файл. Поскольку цель приложения - быть небольшим и легко транспортируемым, я действительно хочу сохранить его как единственный файл jar.   -  person PinkyNoBrain    schedule 17.03.2010
comment
Следует отметить, что я не хочу, чтобы программа модифицировала свой собственный исполняемый код, хотя это было бы круто, я вижу, как это вызовет проблемы. Я просто хочу изменить метаинформацию, которая также хранится в JAR для удобства. P.S. Я тоже понятия не имею, о чем говорит @cOmrade :-S   -  person PinkyNoBrain    schedule 17.03.2010
comment
@pinkynobrain, и вы хотите, чтобы информация о пользователе была переносимой с помощью JAR?   -  person matt b    schedule 17.03.2010
comment
Да, и я подумал, что самый простой способ добиться этого - просто поместить его в сам JAR (поскольку это действительно zip-файл), тогда пользователю нужно скопировать только один файл. у меня есть существующий код, который выполняет модификации, и все в порядке, когда цель файла JAr не выполняется. К сожалению, я забыл о том, что какая-то ОС блокирует исполняемый Jar :-(   -  person PinkyNoBrain    schedule 17.03.2010


Ответы (2)


Один вариант:

Попросите программу записать измененную копию файла JAR.

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

Когда ваша программа завершится (и будут внесены изменения), извлеките эту утилиту и запустите ее в своей собственной JVM (используя Runtime.getRuntime().exec()). Утилита будет ждать, пока блокировка не будет снята с исходного, немодифицированного JAR, а затем выполнит свою работу и завершит работу.

Для пользователя файл JAR будет обновляться при выходе (или достаточно близко!).

person Kris    schedule 17.03.2010
comment
Эй, спасибо за ваш ответ, это определенно другое решение, хотя оно все еще страдает от той же проблемы, что и мой вариант 3. Я полагаю, что использование exec (java) довольно переносимо, я просто надеялся, что есть какой-то действительно независимый от платформы способ создания одной Java приложение от другого. - person PinkyNoBrain; 17.03.2010
comment
Хотя Java намного более независим от платформы, чем многие другие языки, он несовершенен во многих отношениях, и на самом деле не так уж важно, чтобы что-то вроде того, как вы выполняете файл jar, выполнялось в коммутаторе, основанном на платформе ( если он даже должен быть другим - я думаю, что «java ‹jarfile›» работает на unix и windows, не уверен насчет osx). - person Chris; 17.03.2010
comment
Как насчет получения всей информации, необходимой для выполнения Runtime.getRuntime().exec() на платформе independent до фактического вызова. Я думаю, что метод System.getProperties() содержит некоторую полезную информацию. - person Jaime Hablutzel; 08.03.2014

Я искренне думаю, что ваш подход ошибочен. Это просто не подходит для стандартного способа развертывания java. Ваши измененные файлы просто должны сохраняться где-то в файле db или xml - это ЕДИНСТВЕННЫЙ разумный подход.

Все это просто «борьба с ветром» - вы можете с некоторыми трудностями заставить это работать, но в конечном итоге это УКУСАЕТ вас или клиента.

person MJB    schedule 18.03.2010
comment
Мне жаль, что вам не нравится этот ответ. Что касается переименования, блокировки и т. Д., Я просто выразил свое мнение о том, что вы пытались навязать решение, которое не подходит для проблемы. - person MJB; 19.03.2010
comment
Так что это будет комментарий, а не ответ - person Jaime Hablutzel; 08.03.2014