2019-02-20 17:29

@JFinal 终与找到最终凶手了,是undertow中使用了org.jboss.logging,在

com.jfinal.server.undertow.UndertowServer类
547行:di.setResourceManager(config.getResourceManager());

com.jfinal.server.undertow.UndertowConfig类
264行:return new ResourceManagerBuilder().build(resourcePath, getClassLoader());

com.jfinal.server.undertow.ResourceManagerBuilder类
49行:buildFileResourceManager(resourcePathList, classLoader, ret);
87行:ret.add(createFileResourceManager(path));

com.jfinal.server.undertow.ResourceManagerBuilder类
99行:return new FileResourceManager(new File(path), 1024, false);

用到了类
io.undertow.server.handlers.resource.FileResourceManager
该类继承自
io.undertow.server.handlers.resource.PathResourceManager
该类31行:private static final Logger log = Logger.getLogger(PathResourceManager.class.getName());
用到了
org.jboss.logging.Logger类
2465行:return LoggerProviders.PROVIDER.getLogger(name);
用到了
org.jboss.logging.LoggerProviders类
此类中有个static变量PROVIDER,该变量的初始化核心代码即尝试使用各种log框架,因为了项目引入了log4j所以匹配到了log4j,加载了log4j,log4j检查配置文件抛出了该警告。

由于包括jfinal在内的所有框架并没有固定使用某个log框架,所以是由于项目引入了log4j,log4j的配置文件也应该由项目提供,所以说都没有毛病。只需要在
UndertowServer.start(AppConfig.class);
运行前设置一个默认的log4j配置文件即可。

我在项目里面有两种方式可以解决:
1、使用默认的log4j配置文件位置resource根目录和默认配置文件名称log4j.properties
2、设置环境变量log4j.configuration指定配置文件:
System.setProperty("log4j.configuration","config/debug.log4j.properties");

最终我的解决方案为:
使用默认位置默认名称的配置文件作为开发配置,另外的名称为生产配置,在JfinalConfig类中初始化常量时,判断当不为开发模式时,主动加载生产配置:
if (SysConfig.isSysDevModel()) {
PropertyConfigurator.configure(PathKit.getRootClassPath() + "release.log4j.properties");
}

感谢波总,我应该坚持自己查找问题的根源而不急于“拿来主义”

2019-02-20 15:48

@JFinal 你没理解到我的意思,我没有其他多余的filter,我是在JFinalConfig类中初始化常量的configConstant方法中根据devMode来选择加载的log4j配置文件的,但是项目一启动就会打印出警告,我看了源码,是因为在JfinalFilter中有个static的Log对象,在Log类中有个static块,里面就加载了log4j,就是在那报的警告。

我的核心代码就这一句:
PropertyConfigurator.configure(PathKit.getRootClassPath() + "/config/" + (SysConfig.isSysDevModel() ? "debug" : "release") + ".log4j.properties");

2018-12-12 15:18

@JFinal 如果要选,我希望model和Db都加,哈哈哈哈

2018-07-03 19:03

一般有两种方式:
1、websocket
2、轮训

2018-07-03 16:47

@JFinal 确实,考虑一下嘛,将来如果有这个功能就赞了,这个项目遇到这种需求很多次了,现在是通过:

if(Db.tx(...)){
Db.tx(....);
}else{
Db.tx(....);
}

这种方式来处理的。

2018-07-03 11:00

@JFinal 新开一个线程拿不到状态了,而且变成异步的,可能会涉及到线程通信。jfinal以后能不能提供一个支持基于连接的事务处理。如:
Connection conn = DbKit.getConfig().getDataSource().getConnection();
Db.tx(new IAtom(conn) {
@Override
public boolean run(Connection newConnection) throws SQLException {
SysTask sysTask = new SysTask();
sysTask.use(newConnection);
sysTask.update();
sysTask.save();
sysTask.update();
return true;
}
});

或者:
Db.tx(new IAtomNew() {
@Override
public boolean run(Connection newConnection) throws SQLException {
SysTask sysTask = new SysTask();
sysTask.use(newConnection);//显示指定连接
sysTask.update();
sysTask.save();
sysTask.update();
return true;
}
});

这样就能随心所欲的处理嵌套逻辑了,默认使用当前线程连接,也可以支持使用新的连接。

2018-07-03 09:23

@欲风217 这个思路是正统,只是这个项目以前不是异步的,是简单重构后这样子的。只是采用了简答的多线程异步处理。