![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
Добрый день.. Есть задача,сделать так что бы при втором запуске java-приложение, оно блокировалось и перекидывало фокус на уже открытое ..
Разделил на два этапа 1)НЕ допустить запуска второй копии 2)Перебросить фокус 1)Почитал в интернете и тут, нашел два способа, это занимать порт и лочить файл.Т.к я и так занимаю порт под нужные цели, первым вариантом пользоваться не хочется . 2 )Нашел в интернете такую реализацию:
НО что в винде что в линуксе,всё время пишет что файл(ТХТ) залочен,т.е уходит на исключение Что тут не так? 2)Можно ли вообще сделать фокусировку на приложение программно? |
|||
|
||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
Первый вопрос решил)
|
|||
|
||||
Su_ |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
По поводу первого пункта, может кому пригодится:
В начало программы:
методы
Работает и в win и в lin, при чем: В винде блокирует файлы нормально, в Линуксе файл не блокирует , но повторно войти в
не может. Для этого еще есть проверка флага block. Почему не блокирует файл я так и не понял, но это работает. Осталось разворачивать уже запущенное приложение вместо запуска ещё одной копии (lin) ??? |
||||||
|
|||||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
увы этот алгоритм дает сбой в Linux.. отсюда вопрос как заблокировать файл в linux?????????7
|
|||
|
||||
dobrolub |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 385 Регистрация: 18.12.2009 Где: Vancouver, Canada Репутация: 11 Всего: 16 |
Thread t = new Thread() {
public void run() { new FileInputStream("zzz").getChannel().tryLock(); } }; t.start(); t.join(100);//даём 100 ms на захват лока. try { t.interrupt(); } catch (Exception e) { //обработка } Это сообщение отредактировал(а) dobrolub - 12.1.2010, 03:00 |
|||
|
||||
Su_ |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
если это повесить на кнопку
вылетает на исключение ,при чем не на IOException А вообще линукс поддерживает блокировку файлов? Добавлено через 6 минут и 25 секунд для запуска
после запуска
Я не очень понимаю,почему в винде блокирует нормально,а в линуксе нет.? |
||||||
|
|||||||
dobrolub |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 385 Регистрация: 18.12.2009 Где: Vancouver, Canada Репутация: 11 Всего: 16 |
Возможно баг в JDK, но вроде с помощью exception всё можно отследить как я понял.
|
|||
|
||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
к сожалению нет. суть то основываться на блокировки файла , если залочен ,значит одна копия запущена, а так как в Linux он их не лочит, этого не сделать, походу придется на порт вешать.,хотя писали что это далеко не самое лучше решение! dobrolub спасибо)
|
|||
|
||||
dobrolub |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 385 Регистрация: 18.12.2009 Где: Vancouver, Canada Репутация: 11 Всего: 16 |
так получается что не за что :(
слушай а что за JDK / Linux? |
|||
|
||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
java-1.6.0-openJDK уже стояло на мое MandrivaFree2009. Я думаю тут различие идет по возможности lock/unlock по ОС а не по JDK
|
|||
|
||||
dobrolub |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 385 Регистрация: 18.12.2009 Где: Vancouver, Canada Репутация: 11 Всего: 16 |
на debian 5 с JDK от Sun.
java version "1.6.0_07" Java SE Runtime Environment (build 1.6.0_07-b06) Java HotSpot Client VM (build 10.0-b23, mixed mode, sharing) код внизу отработал нормально.
первый запуск:
второй - параллельный запуск
Добавлено через 13 минут и 39 секунд проверил с версией 1.5 - тоже работает. То есть возможно проблема в JDK java version "1.5.0_16" Java 2 Runtime Environment, Standard Edition (build 1.5.0_16-b02) Java HotSpot Client VM (build 1.5.0_16-b02, mixed mode, sharing) Это сообщение отредактировал(а) dobrolub - 12.1.2010, 04:27 |
||||||
|
|||||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
ого Спасибо, это важно для меня ..поковыряюсь с JDK)
Добавлено через 9 минут и 5 секунд Слушай у меня такой же вывод выдает теперь.. может я где то напортачил ,надо больше спать) Спасибо большое ! |
|||
|
||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
токо не понял почему он в дальнейшем сбрасывает Lock , если в этом же потоке работать с файлами)
|
|||
|
||||
dobrolub |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 385 Регистрация: 18.12.2009 Где: Vancouver, Canada Репутация: 11 Всего: 16 |
я думаю что lock сбрасывается когда переменные выходят из области видимости и собираются мусорщиком.
Лучше бы переменные связанные с этим локом положить в новую thread и добавить её kak shutdownHook Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { //освободить локи, закрыть выходные потоки. } }); |
|||
|
||||
dobrolub |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 385 Регистрация: 18.12.2009 Где: Vancouver, Canada Репутация: 11 Всего: 16 |
>1)Почитал в интернете и тут, нашел два способа, это занимать порт и лочить файл.Т.к я и так занимаю порт под нужные цели, первым вариантом пользоваться не хочется
Я про порт не понял, с ним железней, в общем-то, тем более он так и так должен выделиться системой. |
|||
|
||||
Zefick |
|
|||
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 3.12.2009 Репутация: 1 Всего: 2 |
Su_, я не понимаю, почему Вы отмели идею о занятии порта. Мне она пришла в голову сразу, как только я прочитал название темы (наверное, потому что в универе не так давно была лаба по сетевым приложениям на Java и что будет, если запустить два сервера я отлично помню). К тому же Вы говорите, что порт у вас и так занимается. Вот и замечательно - при второй попытке его занять выбросится исключение, которое надо ловить и передавать фокус в первую программу.
|
|||
|
||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
Сейчас я её реализовал правда на другом порте.,т.к на основной не хочеться кидать, иногда в процессе работы (прием сообщений ) вылетает исключение в ожидание порта ,потом пересоздается. С лок-файлом наиболее красивое решение, не надо занимать сетевой порт ,и не должно висеть порт,что если на этот порт начнут спамить ,и он выкинеть исключение)
|
|||
|
||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
а как передать фокус в первую программу?
|
|||
|
||||
serger |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 518 Регистрация: 19.6.2007 Где: Ижевск Репутация: 1 Всего: 5 |
Грубо.
Занятие порта хорошая идея, до тех пор пока есть сеть. В последнее время сеть, правда, уже почти везде... -------------------- упс! |
|||
|
||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
а как передать фокус в первую программу?
Добавлено через 1 минуту и 14 секунд в смысле ГРубо? там мегафон интернет который иногда отваливается .. |
|||
|
||||
Su_ |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
решил вопрос о восстановление фокуса,правда если через порт делать..
т.е. вешаю порт на сервер, если вылетает исключение шлю на этот же порт connect , а если на этом порту срабатывает accept то он делать
т.е так :
|
||||
|
|||||
dobrolub |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 385 Регистрация: 18.12.2009 Где: Vancouver, Canada Репутация: 11 Всего: 16 |
хороший способ; другой, кросс-платформный, трудно найти я думаю.
|
|||
|
||||
Su_ |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 386 Регистрация: 1.8.2007 Репутация: нет Всего: нет |
будем тестировать, Важна стабильность)Спасибо всем кто помогал, я думаю топик можно закрыть)
|
|||
|
||||
Viroman |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 140 Регистрация: 28.7.2008 Репутация: нет Всего: нет |
http://forum.vingrad.ru/forum/topic-303234.html
В продолжение этой темы, модер поспешил закрыть даже до конца не поняв сути, не конкретно незапуск второй копии, а именно шаринг списка задач, общий блок памяти, или ещё чего нибудь быстрое. Порты занимать уже проходили, не то, глупый вариант, и я о нём уже думал, но видимо больше хороших идей нет :( |
|||
|
||||
Viroman |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 140 Регистрация: 28.7.2008 Репутация: нет Всего: нет |
Кстати, просто обязан поблагодарить dobrolub за предоставленный код, работает на ура. Только как я понял, дискуссия была по поводу нерабочести под линуском. Так вот, если вдруг столкнётся кто то с этой проблемой вновь, есть одно огромное различие в плане использования этой фишки под виндой и линухом. Дурость заключается в том, что при воспроизведении этого кода System.out.println(new FileOutputStream("xxx").getChannel().tryLock()); на винде файл лочится до конца воспроизведения всей джава машины!!! и работает как надо и ожидается, что так и будет работать, ведь никто лок программно не освобождает. Но на линухе это не работает, как ожидается!!! Фишка заключается в том, что если воспроизвести этот код System.out.println(new FileOutputStream("xxx").getChannel().tryLock()); то система залочит файл, а потом она его тут же разблокирует, к сожалению, и это и явилось подводным камнем и для меня, и похоже для топикстартера!!! Дабы избежать этой проблемы в КОРНЕ, учтите на будущее, запускайте выжеизложенный код как есть с синхронизацией и wait в отдельном потоке и тогда и файл лочится прекрасно и не разлочивается до конца воспроизведения машины, и работает и на винде, линухе, маке итп... Может кому то это поможет, чтобы на те же грабли не наступали.. |
|||
|
||||
koreyko |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 20.4.2010 Репутация: нет Всего: нет |
Здравствуйте, уважаемые форумчане.
Решил не открывать новую тему, т.к. стоит та же задача - сворачивание приложения в трей и его восстановление из трея при попытке запуска второй копии приложения. Задачу блокировки второй копии решил с помощью лок-файла. Осталось передать фокус в запущенную первой копию. Я пробую сделать это через instance ID. Получаю и сохраняю ID в залоченный файл, при запуске второй копии - считываю. Теперь остался последний шаг: достучаться к уже запущенному инстансу через его ID и восстановить окно программы. Подскажите, пожалуйста, как это сделать? Спасибо. |
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Надо делать, как уже писали выше, все через порт. Приложение при запуске должно запускать сервер, который принимает сокетные соединения на любом свободном порту из заданного диапазона. Приложение должно провести поиск других инстансев соединяясь поочередно к портам из заданного диапазона. Если соединение успешно создано и пароль совпадает, значит два инстанса друг друга нашли и дальше могут обмениваться командами через сокетное соединение. |
|||
|
||||
koreyko |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 20.4.2010 Репутация: нет Всего: нет |
Спасибо, а где можно почитать об этом способе - через порт? Желательно с примерами. После прочтения ветки ясность не наступила, к сожалению.
|
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Примерно так. Запустите этот класс два раза. Когда вторая инстанс стартует, первая закрывается командой System.exit(0). Можно любое другое поведение реализовать.
|
|||
|
||||
koreyko |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 20.4.2010 Репутация: нет Всего: нет |
COVD, спасибо. Вдумчиво изучил Ваш код, но так и не понял -- каким образом я все-таки могу получить из второй запущенной копии доступ к фрейму первой копии? Для того, чтобы развернуть свернутое в трей окно.
|
|||
|
||||
batigoal |
|
|||
![]() Нелетучий Мыш ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6423 Регистрация: 28.12.2004 Где: Санктъ-Петербургъ Репутация: 24 Всего: 151 |
koreyko, тебе не нужно получать доступ к чужому фрейму - это сам первый экземпляр программы слушает события на порту, и, получив сообщение от запущенного второго инстанса, разворачивает себя. Второй же экземпляр после получения сообщения тихо завершается.
-------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли) ЖоржЖЖ |
|||
|
||||
koreyko |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 20.4.2010 Репутация: нет Всего: нет |
batigoal, вы уверены? Потому что COVD писал, цитирую: "Когда вторая инстанс стартует, первая закрывается командой System.exit(0)"
|
|||
|
||||
batigoal |
|
|||
![]() Нелетучий Мыш ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6423 Регистрация: 28.12.2004 Где: Санктъ-Петербургъ Репутация: 24 Всего: 151 |
koreyko, да, но выполняет-то этот System.exit сам инстанс, который будет выключен:
Программа получила сообщение и завершила себя. -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли) ЖоржЖЖ |
|||
|
||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
koreyko
У меня действительно так сделано, что при запуске второго инстанса он шлет команду первому инстансу и первый сам себя закрывает по этой команде. Я привел код, на основе которого вы можете реализовать свою логику, например, второй закрывается, а первый разворачивается. |
|||
|
||||
koreyko |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 20.4.2010 Репутация: нет Всего: нет |
COVD, еще раз спасибо. Разобрался, всё у меня получилось. Я раньше никогда не работал с сокетами и серверами, поэтому у меня осталась пара вопросов:
- что такое readTimeout, равный 2-м секундам и зачем он нужен? Насколько я понял, это диапазон, через который сервер слушает приходящие команды, или нет? Заметил такую ситуацию: если быстро запустить приложение 2 раза, то остаются запущенными две копии. Как с эти можно бороться? - каким образом надо выбирать диапазон портов? Если все они оказались до этого заняты другими процессами, то данное решение не сработает? Или же это порты относятся только к запущенному серверу и они всегда свободны? |
|||
|
||||
COVD |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Поток, читающий из сокета, блокируется, если нет данных (если сокет в блокирующем режиме). Таймаут на чтение определяет максимальное время ожидания данных. Если данных нет большее время, то выбрасывается исключение, и поток разблокируется. Это событие на принимающей стороне (на клиенте) означает, что коммуникация завершилась аварийно. Иначе поток может ожидать данных вечно. 2 сек - предполагается, что в локальной сети этого достаточно. Если обмен данных осуществляется через интернет, то обычно ставят секунд 15.
Очевидно, что второе запущенное приложение начинает поиск, а первое приложение еще не успело запустить свой сервер, так как тоже ищет. Можно попробовать поменять местами операции - сначала стартовать сервер, а потом искать в сети другие инстансы. И, наверное, надо передавать время старта в миллисек, чтобы инстансы могли понять, кто из них первый.
Если все порты из диапазона заняты, то не сработает (сервер не сможет стартовать). Если расширить диапазон, то увеличится время поиска. Я думаю, 5 - 10 портов вполне достаточно для этих целей. Мир не рухнет, если данное решение вдруг не сработает. |
||||||
|
|||||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |