我正在尝试使用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
答案 0 :(得分:0)
您的代码使用非常复杂的逻辑,可能错误的逻辑用于初始化Logger
,由于这个逻辑,您得到了这样的错误。
当您取消注释System.out.println(Utils.hello);
行 -
main()
方法执行开始。System.out.println(Utils.hello);
行时,Java class loader
会尝试加载Utils class
以访问hello static variable
。Utils class
期间,所有static variables
都已初始化,包括logger variable
。现在,由于您使用JDBC appender
进行log4j2
配置,LogManager
尝试通过调用ConnectionFactory.getDatabaseConnection()
方法来获取数据库连接。
在ConnectionFactory.getDatabaseConnection()
方法调用中,调用此单例类的构造函数。
Utils.initProperties()
方法。Utils.initProperties()
方法中,您使用的是logger static variable
,但实际上,您的logger static variable
仍未初始化,因此,当您使用NullPointerException
时{1}}在此方法中。现在,要解决此问题,您应该更改逻辑以打破此链。一种解决方案是不在logger
中使用Logger
。但是,您还需要检查其他可能的情况。