How to Make Large Language Models Understand Third‑Party Java Packages – A Full Case Study
This article examines why AI code assistants struggle to read compiled third‑party Java libraries, documents a failed attempt using Cursor, and presents three solutions—including manual source feeding, read_file tools, and a local decompiler (MCP)—detailing their implementation, trade‑offs, and performance.
Problem
When generating code that depends on third‑party Java libraries (二方包), LLM‑based assistants such as Cursor cannot read compiled classes that are not opened in the current IDE workspace. The model therefore produces hallucinated imports, wrong method signatures and fails to locate methods like xxxService.queryMainAndDetail and xxxBaseService.queryMainAndDetail.
Failed attempt with Cursor
Feeding the internal documentation URLs and asking for a batch order‑query method queryBizOrderList caused Cursor to report that the target methods do not exist. It then guessed an implementation based on getBizOrderById, generating incorrect imports and code.
Explored solutions
Manual source feeding – copy the required source files into the chat. Works but quickly exceeds token limits for large libraries.
Read‑file style tools – instruct the model to call a read_file function with a fully‑qualified class name. AoneCopilot can read files added via “Add File To Chat”, ClaudeCode can read JAR files from the local .m2 repository, but both require the source to be present.
Local decompilation (MCP) – build an index of all third‑party JARs (using mvn dependency:tree and jar tf), map class names to JAR paths, and invoke a Java class analyzer (e.g., CFR) on demand. The model calls the analyzer, receives decompiled source, and can understand method signatures, DTO structures and import statements.
Implementation of the MCP solution
During project initialization run mvn dependency:tree -DoutputType=text -o to list all dependencies.
For each JAR execute jar tf "${jarPath}" | grep '\.class$' to collect fully‑qualified class names and store a class → JAR index.
When the model needs a class (e.g., QueryBizOrderDO), it looks up the JAR, extracts the .class file and decompiles it with CFR. The decompiled source is returned inside a <code> block.
Resulting code generation
After adding the MCP tool to the project rules, the assistant generated a complete implementation of queryBizOrderList that compiles, imports the correct classes and respects the required order of subOrderIdList:
List<BizOrderDO> queryBizOrderList(long userId, List<Long> subOrderIdList) throws TCException {
// 1. Query online orders
List<BizOrderDO> online = xxxService.queryMainAndDetail(userId, subOrderIdList);
Map<Long, BizOrderDO> resultMap = new HashMap<>();
for (BizOrderDO o : online) {
resultMap.put(o.getBizOrderId(), o);
}
// 2. Find missing IDs
List<Long> missing = new ArrayList<>();
for (Long id : subOrderIdList) {
if (!resultMap.containsKey(id)) {
missing.add(id);
}
}
// 3. Query history for missing IDs
if (!missing.isEmpty()) {
List<BizOrderDO> history = xxxBaseService.queryMainAndDetail(userId, missing);
for (BizOrderDO h : history) {
resultMap.put(h.getBizOrderId(), h);
}
}
// 4. Return results in the original order
List<BizOrderDO> ordered = new ArrayList<>();
for (Long id : subOrderIdList) {
ordered.add(resultMap.get(id));
}
return ordered;
}Pros and cons of each approach
Manual source feeding – immediate and works for any library, but labor‑intensive and limited by token context.
Read‑file tools (AoneCopilot / ClaudeCode) – can fetch files on demand, no manual copy, yet still requires source or accessible JAR and may fail for large dependencies.
Local MCP decompiler – one‑time setup, works for any compiled JAR, provides accurate signatures and imports. Initial configuration overhead and token cost for each decompilation call.
Conclusion
The core insight is that LLMs are bounded by the context they receive. Providing a reliable mechanism to read third‑party bytecode—either by feeding source files, using read‑file APIs, or, most effectively, a local decompiler with an index—eliminates hallucinations and dramatically improves code‑generation accuracy for backend Java development.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
