【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、部署异常的问题,都可以按照这个思路一步步缩小范围,最终定位到根因,而不是被表面的报错带偏方向。

相关推荐
Wang's Blog2 小时前
Go-Zero项目开发34: 微服务超时控制与重试机制实践
开发语言·微服务·golang·go-zero
C++、Java和Python的菜鸟2 小时前
第7章 后端Web实战(Tlias系统)
java
憧憬成为java架构高手的小白2 小时前
黑马八股--spring框架学习
java·学习·spring
唐青枫3 小时前
Java Picocli 实战详解:用注解写出好用的命令行工具
java
2zcode3 小时前
项目文档:基于MATLAB神经网络的心力衰竭预测与临床辅助决策系统研究
开发语言·神经网络·matlab·心力衰竭预测\
X-⃢_⃢-X3 小时前
四、OpenFeign远程调用
java·微服务·springboot·springcloud
减瓦3 小时前
深入 Quarkus:云原生时代 Java 的重生之路
java·开发语言·云原生
杨运交3 小时前
[053][核心模块]Java枚举缓存与ORM集成实践
java·开发语言·缓存
繁星蓝雨4 小时前
C++设计原理——异常处理
java·c++·异常处理·noexcept·throw·try catch
BerrySen1784 小时前
一个Java项目改成AI流程后,最难的部分完全变了
java·大数据·人工智能·可观测性·大模型应用开发·工程思维