JUL 配置 class 应该如何(以及为什么)初始化?
How (and why) should a JUL configuration class be initialized?
我有一个命令行工具 (frontend.java
) 使用 args4j 选项 class (Options.java
) 和 JUL 配置 class (LogConfig.java
) .因为在我的实际应用程序中,我需要查看和使用选定的选项来配置日志记录,所以我在 frontend
中有一个静态的 getter,returns 已选择的各种 args4j 选项用户。
frontend.java:
import java.util.logging.Logger;
public class frontend{
private static Logger log = Logger.getLogger(frontend.class.getName());
private static Options opts = new Options();
public frontend(){
System.out.println("Made a new front end");
}
public static Options getOptions(){
if(opts == null)
System.out.println("Opts was null");
else
System.out.println("Opts is not null");
return opts;
}
public static void main(String[] args) {
frontend fe = new frontend();
}
}
显然,下一个文件并不是真正的空白,但我不确定我是否需要此处的任何内容来说明我的问题所在。
Options.java:
public class Options{
}
最后,配置class:
LogConfig.java:
import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class LogConfig {
public LogConfig() {
Options opts = frontend.getOptions();
try {
LogManager.getLogManager().readConfiguration(new FileInputStream("logging.properties"));
}catch (SecurityException e) {
System.err.println("Problem accessing log config file: "
+ e.getMessage());
} catch (IOException e) {
System.err.println("Problem loading log config file: "
+ e.getMessage());
}
}
}
我的问题是 LogConfig
class 似乎在静态初始化设置之前获取了 opts
变量:
Output:
c:\>java -cp . frontend
Made a new front end
Opts is not null
c:\>java -Djava.util.logging.config.class=LogConfig -cp . frontend
Opts was null
Made a new front end
Opts is not null
c:\>
当您的主程序 class 在您知道您的配置 class 需要完成什么之前必须有点活跃时,使用 JUL 日志配置 class 的最佳方法是什么?
创建 Logger 会触发 LogManager 启动。延迟创建您的记录器,直到您需要使用它。
public class frontend {
private static volatile Logger log;
private static Options opts = new Options();
public frontend() {
System.out.println("Made a new front end");
}
public static Options getOptions() {
if (opts == null) {
System.out.println("Opts was null");
} else {
System.out.println("Opts is not null");
}
return opts;
}
public static void main(String[] args) {
frontend fe = new frontend();
log = Logger.getLogger(frontend.class.getName());
}
}
否则,您可以在 LogManager 启动完成后自己重新创建配置 class。然后让您的 LogConfig 在 getOptions returns null.
时执行空操作
public class frontend {
private static final Logger log = Logger.getLogger(frontend.class.getName());
private static Options opts = new Options();
public frontend() {
System.out.println("Made a new front end");
}
public static Options getOptions() {
if (opts == null) {
System.out.println("Opts was null");
} else {
System.out.println("Opts is not null");
}
return opts;
}
public static void main(String[] args) {
frontend fe = new frontend();
init();
}
private static void init() {
String n = System.getProperty("java.util.logging.config.class");
if (n != null) {
try { //LogManager uses the system class loader.
Class<?> k = Class.forName(n, false,
ClassLoader.getSystemClassLoader());
k.newInstance();
} catch (ReflectiveOperationException | LinkageError ignore) {
ignore.printStackTrace();
}
}
}
}
我有一个命令行工具 (frontend.java
) 使用 args4j 选项 class (Options.java
) 和 JUL 配置 class (LogConfig.java
) .因为在我的实际应用程序中,我需要查看和使用选定的选项来配置日志记录,所以我在 frontend
中有一个静态的 getter,returns 已选择的各种 args4j 选项用户。
frontend.java:
import java.util.logging.Logger;
public class frontend{
private static Logger log = Logger.getLogger(frontend.class.getName());
private static Options opts = new Options();
public frontend(){
System.out.println("Made a new front end");
}
public static Options getOptions(){
if(opts == null)
System.out.println("Opts was null");
else
System.out.println("Opts is not null");
return opts;
}
public static void main(String[] args) {
frontend fe = new frontend();
}
}
显然,下一个文件并不是真正的空白,但我不确定我是否需要此处的任何内容来说明我的问题所在。
Options.java:
public class Options{
}
最后,配置class:
LogConfig.java:
import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class LogConfig {
public LogConfig() {
Options opts = frontend.getOptions();
try {
LogManager.getLogManager().readConfiguration(new FileInputStream("logging.properties"));
}catch (SecurityException e) {
System.err.println("Problem accessing log config file: "
+ e.getMessage());
} catch (IOException e) {
System.err.println("Problem loading log config file: "
+ e.getMessage());
}
}
}
我的问题是 LogConfig
class 似乎在静态初始化设置之前获取了 opts
变量:
Output:
c:\>java -cp . frontend
Made a new front end
Opts is not null
c:\>java -Djava.util.logging.config.class=LogConfig -cp . frontend
Opts was null
Made a new front end
Opts is not null
c:\>
当您的主程序 class 在您知道您的配置 class 需要完成什么之前必须有点活跃时,使用 JUL 日志配置 class 的最佳方法是什么?
创建 Logger 会触发 LogManager 启动。延迟创建您的记录器,直到您需要使用它。
public class frontend {
private static volatile Logger log;
private static Options opts = new Options();
public frontend() {
System.out.println("Made a new front end");
}
public static Options getOptions() {
if (opts == null) {
System.out.println("Opts was null");
} else {
System.out.println("Opts is not null");
}
return opts;
}
public static void main(String[] args) {
frontend fe = new frontend();
log = Logger.getLogger(frontend.class.getName());
}
}
否则,您可以在 LogManager 启动完成后自己重新创建配置 class。然后让您的 LogConfig 在 getOptions returns null.
时执行空操作public class frontend {
private static final Logger log = Logger.getLogger(frontend.class.getName());
private static Options opts = new Options();
public frontend() {
System.out.println("Made a new front end");
}
public static Options getOptions() {
if (opts == null) {
System.out.println("Opts was null");
} else {
System.out.println("Opts is not null");
}
return opts;
}
public static void main(String[] args) {
frontend fe = new frontend();
init();
}
private static void init() {
String n = System.getProperty("java.util.logging.config.class");
if (n != null) {
try { //LogManager uses the system class loader.
Class<?> k = Class.forName(n, false,
ClassLoader.getSystemClassLoader());
k.newInstance();
} catch (ReflectiveOperationException | LinkageError ignore) {
ignore.printStackTrace();
}
}
}
}