JFinal异常:The Table mapping of model not exists(3)

33号小人物 发布于 2015/09/17 16:22
阅读 302
收藏 1

前文1 前文2

现在终于找到根源了,在使用启动JFinalConfig中,查看到的ClassLoader为:

Config的ClassLoader是sun.misc.Launcher$AppClassLoader@11eb50b
Config的ClassLoader的父类是sun.misc.Launcher$ExtClassLoader@10014f0
Config的ClassLoader的父类的父类是null

而在运行定时任务是,查看到的ClassLoader为:

Change的ClassLoader是WebAppClassLoader=32845085@1f52d1d
Change的ClassLoader的父类是sun.misc.Launcher$AppClassLoader@11eb50b
Change的ClassLoader的父类的父类是sun.misc.Launcher$ExtClassLoader@10014f0

所以,问题的根源是,JFinalConfig启动的时候,没有使用Jetty的WebAppClassLoader导致的。

@JFinal 你好,想跟你请教个问题:如何才可以把JFinalConfig启动时的ClassLoader限定为WebAppClassLoader

问题补充:

这是另一个项目的启动日志,同样使用了定时任务,项目可以正常运行:

Config的ClassLoader是sun.misc.Launcher$AppClassLoader@5e9e34
Starting JFinal 1.9
Starting scanner at interval of 5 seconds.
Starting web server on port: 80
2015-09-17 21:20:57
[INFO]-[Thread: main]-[org.eclipse.jetty.server.Server.doStart()]: jetty-8.1.8.v20121106
2015-09-17 21:20:58
[INFO]-[Thread: main]-[org.eclipse.jetty.webapp.StandardDescriptorProcessor.visitServlet()]: NO JSP Support for /bocp, did not find org.apache.jasper.servlet.JspServlet
2015-09-17 21:20:58
[INFO]-[Thread: main]-[org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized()]: started o.e.j.w.WebAppContext{/bocp,file:/D:/Eclipse/workspace_j2ee/bocp/src/webapp/}
2015-09-17 21:20:58
[INFO]-[Thread: main]-[com.nfjd.bocp.task.B2pCheckListener.contextInitialized()]: 系统定时任务初始化开始....
Listener的ClassLoader是WebAppClassLoader=21007232@1408b80
2015-09-17 21:20:58
[INFO]-[Thread: main]-[org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized()]: started o.e.j.w.WebAppContext{/bocp,file:/D:/Eclipse/workspace_j2ee/bocp/src/webapp/}
configPlugin的ClassLoader是WebAppClassLoader=21007232@1408b80
2015-09-17 21:20:58
[INFO]-[Thread: main]-[com.mchange.v2.log.MLog.<clinit>()]: MLog clients using log4j logging.
2015-09-17 21:20:59
[INFO]-[Thread: main]-[org.eclipse.jetty.server.AbstractConnector.doStart()]: Started SelectChannelConnector@0.0.0.0:80
Starting Complete. Welcome To The JFinal World :)
定时任务线程的ClassLoader是WebAppClassLoader=21007232@1408b80

截图是运行到configPlugin断点时的ClassLoader变量值

这是现在遇到问题的项目的启动日志为:

TestConfig的ClassLoader是sun.misc.Launcher$AppClassLoader@5e9e34
Starting JFinal 1.9
Starting scanner at interval of 5 seconds.
Starting web server on port: 80
2015-09-17 21:23:23
[INFO]-[Thread: main]-[org.eclipse.jetty.server.Server.doStart()]: jetty-8.1.8.v20121106
2015-09-17 21:23:24
[INFO]-[Thread: main]-[org.eclipse.jetty.webapp.StandardDescriptorProcessor.visitServlet()]: NO JSP Support for /bocpTest, did not find org.apache.jasper.servlet.JspServlet
2015-09-17 21:23:24
[INFO]-[Thread: main]-[org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized()]: started o.e.j.w.WebAppContext{/bocpTest,file:/D:/Eclipse/workspace_j2ee/bocpTest/webapp/}
2015-09-17 21:23:24
[INFO]-[Thread: main]-[com.nfjd.bocpTest.task.B2pCheckListener.contextInitialized()]: 系统定时任务初始化开始....
Listener的ClassLoader是WebAppClassLoader=8493330@819912
2015-09-17 21:23:24
[INFO]-[Thread: main]-[org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized()]: started o.e.j.w.WebAppContext{/bocpTest,file:/D:/Eclipse/workspace_j2ee/bocpTest/webapp/}
configPlugin的ClassLoader是sun.misc.Launcher$AppClassLoader@5e9e34
2015-09-17 21:23:24
[INFO]-[Thread: main]-[com.mchange.v2.log.MLog.<clinit>()]: MLog clients using log4j logging.
2015-09-17 21:23:24
[INFO]-[Thread: main]-[org.eclipse.jetty.server.AbstractConnector.doStart()]: Started SelectChannelConnector@0.0.0.0:80
Starting Complete. Welcome To The JFinal World :)
定时任务线程的ClassLoader是WebAppClassLoader=8493330@819912

截图是运行到configPlugin断点时的ClassLoader变量值

查看日志,唯一的区别就在于标黄的地方。

加载中
0
JFinal
JFinal
    你是在 jetty 启动之前就去使用了 Model  吧? 正常情况 classload 是不会有错的,jfinal 在启动jetty 时将classload 换成了JFinalClassLoader 。我现在断定你的那个定时线程起动的时机过早,将这个启动放在 YourJFinalConfig.afterJFinalStart() 即可解决问题。
33号小人物
33号小人物
在我另外一个同样使用定时线程的项目中,JFinalConfig启动时使用的却是WebAppClassLoader,所以我才认为这个定时线程没有影响@… @
0
JFinal
JFinal

      这么说吧:jfinal 在调用 JettyServer.start() 方法时,会将 classloader 换成 jfinal 自己提供的 JFinalClassLoader,然后再往下继续初始化 ActiveRecordPlugin。如果你在这个过程之前就动用了 Model类,那么此时就会使用默认的 classloader 加载 model 类的 class 文件,这就造成了前后不一致。

     所以,只需要保障对 model 的引用是在 jfinal 调用完了 JetterSever.start() 方法之后即可。

JFinal
JFinal
回复 @33号小人物 : 贴出代码来吧,尤其是初始化定时器那部分,需要知道这个定时器的启动时机
33号小人物
33号小人物
我补充了一些日志,分别在启动运行main的时候,定时器初始化的时候,configPlugin的时候和定时任务执行的时候的ClassLoader。对比两个工程,问题就出在调用configPlugin时,使用的ClassLoader是AppClassLoader,而不是WebAppClassLoader。
返回顶部
顶部