如何编写Bash脚本编译含Gson依赖的多包Java项目
搞定Java网络项目编译脚本:解决ClassNotFoundException+原理详解
我来帮你解决这个编译脚本的问题,同时把背后的原理讲透,以后你自己写脚本也能得心应手!
先理清你的项目结构(很重要!)
首先咱们得把项目目录理清楚,这样脚本才好写。推荐你把项目改成下面的结构(如果还没这么弄的话):
你的项目文件夹/ ├── src/ # 所有Java源码都放这里 │ ├── client/ # client包的源码 │ │ └── ClientMain.java # 客户端主类(假设叫这个) │ ├── server/ # server包的源码 │ │ └── ServerMain.java # 服务端主类 │ └── sharedClasses/ # 共用类包 │ ├── User.java │ └── Message.java ├── lib/ # 放第三方依赖jar包 │ └── gson-2.10.1.jar # 你的Gson版本,要对应实际文件名 └── build/ # 编译后的.class文件输出目录(脚本会自动创建)
直接给可用的编译&运行脚本
根据操作系统不同,脚本写法有点区别,我给你两种版本:
Windows用批处理脚本(命名为compile_run.bat)
@echo off setlocal enabledelayedexpansion :: 定义各个路径,方便后续修改 set SRC_DIR=src set LIB_DIR=lib set BUILD_DIR=build set GSON_JAR=%LIB_DIR%\gson-2.10.1.jar :: 先创建编译输出目录,不存在就新建 if not exist %BUILD_DIR% mkdir %BUILD_DIR% :: 核心编译命令:把源码目录和Gson包都加入类路径 javac -d %BUILD_DIR% -cp "%SRC_DIR%;%GSON_JAR%" %SRC_DIR%\client\*.java %SRC_DIR%\server\*.java %SRC_DIR%\sharedClasses\*.java :: 检查编译是否成功 if %errorlevel% equ 0 ( echo 编译成功啦! :: 启动服务端(如果要启动客户端,新开一个cmd窗口运行下面的命令) echo 正在启动服务端... java -cp "%BUILD_DIR%;%GSON_JAR%" server.ServerMain :: 客户端运行命令(单独开窗口执行): :: java -cp "%BUILD_DIR%;%GSON_JAR%" client.ClientMain ) else ( echo 编译失败了,看看上面的错误提示找原因哦 ) endlocal
Linux/macOS用Shell脚本(命名为compile_run.sh)
#!/bin/bash # 定义路径变量 SRC_DIR=src LIB_DIR=lib BUILD_DIR=build GSON_JAR="$LIB_DIR/gson-2.10.1.jar" # 创建编译输出目录(不存在就新建) mkdir -p "$BUILD_DIR" # 核心编译命令:Linux/macOS的路径分隔符是冒号,和Windows不一样! javac -d "$BUILD_DIR" -cp "$SRC_DIR:$GSON_JAR" "$SRC_DIR"/client/*.java "$SRC_DIR"/server/*.java "$SRC_DIR"/sharedClasses/*.java # 检查编译状态 if [ $? -eq 0 ]; then echo "编译成功!" # 启动服务端 echo "正在启动服务端..." java -cp "$BUILD_DIR:$GSON_JAR" server.ServerMain # 客户端运行命令(新开终端执行): # java -cp "$BUILD_DIR:$GSON_JAR" client.ClientMain else echo "编译失败,请查看错误提示信息" fi
为什么之前会出ClassNotFoundException?原理讲清楚
这个错误本质就是Java找不到它需要的类文件,不管是编译时还是运行时。NetBeans IDE帮你自动处理了类路径,但手动写脚本得自己配置,核心要点有这几个:
类路径(Classpath)是Java的“搜索路径”
编译器(javac)和虚拟机(java)都会根据类路径去查找需要的类。你的脚本里必须把两个东西加入类路径:- 你自己写的类:
src目录(因为Java的包结构对应目录结构,src是根目录,编译器能找到client、server、sharedClasses这些包下的源码);编译后就是build目录(放生成的.class文件)。 - 第三方依赖:Gson.jar(因为Message类要用到Gson的JSON转换类,不管编译还是运行都得让Java找到它)。
- 你自己写的类:
编译和运行的类路径要覆盖必要内容
- 编译时:
javac需要找到Gson的类(因为Message类依赖它),还要找到你自己的其他类(比如Message可能用到User类),所以-cp参数要包含src和Gson.jar。 - 运行时:
java需要找到编译好的自己的类(在build里),还要找到Gson的类(还是Gson.jar),所以-cp参数要包含build和Gson.jar。
- 编译时:
路径分隔符是大坑!
Windows系统里用分号;分隔多个路径,Linux/macOS用冒号:,搞混了就会出问题,这是很多人踩坑的点!
万一还是出问题?排查步骤
如果运行脚本还是报ClassNotFoundException,按下面的步骤查:
- 检查Gson.jar的路径对不对:比如你是不是把Gson.jar放在了lib目录里,文件名和脚本里写的
gson-2.10.1.jar一致? - 看build目录里有没有生成.class文件:比如
build/sharedClasses/Message.class、build/server/ServerMain.class这些文件是不是都存在? - 检查运行命令的类路径:有没有漏加
build或者Gson.jar? - 看代码里的import语句:比如Message类里是不是正确导入了
com.google.gson.Gson?Gson.jar里确实有这个类(可以解压jar包看看)。
内容的提问来源于stack exchange,提问作者Giulio Paparelli
相关产品推荐
相关产品推荐

