@yudongf/java-class-analyzer
v1.0.4
Published
Java Class Analyzer - MCP server for Java class file analysis and decompilation
Maintainers
Readme
Java Class Analyzer
当前项目地址:yudongf/java-class-analyzer。
在保留原有 MCP 工具能力的基础上,重点完善了 Windows / macOS 跨平台支持 与 CFR 反编译工具的查找与加载逻辑,使其可直接在 macOS / Linux 环境下稳定运行。
一个基于 Model Context Protocol (MCP) 的 Java 类分析服务,可以扫描 Maven 项目依赖、反编译 Java 类文件、获取 class 方法列表等详细信息,并提供给 LLM 进行代码分析。
适用场景
Cursor等AI工具直接生成调用二方(内部调用)、三方包(外部调用)接口的代码,但因AI无法读取未在当前工程中打开的依赖源码,导致生成的代码错误频出,甚至出现幻觉式编码。
为解决此问题,一般会直接拷贝源码内容喂给LLM;或者先将源码文件放到当前工程内,再在对话中引用。
而使用本地反编译MCP方案最有效,能精准解析jar包中的类与方法,显著提升代码生成的准确性和可用性。
功能特性
- 🚀使用方便:mcp服务基于TypeScript实现,使用npm打包,方便分发和安装,弱环境依赖。
- 🔍 依赖扫描: 自动扫描Maven项目的所有依赖JAR包
- 📦 类索引: 建立类全名到JAR包路径的映射索引
- 🧭 智能类名匹配: 当未找到精确全限定类名时,按 simpleName 进行模糊匹配,并对包含匹配的候选给出友好提示
- 🔄 反编译: 使用CFR工具(已内置有)实时反编译.class文件为Java源码
- 📊 类分析: 分析Java类的结构、方法、字段、继承关系等
- 💾 智能缓存: 按包名结构缓存反编译结果,支持缓存控制
- 🚀 自动索引: 执行分析前自动检查并创建索引
- ⚙️ 灵活配置: 支持外部指定CFR工具路径,并通过
CFR_PATH环境变量优先加载 - 🖥️ 跨平台兼容: 已修复 macOS / Linux 下
javap调用问题,自动按平台选择可执行文件 - 🤖 LLM集成: 通过MCP协议为LLM提供Java代码分析能力
本次更新内容(v1.0.4)
相对于 v1.0.3 的改进。
修复:移除降级扫描逻辑,避免索引多余版本的依赖
问题背景
v1.0.3 及之前版本在 mvn dependency:tree 执行失败时,会降级扫描整个 Maven 本地仓库,导致:
实际案例:
项目实际依赖:hutool-all:5.6.7(dependency:tree 显示)
数据库中却包含:5.6.7, 5.7.22, 5.8.3, 5.8.26, 5.8.29, 5.8.32, 5.8.37, 5.8.38 等多个版本具体问题:
- 索引膨胀:本地仓库中所有历史版本的 JAR 包都被索引
- 查询混乱:同一类名可能对应多个版本的 JAR 包
- 资源浪费:索引了大量项目中未使用的依赖
解决方案
移除 scanLocalMavenRepo() 降级逻辑:
- ❌ 不再扫描整个本地仓库
- ✅ Maven 命令失败时直接报错,提示用户检查环境
- ✅ 确保只索引项目实际依赖的 JAR 包
影响范围
如果 mvn dependency:tree 命令失败,工具会抛出明确的错误信息,而不是静默降级。用户需要:
- 确保 Maven 已安装并配置到 PATH
- 确保项目路径正确且包含
pom.xml
历史版本更新内容
v1.0.2 更新内容
相对于 v1.0.1 的重要改进。
一、索引存储优化:从 JSON 迁移到 SQLite
问题背景
v1.0.1 及之前版本使用 JSON 文件(.mcp-class-index.json)存储类索引,在大型项目中遇到严重问题:
实际案例:
错误信息:Invalid string length
原因:项目依赖过多(500+ JAR包,数十万个类)
结果:JSON 文件超过 Node.js 字符串长度限制(约 512MB),索引创建失败具体问题:
- 文件过大:单个 JSON 文件可能超过数百 MB,超出 Node.js 字符串长度限制,导致
Invalid string length错误 - 内存占用高:加载整个索引到内存,大型项目可能占用数 GB 内存
- 查询慢:需要遍历整个数组查找类,时间复杂度 O(n),查询耗时可能达到数秒
- 写入失败:JSON.stringify() 处理大数据时可能崩溃
解决方案:SQLite 数据库
v1.0.2 改进:
1. 使用 SQLite 数据库存储索引
- 索引文件改为
.mcp-class-index.db(SQLite 数据库) - 数据库表结构:
CREATE TABLE class_index ( id INTEGER PRIMARY KEY AUTOINCREMENT, className TEXT NOT NULL, -- 全限定类名 jarPath TEXT NOT NULL, -- JAR 包路径 packageName TEXT, -- 包名 simpleName TEXT NOT NULL -- 简单类名 ); - 建立索引加速查询:
CREATE INDEX idx_className ON class_index(className); -- 精确查询 CREATE INDEX idx_simpleName ON class_index(simpleName); -- 简单名称查询 CREATE INDEX idx_packageName ON class_index(packageName); -- 包名查询
2. 性能对比
大型项目实测(500+ JAR包,30万+ 类):
| 操作 | v1.0.1 (JSON) | v1.0.2 (SQLite) | 提升 | |------|---------------|-----------------|------| | 索引文件大小 | 300-500MB | 80-150MB | 小 50-70% | | 创建索引 | 失败(Invalid string length) | 成功(30秒) | 从不可用到可用 | | 查询速度 | O(n) 遍历,2-5秒 | O(log n) 索引,<10ms | 500倍+ | | 内存占用 | 加载全部,2-3GB | 按需查询,<50MB | 降低 95% | | 写入速度 | 一次性写入,易崩溃 | 批量事务,稳定 | 从不可用到可用 |
3. 查询优化示例
// 精确匹配 - 使用索引,毫秒级
SELECT * FROM class_index WHERE className = 'com.example.UserService';
// 简单名称匹配 - 使用索引
SELECT * FROM class_index WHERE simpleName = 'UserService';
// 模糊匹配 - LIKE 查询
SELECT * FROM class_index WHERE className LIKE '%Service%';二、新增类名模糊搜索工具
新增 search_classes 工具,支持多种搜索模式:
工具参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| pattern | string | ✅ | 搜索模式 |
| projectPath | string | ✅ | Maven 项目根目录路径 |
| searchType | string | ❌ | 搜索类型,默认 contains |
| limit | number | ❌ | 返回结果最大数量,默认 20 |
支持的搜索类型
regex - 正则表达式查询
{ "pattern": "User.*Service", "searchType": "regex" }匹配:
UserService,UserController,UserDetailService等prefix - 前缀查询
{ "pattern": "com.example.*", "searchType": "prefix" }匹配:所有
com.example包下的类suffix - 后缀查询
{ "pattern": "*Service", "searchType": "suffix" }匹配:所有以
Service结尾的类contains - 包含查询(默认)
{ "pattern": "User", "searchType": "contains" }匹配:类名中包含
User的所有类
三、智能索引刷新机制
1. 自动检测 pom.xml 变化
索引会在以下情况自动刷新(检查耗时 < 5ms):
- 首次使用:无索引文件时自动创建
- pom.xml 修改:检测到 pom.xml 修改时间变化时自动刷新
2. 元数据文件
新增 .mcp-class-index.metadata.json 记录索引元信息:
{
"lastScanTime": "2026-07-02T10:30:00.000Z",
"pomModifiedTime": "2026-07-02T09:15:00.000Z",
"dependencyCount": 156
}3. 手动刷新
支持手动强制刷新索引:
{
"projectPath": "/path/to/project",
"forceRefresh": true
}适用场景:
- 本地仓库 JAR 包被手动删除
- 依赖版本未变但内容变化
- 怀疑索引过期
4. 检查流程(< 5ms)
启动 MCP 服务器
↓
检查 .mcp-class-index.metadata.json 是否存在 (< 1ms)
↓
读取元数据 (< 1ms)
↓
对比 pom.xml 修改时间 (< 1ms)
↓
┌─────────────┐
│ 时间匹配? │ → ❌ → 重新扫描索引
└─────────────┘
↓ ✅
使用缓存的索引(毫秒级响应)四、其他改进
删除旧版索引兼容逻辑
- 移除对
.mcp-class-index.json和.mcp-class-index/分片索引的支持 - 简化代码逻辑,提升性能
- 移除对
依赖更新
- 新增
[email protected]依赖 - 新增
@types/better-sqlite3类型定义
- 新增
错误提示优化
- 索引不存在时提示更友好
- 查询失败时提供明确的解决方案
v1.0.1 更新内容
相对于原 handsomestWei/java-class-analyzer-mcp-server 的改造点。
一、Windows 与 macOS 跨平台支持
原版本在多处硬编码了 Windows 路径与可执行文件名,导致在 macOS / Linux 下无法运行。本次改造实现了真正的跨平台兼容:
javap调用按平台选择:JavaClassAnalyzer.getJavapCommand()不再硬编码javap.exe,改为依据process.platform自动选择:- Windows:
${JAVA_HOME}/bin/javap.exe - macOS / Linux:
${JAVA_HOME}/bin/javap - 未设置
JAVA_HOME时回退到PATH中的javap
- Windows:
- 临时目录改用系统 tmp:
DecompilerService.extractClassFile()由原来固定写入process.cwd()/.mcp-class-temp改为优先使用os.tmpdir()/mcp-class-temp,避免不同平台下污染工作目录;当 MCP 进程下os.tmpdir()异常返回/或空时,回退到用户主目录(HOME/USERPROFILE)下的.mcp-class-temp/。 - 示例配置跨平台化:
mcp-server-config.json由原 Windows 绝对路径(D:/ws-git/...) +node启动方式,改为推荐的全局命令java-class-analyzer-mcp start,环境变量改用占位符(${HOME}/.m2/repository、${JAVA_HOME}、新增CFR_PATH),Windows / macOS 通用。
| 系统 | JAVA_HOME 示例 | MAVEN_REPO 示例 | javap 实际调用 |
| --- | --- | --- | --- |
| Windows | C:/Program Files/Java/jdk-11 | D:/maven/repository | ${JAVA_HOME}/bin/javap.exe |
| macOS | /Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home | ${HOME}/.m2/repository | ${JAVA_HOME}/bin/javap |
| Linux | /usr/lib/jvm/java-11-openjdk | ${HOME}/.m2/repository | ${JAVA_HOME}/bin/javap |
二、CFR 反编译工具处理逻辑增强
原版本仅从项目目录或 CLASSPATH 查找 CFR,配置不灵活、缺失时报错信息也不友好。本次改造重��了 CFR 查找与失败提示逻辑:
四级优先级查找(
DecompilerService.findCfrJar(),每一步都会打印明确日志便于排查):CFR_PATH环境变量(最高优先级,推荐方式)- 用户主目录下匹配
cfr-*.jar正则的文件(HOME/USERPROFILE,跨平台) - 项目
lib/目录及当前工作目录等常见路径 CLASSPATH环境变量中包含cfr的条目
CFR 缺失时的友好错误:
DecompilerService.decompileWithCfr()在未找到 CFR 时不再抛出笼统报错,而是直接列出 3 种可用配置方式,引导用户快速修复:未找到CFR反编译工具。请通过以下方式之一配置: 1. 设置 CFR_PATH 环境变量指向 cfr jar 文件路径 2. 将 cfr jar 放到 ~/cfr-*.jar(用户主目录) 3. 将 cfr jar 放到项目 lib/ 目录下运行时仍支持
cfrPath参数覆盖:通过decompile_class工具调用时显式传入cfrPath,可临时指定 CFR jar 路径,优先级高于上述自动查找。
推荐配置方式:
- Windows:下载
cfr-0.152.jar后设置环境变量CFR_PATH=D:\tools\cfr-0.152.jar,或放到%USERPROFILE%\cfr-0.152.jar。 - macOS / Linux:
export CFR_PATH=$HOME/cfr-0.152.jar,或直接将 jar 放到~/cfr-0.152.jar,无需任何额外配置即可被自动识别。
cfr下载地址 下面是CFR的下载地址,可根据自己的需求选择版本: leibnitz27/cfr 选择最新的版本即可,目前最新版本是0.152,放到本地的磁盘上即可(记好路径,后续配置时需要)。
三、其它改造
- 类名查找支持模糊匹配:
DependencyScanner.findJarForClass()精确匹配失败后会按 simpleName 唯一匹配、多候选报错、包含匹配三级回退,输入短类名也能定位。 - 版本号统一:
src/cli.ts与src/index.ts由1.0.0更新为1.0.1,与package.json对齐。
使用示例
在IDE中注册mcp服务

在智能体对话中使用mcp

使用说明
安装
# 从 npm 安装(推荐)
npm install -g @yudongf/java-class-analyzer从源码安装
git clone https://github.com/yudongf/java-class-analyzer-mcp-server.git
cd java-class-analyzer-mcp-server
npm install
npm run build
npm install -g .MCP服务配置
方法1:使用生成的配置(推荐)
运行以下命令生成配置模板:
java-class-analyzer config -o mcp-client-config.json然后将生成的配置内容添加到你的MCP客户端配置文件中。
方法2:手动配置
参考以下配置示例,添加到MCP客户端配置文件中:
Windows全局安装后的配置:
{
"mcpServers": {
"java-class-analyzer": {
"command": "java-class-analyzer",
"args": ["start"],
"env": {
"NODE_ENV": "production",
"MAVEN_REPO": "D:/maven/repository",
"JAVA_HOME": "C:/Program Files/Java/jdk-11",
"CFR_PATH": "D:/tools/cfr-0.152.jar"
}
}
}
}MAC全局安装后的配置(添加自动授权):
{
"mcpServers": {
"java-class-analyzer": {
"autoApprove": [
"scan_dependencies",
"analyze_class",
"decompile_class"
],
"disabled": false,
"timeout": 180,
"command": "java-class-analyzer",
"type": "stdio",
"transportType": "stdio",
"args": [
"start"
],
"env": {
"NODE_ENV": "production",
"MAVEN_REPO": "/tools/maven/repo",
"CFR_PATH": "/tools/cfr-0.152.jar"
}
}
}
}本地安装后的配置:
{
"mcpServers": {
"java-class-analyzer": {
"command": "node",
"args": [
"node_modules/@yudongf/java-class-analyzer/dist/index.js"
],
"env": {
"NODE_ENV": "production",
"MAVEN_REPO": "D:/maven/repository",
"JAVA_HOME": "C:/Program Files/Java/jdk-11",
"CFR_PATH": "D:/tools/cfr-0.152.jar"
}
}
}
}参数说明
command: 运行MCP服务器的命令,这里使用nodeargs: 传递给Node.js的参数,指向npm run build编译后的dist文件夹内文件env: 环境变量设置
环境变量说明
NODE_ENV: 运行环境标识production: 生产环境,减少日志输出,启用性能优化development: 开发环境,输出详细调试信息test: 测试环境
MAVEN_REPO: Maven本地仓库路径(可选)- 如果设置,程序会使用指定的仓库路径扫描JAR包
- 如果未设置,程序会使用默认的
~/.m2/repository路径
JAVA_HOME: Java安装路径(可选)- 如果设置,程序会使用
${JAVA_HOME}/bin/java执行Java命令(用于CFR反编译) - 如果未设置,程序会使用PATH中的
java命令
- 如果设置,程序会使用
CFR_PATH: CFR反编译工具的路径(可选,程序会自动查找)- 查找顺序为:
CFR_PATH→ 用户主目录cfr-*.jar→ 项目lib/目录 →CLASSPATH
- 查找顺序为:
可用的工具
1. scan_dependencies
扫描Maven项目的所有依赖,建立类名到JAR包的映射索引。
参数:
projectPath(string): Maven项目根目录路径forceRefresh(boolean, 可选): 是否强制刷新索引,默认false
示例:
{
"name": "scan_dependencies",
"arguments": {
"projectPath": "/path/to/your/maven/project",
"forceRefresh": false
}
}2. decompile_class
反编译指定的Java类文件,返回Java源码。
参数:
className(string): 要反编译的Java类全名,如:com.example.QueryBizOrderDOprojectPath(string): Maven项目根目录路径useCache(boolean, 可选): 是否使用缓存,默认true。避免每次都重复生成。cfrPath(string, 可选): CFR反编译工具的jar包路径。已内置有,可以额外指定版本。
示例:
{
"name": "decompile_class",
"arguments": {
"className": "com.example.QueryBizOrderDO",
"projectPath": "/path/to/your/maven/project",
"useCache": true,
"cfrPath": "/path/to/cfr-0.152.jar"
}
}3. analyze_class
分析Java类的结构、方法、字段等信息。
参数:
className(string): 要分析的Java类全名projectPath(string): Maven项目根目录路径
示例:
{
"name": "analyze_class",
"arguments": {
"className": "com.example.QueryBizOrderDO",
"projectPath": "/path/to/your/maven/project"
}
}4. search_classes (v1.0.2 新增)
模糊搜索类名,支持正则表达式、前缀、后缀和包含查询。
参数:
pattern(string): 搜索模式projectPath(string): Maven项目根目录路径searchType(string, 可选): 搜索类型,默认containsregex: 正则表达式prefix: 前缀匹配(如com.example.*)suffix: 后缀匹配(如*Service)contains: 包含匹配(默认)
limit(number, 可选): 返回结果最大数量,默认20
示例:
{
"name": "search_classes",
"arguments": {
"pattern": "*Service",
"projectPath": "/path/to/your/maven/project",
"searchType": "suffix",
"limit": 10
}
}返回示例:
找到 3 个匹配的类:
1. com.example.UserService
包: com.example
JAR: my-app-1.0.0.jar
2. com.example.OrderService
包: com.example
JAR: my-app-1.0.0.jar
3. org.test.DataService
包: org.test
JAR: external-lib-2.1.0.jar缓存文件
在当前工程,会生成以下缓存目录和文件:
.mcp-class-index.db: 类索引数据库文件(v1.0.2+,SQLite格式).mcp-class-index.metadata.json: 索引元数据文件(v1.0.2+).mcp-decompile-cache/: 反编译结果缓存目录(按包名结构)
注意:
- v1.0.2 起使用 SQLite 数据库存储索引,不再使用
.mcp-class-index.json文件- 临时 class 提取目录已迁移到系统临时目录(
os.tmpdir()/mcp-class-temp),不再污染项目根目录
工作流程
- 自动索引: 首次调用
analyze_class或decompile_class时,自动检查并创建索引 - 智能缓存: 反编译结果按包名结构缓存,支持缓存控制
- 分析类: 使用
analyze_class或decompile_class获取类的详细信息 - LLM分析: 将反编译的源码提供给LLM进行代码分析
技术架构
核心组件
- DependencyScanner: 负责扫描Maven依赖和建立类索引
- DecompilerService: 负责反编译.class文件
- JavaClassAnalyzer: 负责分析Java类结构
- MCP Server: 提供标准化的MCP接口
依赖扫描流程
- 检查索引元数据,判断是否需要刷新(< 5ms)
- 如需刷新,执行
mvn dependency:tree获取依赖树 - 解析每个JAR包,提取所有.class文件
- 建立"类全名 -> JAR包路径"的映射索引
- 存储到 SQLite 数据库
.mcp-class-index.db - 保存元数据到
.mcp-class-index.metadata.json
反编译流程
- 根据类名查找对应的JAR包路径
- 检查缓存,如果存在且启用缓存则直接返回
- 从JAR包中提取.class文件到
.mcp-class-temp目录(按包名结构) - 使用CFR工具反编译.class文件
- 保存反编译结果到缓存
.mcp-decompile-cache目录(按包名结构) - 返回Java源码
故障排除
常见问题
Maven命令失败
- 确保Maven已安装并在PATH中
- 检查项目是否有有效的pom.xml文件
CFR反编译失败
- 确保CFR jar包已下载(支持任意版本号)
- 检查Java环境是否正确配置
- 可通过
cfrPath参数指定CFR路径 - 也可通过
CFR_PATH环境变量或将cfr-*.jar放到用户主目录 / 项目lib/下自动加载
类未找到
- 程序会自动检查并创建索引
- 使用
search_classes工具搜索类名(v1.0.2+) - 检查类名是否正确(支持 simpleName 模糊匹配)
- 确保项目依赖已正确解析
索引过期或不完整
- 使用
forceRefresh: true强制刷新索引 - 检查 pom.xml 是否最近修改过
- 删除
.mcp-class-index.db和.mcp-class-index.metadata.json重新生成
- 使用
macOS / Linux 下
javap调用失败- 该问题在 v1.0.1 已修复(不再硬编码
javap.exe) - 请确认已正确设置
JAVA_HOME,或将javap加入PATH
- 该问题在 v1.0.1 已修复(不再硬编码
索引文件过大或创建失败
- v1.0.2 起使用 SQLite 数据库,文件更小、性能更好
- 如果从旧版本升级,建议删除旧的
.mcp-class-index.json文件
测试说明
构建项目
npm install
npm run build测试工具使用
项目提供了独立的测试工具,可以直接测试MCP服务的各个功能,无需通过MCP客户端。
# 测试所有工具
node test-tools.js
# 测试特定工具
node test-tools.js --tool decompile_class --class com.alibaba.excel.EasyExcelFactory --project /path/to/project
# 不使用缓存
node test-tools.js --tool decompile_class --no-cache
# 指定CFR路径
node test-tools.js --tool decompile_class --cfr-path /path/to/cfr.jar测试工具参数
-t, --tool <工具名>: 指定要测试的工具 (scan|decompile|analyze|all)-p, --project <路径>: 项目路径-c, --class <类名>: 要分析的类名--no-refresh: 不强制刷新依赖索引--no-cache: 不使用反编译缓存--cfr-path <路径>: 指定CFR反编译工具的jar包路径-h, --help: 显示帮助信息
日志级别控制
通过 NODE_ENV 环境变量控制日志输出:
development: 输出详细调试信息production: 只输出关键信息
