JDBC Appender log4j2错误

时间:2017-06-09 10:25:29

标签: java log4j2

我正在尝试使用log4j2将错误记录到PostgreSQL数据库中。虽然我能做到这一点,但我有一个疑问。

(案例:0)如果我尝试按原样运行显示的代码,它不会给出任何错误。

(案例:1)但是,如果我取消注释' System.out.println(Utils.hello);'它显示空指针异常。我认为这主要是因为在Utils类中记录器为空。我正在初始化它,但不知道为什么会发生这种情况。

我尝试调试它(在例如:1)并发现logger变量已初始化,并且每当控件到达System.out.println(Utils.hello)'时,它变为空值。我只是想知道这里发生了什么(不是如何登录到DB的解决方案)。对于上述两种情况,内部实际发生了什么?为什么'案例:1'给出错误。提前致谢。 : - )

主要功能:

public class Main {
public static void main(String[] args)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException {
    System.out.println("aa");
    System.out.println(Utils.class);
    //System.out.println(Utils.hello);
    if (args.length == 0) {
        ...
    } else {
        Processing procObj = new Processing();      
    }
}

Utils Class:

public class Utils {

public static Properties prop;
static InputStream input;
public static org.apache.logging.log4j.Logger logger= LogManager.getLogger(Utils.class);
public static int hello = 10;

public static void initProperties() {
    System.out.println(logger);
    logger.traceEntry();
    prop = new Properties();
    input = null;
    try {
        input = new FileInputStream(prop.getClass().getResource("/config.properties").getPath());
        prop.load(input);
        logger.info("Successully completed initialization process.");
    } catch (IOException e) {
        logger.error("{} Error initializing from properties file. <{}>",Utils.prop.getProperty("utility"), e);
    } catch (Exception e) {
        logger.error("{} Error initializing from properties file. <{}>",Utils.prop.getProperty("utility"), e);
    }
}
}

ConnectionFactory Class:

  public class ConnectionFactory  implements ConnectionSource{
 private static interface Singleton {
  final ConnectionFactory INSTANCE = new ConnectionFactory();
 }

 private final DataSource dataSource;

 public ConnectionFactory() {
     Utils.initProperties();
  Properties properties = new Properties();
  properties.setProperty("user", "user");
  properties.setProperty("password", "password");

  GenericObjectPool pool = new GenericObjectPool();

  DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
   "url", properties);
  new PoolableConnectionFactory(connectionFactory, pool, null,
    "SELECT 1", 3, false, false,
    Connection.TRANSACTION_READ_COMMITTED);

  this.dataSource = new PoolingDataSource(pool);
 }

 public static Connection getDatabaseConnection() throws SQLException {
  return Singleton.INSTANCE.dataSource.getConnection();
 }

@Override
public Connection getConnection() throws SQLException {
    return Singleton.INSTANCE.dataSource.getConnection();
}
}

处理类:

public class Processing {
    String query;
    private static org.apache.logging.log4j.Logger logger = LogManager.getLogger(Processing.class);

    public Processing() {
        Utils.initProperties();
        ....
    }
    .....
    .....
    }

错误是:

  2017-06-09 16:38:32,318 main ERROR JdbcDatabaseManager JdbcManager{name=databaseAppender, bufferSize=0, tableName=error, columnConfigs=[{ name=key, layout=null, literal=-100, timestamp=false }, { name=create_date, layout=null, literal=null, timestamp=true }, { name=create_user, layout=%logger, literal=null, timestamp=false }, { name=error_message, layout=%msg, literal=null, timestamp=false }], columnMappings=[]} Could not perform database startup operations: java.sql.SQLException: Failed to obtain connection from factory method. java.sql.SQLException: Failed to obtain connection from factory method.
    at org.apache.logging.log4j.core.appender.db.jdbc.FactoryMethodConnectionSource$1.getConnection(FactoryMethodConnectionSource.java:108)
    at org.apache.logging.log4j.core.appender.db.jdbc.FactoryMethodConnectionSource.getConnection(FactoryMethodConnectionSource.java:54)
    at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.startupInternal(JdbcDatabaseManager.java:74)
    at org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager.startup(AbstractDatabaseManager.java:65)
    at org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender.start(AbstractDatabaseAppender.java:89)
    at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:260)
    at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:545)
    at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
    at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
    at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
    at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
    at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
    at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
    at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:551)
    at mypackage.Utils.<clinit>(Utils.java:19)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at mypackage.Main.main(Main.java:18)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.logging.log4j.core.appender.db.jdbc.FactoryMethodConnectionSource$1.getConnection(FactoryMethodConnectionSource.java:106)
    ... 17 more
Caused by: java.lang.ExceptionInInitializerError
    at mypackage.ConnectionFactory.getDatabaseConnection(ConnectionFactory.java:40)
    ... 22 more
Caused by: java.lang.NullPointerException
    at mypackage.Utils.initProperties(Utils.java:45)
    at mypackage.ConnectionFactory.<init>(ConnectionFactory.java:23)
    at mypackage.ConnectionFactory$Singleton.<clinit>(ConnectionFactory.java:17)
    ... 23 more

1 个答案:

答案 0 :(得分:0)

您的代码使用非常复杂的逻辑,可能错误的逻辑用于初始化Logger,由于这个逻辑,您得到了这样的错误。

当您取消注释System.out.println(Utils.hello);行 -

时,事情发生在幕后
  1. main()方法执行开始。
  2. 现在,当执行到System.out.println(Utils.hello);行时,Java class loader会尝试加载Utils class以访问hello static variable
  3. 在加载Utils class期间,所有static variables都已初始化,包括logger variable
  4. 现在,由于您使用JDBC appender进行log4j2配置,LogManager尝试通过调用ConnectionFactory.getDatabaseConnection()方法来获取数据库连接。

    < / LI>
  5. ConnectionFactory.getDatabaseConnection()方法调用中,调用此单例类的构造函数。

  6. 在构造函数体中,您正在调用Utils.initProperties()方法。
  7. Utils.initProperties()方法中,您使用的是logger static variable,但实际上,您的logger static variable仍未初始化,因此,当您使用NullPointerException时{1}}在此方法中。
  8. 现在,要解决此问题,您应该更改逻辑以打破此链。一种解决方案是不在logger中使用Logger。但是,您还需要检查其他可能的情况。