Сборка мусора Java

Java управляет памятью кучи за вас. Вы запускаете свое приложение внутри виртуальной машины (JVM). JVM выполняет работу по выделению пространства, когда это необходимо, и освобождению его, когда оно больше не нужно. Сборщик мусора (GC) — вот что вам поможет.

Переработка памяти включает в себя «циклы» сборки мусора, которые влияют на производительность. Степень воздействия зависит от характера вашего приложения и выбранного вами GC. Хорошая новость заключается в том, что существует более одного сборщика мусора, и каждый последний выпуск Java предлагает больше вариантов. Вы можете выбрать GC, который наилучшим образом соответствует потребностям вашего приложения.

Новые сборщики мусора

В последних двух выпусках Java представлены три новых GC. Мы рассмотрим каждый из них и то, что они добавляют в экосистему.

Java 11 представила Epsilon и сборщик мусора Z (ZGC). Epsilon — это сборщик мусора без операций. Он выделяет новую память, но никогда не перерабатывает ее. ZGC обещает управлять большими объемами памяти с высокой пропускной способностью и коротким временем паузы.

Java 12 добавляет сборщик мусора Shenandoah. Как и ZGC, он управляет большими кучами с коротким временем паузы, но использует совершенно другой подход.

Сборщик мусора Эпсилон

Что такое Эпсилон?

Epsilon — это пассивный или «нерабочий» GC. Он обрабатывает выделение памяти, но не перерабатывает ее, когда объекты больше не используются. Когда ваше приложение исчерпывает кучу Java, JVM отключается. Другими словами, Epsilon позволит вашему приложению исчерпать память и сломаться.

Как использовать Эпсилон 

Параметры командной строкиПримечания
 -XX:+UnlockExperimentalVMOptions Разблокируйте экспериментальные возможности Java.
 -XX:+UseEpsilonGC Используйте Эпсилон ГХ
 -XmxXg Установить размер кучи. JVM завершит работу с OutOfMemoryError, если это количество будет превышено.
 -XX:HeapDumpOnOutOfMemoryError Создайте дамп кучи, если JVM не хватает памяти.
 -XX:OnOutOfMemoryError= Выполнить указанную команду при возникновении ошибки нехватки памяти.


Зачем использовать No-Op GC? 

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

Epsilon устраняет влияние GC на производительность. Нет циклов GC или барьеров чтения или записи. При использовании Epsilon GC ваш код выполняется изолированно. Вы можете использовать его, чтобы увидеть, как сбор мусора влияет на производительность вашего приложения и каков ваш порог памяти, поскольку он сообщит вам, когда он закончится. Если вы думаете, что вам нужно всего четыре гигабайта памяти, запустите его  -Xmx4g и посмотрите, правы ли вы. Если вы ошибаетесь, перезапустите его с  XX:HeapDumpOnOutOfMemoryError включенным и посмотрите на дамп кучи, чтобы увидеть, где вы ошибаетесь.

Если вам нужно выжать из приложения все, что можно, от производительности, Epsilon может стать лучшим выбором для сборщика мусора. Но вам нужно иметь полное представление о том, как ваш код использует память. Если он почти не создает мусора или вы точно знаете, сколько памяти он использует за период, в течение которого он работает, Epsilon является приемлемым вариантом.

Сборщик мусора Z

Что такое сборщик мусора Z?

ZGC — сборщик мусора с малой задержкой, предназначенный для работы с огромными объемами памяти. Документация Oracle ссылается на многотерабайтные кучи в своем описании Z. Oracle представила ZGC в Java 11. В Java 12 Oracle добавила исправления производительности и выгрузку классов, хотя Z все еще находится в экспериментальном состоянии. Он доступен только в 64-разрядной версии Linux.

Как работает ЗГК?

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

ZGC использует преимущества 64-битных указателей с помощью метода, называемого раскрашиванием указателей. Цветные указатели хранят дополнительную информацию об объектах в куче. (Это одна из причин, по которой он ограничен 64-битной JVM.) Ограничив GC кучами размером 4 ТБ, разработчики получили 22 дополнительных бита в каждом указателе для кодирования дополнительной информации. В настоящее время Z использует четыре дополнительных бита. Каждый указатель имеет бит для финализации, переназначения, метки0 или метки1.

Сборщик мусора Z переназначает объекты, когда память становится фрагментированной. Сопоставление позволяет избежать снижения производительности, когда сборщику мусора требуется найти место для нового выделения. Цвет указателя помогает при переназначении, поскольку переназначенная ссылка обнаруживает новое местоположение при следующем доступе.

Когда ваше приложение загружает ссылку из кучи, ZGC проверяет лишние биты. Если ему нужно выполнить какую-либо дополнительную работу (например, получить переназначенный экземпляр), он обрабатывает ее в барьере нагрузки. Это нужно сделать только один раз, когда он загружает ссылку. Это отличает его от барьеров записи, используемых основными сборщиками мусора, такими как G1.

Сборщик мусора Z выполняет свои циклы в своих потоках. Он приостанавливает приложение в среднем на 1 мс. Сборщики G1 и Parallel в среднем составляют около 200 мс.

Как использовать ЗГК

Параметры командной строкиПримечания
 -XX:+UnlockExperimentalVMOptions Разблокируйте экспериментальные возможности Java
 -XX:+UseZGC Используйте ЗГК.
 -XmxXg Установить размер кучи.
 -XX:ConcGCThreads=X Установить количество потоков GC

ZGC — это параллельный сборщик мусора, поэтому установка правильного размера кучи очень важна. Куча должна быть достаточно большой для размещения вашего приложения, но также нуждается в дополнительном запасе, чтобы Z мог удовлетворять новые запросы при перемещении активных объектов. Объем необходимого запаса зависит от того, насколько быстро ваше приложение запрашивает новую память.

ZGC сам попытается установить количество потоков, и обычно это правильно. Но если у ZGC слишком много потоков, ваше приложение будет голодать. Если его недостаточно, вы создадите мусор быстрее, чем сборщик мусора сможет его собрать.

Зачем использовать ZGC?

Дизайн ZGC хорошо работает с приложениями большого размера кучи. Он управляет этими кучами с временем паузы менее 10 мс и незначительно влияет на пропускную способность. Эти времена лучше, чем у G1.

ZGC выполняет маркировку в три этапа. Первая — это короткая фаза остановки мира. Он проверяет корни GC, локальные переменные, которые указывают на остальную часть кучи. Общее количество этих корней обычно минимально и не масштабируется с размером нагрузки, поэтому паузы ZGC очень короткие и не увеличиваются по мере роста вашей кучи.

После завершения начальной фазы ZGC переходит к параллельной фазе. Он проходит по графу объектов и исследует цветные указатели, отмечая доступные объекты. Барьер нагрузки предотвращает конкуренцию между фазой сборки мусора и активностью любого приложения.

После того, как ZGC завершил маркировку, он перемещает живые объекты, чтобы освободить большие разделы кучи для более быстрого выделения памяти. Когда начинается фаза перемещения, ZGC делит кучу на страницы и работает с одной страницей за раз. Как только ZGC завершает перемещение всех корней, остальная часть перемещения происходит в параллельной фазе.

Фазы ZGC иллюстрируют, как он управляет большими кучами, не влияя на производительность по мере роста памяти приложения.

Шенандоа

Что такое Шенандоа?

Shenandoah — еще один сборщик мусора с коротким временем паузы. Эти времена короткие и предсказуемые, независимо от размера кучи. Shenandoah был разработан в Red Hat и существует уже несколько лет. Теперь это часть выпуска Java 12.

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

Как работает Шенандоа?

Дизайн Shenandoah обменивает параллельные циклы ЦП и пространство на улучшение времени паузы. Указатель переадресации упрощает перемещение объектов, но агрессивные перемещения означают, что Shenandoah использует больше памяти и требует больше параллельной работы, чем другие сборщики мусора. Но он выполняет дополнительную работу с очень короткими паузами в стиле «останови мир».

Фазы Шенандоа

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

Первая фаза содержит первую остановку мира в цикле. Он подготавливает кучу для одновременной маркировки и сканирует корневой набор. Как и в ZGC, длина этой паузы соответствует размеру корневого набора, а не кучи. Затем на параллельной фазе выполняется обход кучи и идентификация доступных и недоступных объектов.

Третий завершает процесс маркировки, сливая ожидающие обновления кучи и повторно сканируя корневой набор. Эта фаза запускает вторую паузу в цикле «останови мир». Количество ожидающих обновлений и размер корневого набора определяют продолжительность паузы.

Затем другая параллельная фаза копирует объекты из регионов, определенных на последней фазе маркировки. Этот процесс отличает Shenandoah от других сборщиков мусора, поскольку он агрессивно сжимает кучу параллельно с потоками приложения.

Следующая фаза запускает третью (и самую короткую) паузу в цикле. Это гарантирует, что все потоки GC завершили эвакуацию. По завершении параллельная фаза проходит по куче и обновляет ссылки на объекты, перемещенные ранее в цикле.

Последняя пауза в цикле «останови мир» завершает обновление ссылок путем обновления корневого набора. В то же время он утилизирует эвакуированные регионы. Наконец, последняя фаза восстанавливает эвакуированные регионы, в которых теперь нет ссылок.

Как использовать Шенандоа

Параметры командной строкиПримечания
 -XX:+UnlockExperimentalVMOptions Разблокируйте экспериментальные возможности Java.
 -XX:+UseShenanodoahC Используйте Шенандоа GC.
 -XmxXg Установить размер кучи.
 -XX:ShenandoahGCHeuristics=  Выберите эвристику.

Эвристика Шенандоа

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

1. Адаптивный : наблюдает за циклами GC и запускает следующий цикл, чтобы он завершился до того, как приложение исчерпает кучу. Эта эвристика является режимом по умолчанию.

2. Статический . Запускает цикл сборки мусора в зависимости от занятости кучи и давления на выделение.

3. Компактный : Непрерывно запускает циклы ГХ. Shenandoah начинает новый цикл, как только заканчивается предыдущий или на основе объема кучи, выделенной с момента последнего цикла. Эта эвристика влечет за собой накладные расходы на пропускную способность, но обеспечивает наилучшее высвобождение пространства.

Режимы отказа

Shenandoah должен собирать кучу быстрее, чем приложение, которое он обслуживает, выделяет его. Если давление выделения слишком велико и для новых выделений недостаточно места, произойдет сбой. У Shenandoah есть настраиваемые механизмы для этой ситуации.

  • Шаг : если Shenandoah начинает отставать от скорости выделения, потоки выделения останавливаются, чтобы наверстать упущенное. Прилавков обычно достаточно для умеренных всплесков распределения. Shenandoah вводит задержки в 10 мс или меньше. Если стимуляция не удалась, Шенандоа перейдет к следующему этапу: вырожденному GC.
  • Вырожденный GC : если происходит сбой распределения, Shenandoah запускает фазу остановки мира. Он использует фазу для завершения текущего цикла GC. Поскольку остановивший мир не соперничает с заявкой на ресурсы, цикл должен завершиться быстро и устранить дефицит распределения. Часто вырожденный цикл происходит после того, как большая часть работы цикла уже завершена, поэтому остановка мира непродолжительна. Однако журнал GC сообщит об этом как о полной паузе.
  • Полный GC : если и стимуляция, и вырожденный GC терпят неудачу, Шенандоа возвращается к полному циклу GC. Этот окончательный сборщик мусора гарантирует, что приложение не завершится с ошибкой нехватки памяти, если не останется кучи.

Зачем использовать Шенандоа?

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

Хотя Shenandoah не был доступен как часть Java до версии 12, он существует дольше, чем ZGC. Он прошел больше тестов и даже доступен в качестве резервной копии для Java 8 и 10.

Заключение

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

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

Низкая производительность или высокие накладные расходы из-за вызовов System.gc()

Проблема

Накладные расходы на сборку мусора могут быть довольно высокими, или на производительность может повлиять частая сборка мусора из-за пользовательских запросов от вызовов System.gc().

Симптом

Высокие накладные расходы на сборку мусора в случаях, когда куча не страдает сбоями выделения.

Причина

Код приложения вызывает System.gc();

Диагностика проблемы

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

Решение проблемы

Чтобы снизить нагрузку на производительность, введите следующий общий аргумент JVM:

-Xdisableexplicitgc

Подробные сведения об общих аргументах JVM см. в этой технической заметке
«Настройка общих аргументов JVM в WebSphere Application Server» http://www.ibm.com/support/docview .wss?rs=180&uid=swg21417365 Чтобы идентифицировать вызовы из кода приложения, которые выдают явные запросы на сборку мусора, введите следующий параметр -Xtrace в качестве общего аргумента JVM: -Xtrace:print=mt,methods={java/lang /System.gc}, триггер = метод {java/lang/System.gc, jstacktrace}

Xtrace будет регистрировать вызовы методов в файле native_stderr.log. Трассировка покажет вызовы даже с включенным параметром -Xdisableexplicitgc. Трассировку стека следует использовать для поиска источника явных запросов на сборку мусора в коде приложения.

После обновления кода приложения для удаления явных запросов на сборку мусора удалите упомянутые выше универсальные аргументы JVM

Java. System.gc(); Эффективность.

После ответа на вопрос о том, как принудительно освобождать объекты в Java (парень очищал HashMap размером 1,5 ГБ) с помощью System.gc(), мне сказали, что вызывать System.gc() вручную — плохая практика, но комментарии не были вполне убедительно. Вдобавок, похоже, никто не осмелился проголосовать ни за, ни против моего ответа.

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

Я понимаю, что JVM обычно лучше вас знает, когда ей нужно освободить память. Я также понимаю, что беспокоиться о нескольких килобайтах данных глупо. Я также понимаю, что даже мегабайты данных уже не те, что были несколько лет назад. Но все же, 1,5 гигабайта? И вы знаете, что в памяти висит около 1,5 ГБ данных; это не похоже на выстрел в темноте. Является ли System.gc() систематически плохой или есть какой-то момент, когда все становится хорошо?

Так что вопрос на самом деле двойной:

Почему вызов System.gc() является плохой практикой? Это действительно просто намек на JVM в определенных реализациях или это всегда полный цикл сбора? Существуют ли действительно реализации сборщиков мусора, которые могут выполнять свою работу, не останавливая мир? Пожалуйста, пролейте свет на различные утверждения, сделанные людьми в комментариях к моему ответу.
Где порог? Никогда не стоит вызывать System.gc() или бывают случаи, когда это допустимо? Если да, то какие это времена?

Причина, по которой все всегда говорят избегать System.gc(), заключается в том, что это довольно хороший индикатор фундаментально неработающего кода. Любой код, корректность которого зависит от него, безусловно, неисправен; любые, которые полагаются на него для производительности, скорее всего, сломаны.

Вы не знаете, под каким сборщиком мусора вы работаете. Конечно, есть некоторые, которые не «останавливают мир», как вы утверждаете, но некоторые JVM не такие умные или по разным причинам (возможно, они на телефоне?) этого не делают. Вы не знаете, что это будет делать.

Кроме того, ничего не гарантировано. JVM может просто полностью проигнорировать ваш запрос.

Комбинация «вы не знаете, что он сделает», «вы не знаете, поможет ли он вообще» и «вам все равно не нужно вызывать его» — вот почему люди так настойчиво говорят, что обычно Вы не должны называть это. Я думаю, что это случай «если вам нужно спросить, следует ли вам использовать это, вы не должны»

РЕДАКТИРОВАТЬ, чтобы решить несколько проблем из другого потока:

После прочтения темы, на которую вы ссылаетесь, есть еще несколько вещей, которые я хотел бы отметить. Во-первых, кто-то предположил, что вызов gc() может вернуть память системе. Это, конечно, не обязательно верно — сама куча Java растет независимо от выделений Java.

Например, JVM будет хранить память (многие десятки мегабайт) и увеличивать кучу по мере необходимости. Это не обязательно возвращает эту память системе, даже когда вы освобождаете объекты Java; можно совершенно свободно удерживать выделенную память для использования в будущих распределениях Java.

Чтобы показать, что System.gc() может ничего не делать, просмотрите ошибку JDK 6668279 и, в частности, наличие опции -XX:DisableExplicitGC VM:

По умолчанию вызовы System.gc() включены (-XX:-DisableExplicitGC). Используйте -XX:+DisableExplicitGC, чтобы отключить вызовы System.gc(). Обратите внимание, что JVM по-прежнему выполняет сборку мусора, когда это необходимо.

Уже было объяснено, что вызов system.gc() может ничего не дать, и что любой код, который «нуждается» в сборщике мусора для работы, сломан.

Однако прагматическая причина, по которой вызов System.gc() является плохой практикой, заключается в том, что это неэффективно. А в худшем случае — ужасно неэффективно! Позвольте мне объяснить.

Типичный алгоритм GC определяет мусор, обходя все не-мусорные объекты в куче и делая вывод, что любой объект, который не был посещен, должен быть мусором. Исходя из этого, мы можем смоделировать общую работу сборки мусора, состоящую из одной части, пропорциональной количеству живых данных, и другой части, пропорциональной количеству мусора; то есть work = (live * W1 + garbage * W2).

Теперь предположим, что вы делаете следующее в однопоточном приложении.

System.gc(); System.gc();
Первый вызов (по нашим прогнозам) выполнит работу (live * W1 + garbage * W2) и избавится от оставшегося мусора.

Второй вызов выполнит работу (live * W1 + 0 * W2) и ничего не вернет. Другими словами, мы проделали (live * W1) работу и не достигли абсолютно ничего.

Мы можем представить эффективность сборщика как количество работы, необходимое для сбора единицы мусора; т.е. эффективность = (live * W1 + garbage * W2) / garbage. Поэтому, чтобы сделать GC максимально эффективным, нам нужно максимизировать значение мусора, когда мы запускаем GC; т.е. ждать, пока куча не заполнится. (А также сделать кучу как можно больше. Но это отдельная тема).

Если приложение не вмешивается (вызывая System.gc()), GC будет ждать, пока куча не заполнится перед запуском, что приведет к эффективной сборке мусора1. Но если приложение заставляет GC запускаться, есть вероятность, что куча не будет заполнена, и в результате мусор будет собираться неэффективно. И чем чаще приложение заставляет GC, тем более неэффективным становится GC.

Примечание: приведенное выше объяснение не учитывает тот факт, что типичный современный GC разделяет кучу на «пространства», GC может динамически расширять кучу, рабочий набор не-мусорных объектов приложения может меняться и так далее. Тем не менее, один и тот же основной принцип применим ко всем настоящим сборщикам мусора2. Заставлять GC работать неэффективно.

xubuntu lightdm error

Random logout (Xorg crashing?)
Падает Xorg
Внезапный рестарт сессии xubunta
Рестарт иксов
Падают иксы
Крах(рестарт) Xfce

Смотрим логи

>journalctl -S «2022-03-05 12:10» -U «2022-03-05 22:00»

И видим красные строки

lightdm[19715]: PAM unable to dlopen(pam_kwallet.so): /lib/security/pam_kwallet.so: cannot open shared object file: No such file or directory
lightdm[19715]: PAM adding faulty module: pam_kwallet.so
lightdm[19715]: PAM unable to dlopen(pam_kwallet5.so): /lib/security/pam_kwallet5.so: cannot open shared object file: No such file or directory
lightdm[19715]: PAM adding faulty module: pam_kwallet5.so

Поскольку эта штука глючная и бороться с ней дело неблагодарное, то отключаем ее и живем счастливо.

  1. Редактируем два файла /etc/pam.d/lightdm и /etc/pam.d/lightdm-greeter 
    Коментируем # или вообще удаляем строки
    auth    optional        pam_kwallet.so
    auth    optional        pam_kwallet5.so
    session optional        pam_kwallet.so auto_start
    session optional        pam_kwallet5.so auto_start
    2. Перезапускаем  systemctl restart lightdm

Linux, sqlplus, нет такого файла или каталога

После установки не запускается sqlplus /nolog
Ошибка: sqlplus: command not found

  1. Проверяем наличие переменных окружения
    ORACLE_HOME
    LD_LIBRARY_PATH
    PATH
    Что в них писать, вроде, не проблема — куча статей и документации. Например:
ORACLE_HOME=/opt/oracle/19.2/client
PATH=$ORACLE_HOME/bin:$PATH
LD_LIBRARY_PATH=$ORACLE_HOME:$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export ORACLE_HOME
export LD_LIBRARY_PATH
export PATH
  1. Следующая возможная ошибка

sqlplus: error while loading shared libraries: libsqlplus.so: cannot open shared object file: No such file or directory

Устанавливаем нужную библиотеку. А вот тут практически все статьи умалчивают одну маленькую деталь. Нужная библиотека — libsqlplus.so или libaio или libaio1. Пример установки:

sudo apt-get install libaio1

И нигде не уточняют, что это 64 бита. Но если вы установили 32-битный клиент, то вам это не поможет. А поможет

sudo apt-get install libaio1:i386

Selenium, java, timezone

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

Предлагаю такое решение:

Calendar c = Calendar.getInstance();
c.setTime(new Date());
System.out.println(«Europe zone: » + TimeZone.getTimeZone(«CET»));
System.out.println(«Local zone: » + TimeZone.getDefault());

int europeOffset = TimeZone.getTimeZone(«CET»).getOffset(System.currentTimeMillis());
int localOffset = TimeZone.getDefault().getOffset(System.currentTimeMillis());

System.out.println(«Europe offset: » + amsOffset);
System.out.println(«Local offset: » + localOffset);
int delta = (europeOffset — localOffset) / 60000;
System.out.println(delta + » min»);

c.add(Calendar.MINUTE, delta);

Date currentDate = c.getTime();
System.out.println(«date today = » + currentDate);

Здесь «СЕТ» — часовой пояс на frontend. Его можно передавать как параметр, а можно и правильно хранить в файле property каждого сервера с которым может работать тест.

P.S. Да, летнее /зимнее время тут учтено!

Selenium, Java, E-mail, pop3

Добавляем в зависимости Мавена

<!-- http://repo1.maven.org/maven2/javax/mail/javax.mail-api/1.5.6/javax.mail-api-1.5.6.jar -->
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>javax.mail-api</artifactId>
    <version>1.6.2</version>
</dependency>
<!-- http://repo1.maven.org/maven2/javax/mail/mail/1.4.7/mail-1.4.7.jar -->
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.7</version>
</dependency>
  1. Setup properties for the mail session.
  2. Creates a javax.mail.Authenticator object.
  3. Creating mail session.
  4. Get the POP3 store provider and connect to the store.
  5. Get folder and open the INBOX folder in the store.
  6. Retrieve the messages from the folder.
  7. Close folder and close store.

Выглядит все просто, но из коробки не завелось. Вылезла странная проблема с кодировкой Subject-a писем.

Selenium, Java, время на Frontend

Проблема:
1. Тест может запускаться из разных часовых поясов — локально, на разных серверах с Jenkins.
2. Тест может проверять разные инстансы фронтенда — Demo, Staging, Production.
Всё это может находиться в разных часовых поясах

Задача: тест должен оперировать/определять время фронтенда с которым он работает.

Calendar c = Calendar.getInstance();
c.setTime(new Date());
System.out.println(«Europe zone: » + TimeZone.getTimeZone(«CET»));
System.out.println(«Local zone: » + TimeZone.getDefault());

int europeOffset = TimeZone.getTimeZone(«CET»).getOffset(System.currentTimeMillis());
int localOffset = TimeZone.getDefault().getOffset(System.currentTimeMillis());

System.out.println(«Europe offset: » + amsOffset);
System.out.println(«Local offset: » + localOffset);
int delta = (europeOffset — localOffset) / 60000;
System.out.println(delta + » min»);

c.add(Calendar.MINUTE, delta);

Date currentDate = c.getTime();
System.out.println(«date today = » + currentDate);

Здесь в коде часовой пояс захардкожен. Правильно брать его из параметров фронденда. Но это уже сами ))).

Selenium и iframe

Хром в панели разработчика находит элемент по xPath, а Selenium не хочет по нему кликать и ругается, что элемент не найден.

Проблема в iframe. Selenium не видит элементы внутри iframe. Надо переключить фокус туда. Ну и не забыть потом вернуться.

driver.switchTo().frame(driver.findElement(By.xpath(«//iframe[@id=’iframeM’]»)));
driver.findElement(By.xpath(«//*[@id=’12345′]»)).click(); driverWrapper.switchTo().defaultContent();

Не успевает отработать Click

Исходные данные: автотест на java selenium. Столкнулся с ситуацией что после клика происходит долгая обработка данных и Selenium падает по таймауту. Перелопатил интернет, перепробовал все ожидания — явные, не явные и все другие включая банальную паузу:

            driver.manage().timeouts().setScriptTimeout(180, TimeUnit.SECONDS);
            driver.manage().timeouts().implicitlyWait(180, TimeUnit.SECONDS);
            driver.manage().timeouts().pageLoadTimeout(180, TimeUnit.SECONDS);

Ничего из этого не помогает. Автотест висит на клике, не переходит к следующей команде, а по истечению времени ожидания — падает.

Решение проблемы пришло с неожиданной для меня стороны и оказалось, как и все гениальное ), простым.

try {
                    driver.findElement(By.xpath("//*[@id='a_do_import']")).click();
                } catch (Exception exception) {
                    logger.info("Exception was catch, is waiting 2 min.");
                    new Pause("120000").act(driver, context, reporter);
                    logger.info("Reload page.");
                    ...
}

Ловим и обрабатываем ошибку сами.