java.util.logging.LogManager.getLogger() возвращает ноль
У меня есть проблема, которая действительно сбивает меня с толку. Я хотел попробовать кое-что с регистрацией JUL (регистрация JDK). Я начал со следующей простой программы:
package biz.ple;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class Application {
public static void main(String[] args)
{
Logger logA = LogManager.getLogManager().getLogger("LoggerA");
Logger logB = LogManager.getLogManager().getLogger("LoggerB");
if (logA == null) {
System.out.println("LoggerA is null!");
}
if (logB == null) {
System.out.println("LoggerB is null!");
}
String normalMsg = "Message without cookie prefix.";
String cookieMsg = "[Cookie] Message with a cookie prefix.";
logA.info(normalMsg);
logA.info(cookieMsg);
logB.info(normalMsg);
logB.info(cookieMsg);
}
}
Удивительно, но логгеры logA и logB всегда равны нулю. Я прочитал в документации, что регистратор, на который приложение не имеет строгой ссылки, может быть GCed в любое время, но мне кажется, что переменные logA и logB действительно являются сильными ссылками, не так ли?
Я действительно не понимаю этого и буду признателен за любую помощь.
3 ответа
Насколько я понимаю, это будут только существующие регистраторы, а не создание нового с таким именем. Для создания нового регистратора необходимо использовать статический Logger.getLogger("myLogger");
команда
public static void main(String[] args){
Logger log=Logger.getLogger("myLogger");
Logger logA = LogManager.getLogManager().getLogger("myLogger"); //exists
Logger logB = LogManager.getLogManager().getLogger("nonExistantLogger"); //is null
}
Logger.getLogger("myLogger") javadoc:
Найдите или создайте регистратор для именованной подсистемы. Если регистратор уже был создан с заданным именем, он возвращается. В противном случае создается новый регистратор.
Если новый регистратор создан, его уровень журнала будет настроен на основе конфигурации LogManager, и он также будет настроен на отправку выходных данных журнала обработчикам его родителя. Он будет зарегистрирован в глобальном пространстве имен LogManager.
Примечание. LogManager может сохранять только слабую ссылку на только что созданный Logger. Важно понимать, что ранее созданный Logger с заданным именем может быть собран в любое время, если нет строгой ссылки на Logger. В частности, это означает, что при двух параллельных вызовах, таких как getLogger("MyLogger"). Log(...), могут использоваться разные объекты Logger с именем "MyLogger", если в другом месте нет сильной ссылки на Logger с именем "MyLogger". в программе.
LogManager.getLogManager (). GetLogger ("myLogger") javadoc
Способ найти именованный регистратор.
Обратите внимание, что поскольку ненадежный код может создавать регистраторы с произвольными именами, на этот метод не следует полагаться при поиске регистраторов для ведения журнала, чувствительного к безопасности. Также важно отметить, что Logger, связанный с именем String, может быть собран в любое время, если нет строгой ссылки на Logger. Вызывающая сторона этого метода должна проверить возвращаемое значение для нуля, чтобы правильно обработать случай, когда Logger был собран мусором.
Дайте имя класса, для которого вы хотите использовать регистратор, как показано ниже:
Logger logA = LogManager.getLogManager().getLogger(MyClass.class .getName());
У вас действительно есть сильная ссылка, поэтому они не были собраны мусором. Вы должны использовать API неправильно, так как он возвращает нулевые ссылки.