【TongWeb7启动报错】TongWeb控制台可以访问,但是应用访问404

现象:

  • TongWeb7 启动日志出现大量报错
  • 控制台可以正常访问
  • 部署的应用全部 404
  • 日志中一直提示:
    java.lang.NoClassDefFoundError: Could not initialize class com.tongweb.tongejb.assembler.DeployerEjb

先看现象

最近帮客户排查一个 TongWeb7 的问题。

启动的时候日志一直报错:

text 复制代码
java.lang.NoClassDefFoundError:
Could not initialize class
com.tongweb.tongejb.assembler.DeployerEjb

第一眼看到这个错误,我的反应和很多人一样:

是不是 TongWeb 缺少 Jar 包?

是不是版本有问题?

是不是安装包损坏了?

但是继续观察发现了一个很奇怪的现象。

  • TongWeb 控制台可以正常访问
  • 服务其实已经启动成功
  • 唯独应用访问全部 404

说明 TongWeb 并没有真正启动失败,而是应用没有成功部署。

这时候排查方向就不能只盯着 NoClassDefFoundError 了。


第一反应:先对比 Jar 包

因为异常提示的是:

text 复制代码
Could not initialize class

很多人第一反应都会怀疑:

是不是少了某个 Jar?

于是我找到另外一台正常运行的 TongWeb。

把两个 TongWeb 的 Jar 包全部进行了对比。

结果发现:

完全一致,没有任何区别。

说明:

并不是安装包的问题。


日志太多,看不到真正原因

TongWeb 的启动日志非常长。

前面几百行都是各种初始化信息。

真正有价值的异常,很容易被淹没。

翻了很久日志,都没有发现真正的问题。

后来突然想到一个经验:

Java 的真正原因,很多时候都藏在 Caused by 后面。

于是没有继续人工翻日志,而是直接过滤。

例如:

bash 复制代码
grep "Caused by" server.log

果然一下子找到了真正的异常。


真正的问题终于出现了

过滤以后,看到了下面这段日志。

核心内容如下:

text 复制代码
Caused by:
com.tongweb.tongejb.OpenEJBRuntimeException:

cannot create unique file,
please set java.io.tmpdir to a writable folder
or create work folder

继续往下看。

还有真正的 IOException。

text 复制代码
Caused by:

java.io.IOException:
Permission denied

看到这里,问题基本就已经明确了。

不是类找不到。

而是:

初始化这个类的时候,需要创建临时文件,但是没有权限

所以最终才导致:

text 复制代码
NoClassDefFoundError

很多时候:

NoClassDefFoundError 并不是类不存在。

而是:

类初始化失败。

真正原因一定要继续往下找。


为什么会没有权限?

继续检查对应目录。

发现 temp 目录里的文件居然属于 root。

后来和客户沟通了解到。

客户平时有两种启动方式。

有时候:

text 复制代码
root

启动 TongWeb。

有时候:

text 复制代码
普通用户

启动 TongWeb。

例如:

今天 root 部署应用。

明天普通用户启动。

后天又 root 更新。

这样来回切换以后。

temp、work、deployment 等目录,很容易出现:

文件属于 root,普通用户没有写权限。

于是:

初始化临时文件失败。

应用部署失败。

最终表现出来就是:

  • 控制台正常
  • 应用 404
  • NoClassDefFoundError

最终解决办法

把 temp 目录重新赋予普通用户权限即可。

例如:

bash 复制代码
chown -R coremail:coremail /tongweb/TongWeb7/temp

然后重新启动 TongWeb。

结果:

  • 不再出现 NoClassDefFoundError
  • 应用正常部署
  • 页面恢复访问

问题彻底解决。


为什么会出现 NoClassDefFoundError?

很多人看到这个异常就开始找 Jar。

其实 Java 里面,它还有另一种情况。

例如:

text 复制代码
class A {

    static{
        // 初始化失败
    }

}

如果静态代码块执行失败。

或者静态变量初始化失败。

那么以后再次加载这个类。

Java 就会直接抛:

text 复制代码
NoClassDefFoundError

所以:

看到这个异常,不一定是缺类。

还要继续看:

text 复制代码
Caused by

那里才是真正原因。


以后遇到这种问题,可以按照这个思路排查

不要只看第一条异常。

很多时候第一条只是结果。

真正原因在下面。


重点搜索 Caused by

例如:

bash 复制代码
grep "Caused by" server.log

效率远远高于人工翻日志。


确认是不是权限问题。

重点检查:

  • temp
  • work
  • deployment
  • logs

看看目录是不是属于 root。

普通用户有没有写权限。


如果两台环境一台正常一台异常。

先不要怀疑程序。

先对比:

  • Jar 包
  • 配置
  • 用户
  • 文件权限

很多问题,其实都出在运行环境。


思考

这次排查,真正花时间的不是解决问题,而是找到真正的异常。

日志里一直提示的是:

text 复制代码
NoClassDefFoundError

如果一直围绕这个错误去分析,很容易认为是 Jar 包、版本或者安装包的问题。

但真正的根因,其实藏在 Caused by 后面的几行日志里。

以后排查 Java 或 TongWeb 启动问题时,可以记住一个思路:

第一条异常只是现象,最后一个 Caused by 才最有可能是真正的原因。

很多启动失败、应用 404、部署异常的问题,都可以按照这个思路一步步缩小范围,最终定位到根因,而不是被表面的报错带偏方向。

相关推荐
半旧518几秒前
【Java Web02】WEB服务器内部实现技术揭秘
java·服务器·前端
gis开发之家2 分钟前
日志怎么打才专业?Spring Boot 4 日志体系与 Logback 配置(生产级实战)
java·spring boot·后端·logback
平常心的技术小牛6 分钟前
Qt-快速上手-QLabel
开发语言·qt
XR1234567888 分钟前
工厂办公楼无线网络:多楼层覆盖与访客体验怎么选?
开发语言·php
SaaS发言人9 分钟前
渠道数字化解决方案横评:谁更懂快消
java·大数据·人工智能
JL159 分钟前
Java并发编程面试全攻略-从synchronized到AQS底层原理
java·开发语言·面试·并发编程
云泽80810 分钟前
Python 开发环境搭建全指南:从 Python 安装到 PyCharm 配置详解
开发语言·python·pycharm
不会代码的小猴17 分钟前
2. 了解Qt
开发语言·c++·笔记·qt·算法
ZC跨境爬虫18 分钟前
LeetCode 119. 杨辉三角 II(原地更新优化详解 + Java Python 实现)
java·python·leetcode
ZJU_统一阿萨姆19 分钟前
【推理优化进阶】Hopper_Blackwell 微架构:从指令、流水线到真实性能上限
开发语言·人工智能·语言模型·架构·开源