应该如何(以及为什么)初始化JUL配置类?

时间:2016-08-01 21:07:42

标签: java logging java.util.logging

我有一个使用args4j选项类(frontend.java)和JUL配置类(Options.java)的命令行工具(LogConfig.java)。因为在我的实际应用程序中,我需要查看和使用所选的选项以配置日志记录,我在frontend中有一个静态getter,它返回用户选择的各种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{
}

最后,配置类:

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类似乎在静态初始化设置之前得到了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:\>

在知道配置类需要完成什么之前,当主类必须有点活跃时,使用JUL日志配置类的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

创建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启动完成后自行重新创建配置类。然后,当getOptions返回null时,使LogConfig执行no-op。

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();
            }
        }
    }
}