# JavaParser: a Java 1 to 25 parser and AST library for source analysis

> JavaParser parses Java source into an abstract syntax tree, and the optional symbol solver resolves names back to their declarations. It is a library for build tools, linters and codemods, not a runtime for your application.

**javaparser/javaparser** — Java 1-25 Parser and Abstract Syntax Tree for Java with advanced analysis functionalities.

- Repository: https://github.com/javaparser/javaparser
- Website: https://javaparser.org
- Stars: 6,157 · Forks: 1,257
- Language: Java
- License: NOASSERTION
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/javaparser-javaparser

## What JavaParser is for, and who ends up using it

JavaParser is a set of libraries that turn Java source text into an abstract syntax tree. The project describes itself as implementing a Java 1.0 through Java 25 parser with analysis features on top. The audience is not application developers writing business logic. It is people who build tools that read other people's Java: static analysis rules, migration and refactoring scripts, documentation generators, architecture checks, and anything that inspects a codebase without executing it.

The distinction matters because there are several ways to ask a JVM about Java code, and they answer different questions. Reflection tells you about classes that are already loaded. The compiler API tells you about a compilation you are willing to run. JavaParser answers a third question: what does this source file say, as text, including the parts that never survive compilation. Comments, formatting, annotations on local variables and the exact shape of an expression are all visible in the tree. That is why tooling built on JavaParser can rewrite a method body and print it back with the formatting preserved, which is a different job from type checking.

## The AST and the symbol solver are two separate layers

The core module produces the tree. Each node corresponds to a construct in the grammar, and the API exposes traversal and mutation over those nodes. The README frames the split plainly: JavaParser generates an abstract syntax tree, and JavaSymbolSolver analyzes that AST to find the relation between an element and its declaration. A variable name in the tree is just a name until the solver ties it to a parameter, a field or a local, with type information and the position of the declaration.

That layering is the design decision worth understanding before you pick a dependency. Parsing is self-contained and needs no classpath. Resolution needs to know what the names refer to, which means it needs the types on the classpath or in the source you hand it. The README notes that since version 3.5.10 the project includes the JavaSymbolSolver, and that depending on javaparser-symbol-solver-core pulls in both. If you only traverse and manipulate the tree, javaparser-core alone is enough. Choosing the larger artifact when you never resolve a symbol is a straightforward way to carry weight you do not use.

The repository layout reflects the same separation: javaparser-core, javaparser-symbol-solver-core, and javaparser-core-serialization as distinct modules, alongside testing modules and the code generators that build the node classes from a metamodel. Since version 3.6.17, the README states, the AST can be serialized to JSON through that separate serialization module.

## Installing JavaParser with Maven or Gradle and parsing a first file

The binaries are on Maven Central, and the README advises using Maven, Gradle or another build system rather than managing jars by hand. The full artifact, which brings in both the parser and the symbol solver, is javaparser-symbol-solver-core. The README shows version 3.28.2 for it:

```xml
<dependency>
    <groupId>com.github.javaparser</groupId>
    <artifactId>javaparser-symbol-solver-core</artifactId>
    <version>3.28.2</version>
</dependency>
```

The Gradle form is the same coordinates in a single line. If you only need to parse, traverse and manipulate the tree, the README points to javaparser-core instead, which drops the symbol solver from your dependency graph:

```xml
<dependency>
    <groupId>com.github.javaparser</groupId>
    <artifactId>javaparser-core</artifactId>
    <version>3.28.2</version>
</dependency>
```

The README does not walk through a traversal example, so there is no documented snippet to copy here. In practice you call the parser facade to turn a file or a string into a compilation unit, which is the root of the tree for one source file, then walk the nodes it exposes (types, methods, and the rest of the grammar) and read names off them. The same nodes accept modification, and the unit can be printed back out. If you check out the sources rather than consuming the artifact, the README gives `./mvnw clean install` to build, `./mvnw package` to produce the jars, and notes the jars land in javaparser-core/target and javaparser-symbol-solver-core/target. It also warns that generating sources first with `./mvnw javacc:javacc` avoids a wave of IDE compilation complaints.

## Where JavaParser stops being the right tool

Resolution is the sharp edge. The symbol solver needs to see the types a name refers to, and the README does not claim it can conjure them from nothing. Code that depends on a classpath you have not supplied, or on generated sources that do not exist yet, will not resolve cleanly. If your analysis needs a fully linked type graph across a large multi-module build, you are signing up to assemble that classpath yourself.

The second boundary is the language range. The project states Java 1.0 through Java 25. Source compiled by a newer release, or by preview features outside that range, is outside the promise. For a tool that must keep pace with the newest syntax the moment it ships, that lag is a real constraint, and the release cadence in the changelog is the thing to watch rather than the version number itself.

Third, JavaParser is the wrong choice when the question is about behaviour rather than text. If you want to run a method, inspect a live object, or evaluate an expression, reflection or the compiler API is the shorter path. JavaParser will happily hand you the tree for a method it cannot execute, and that is the entire point of the library, not a defect.

## How it compares with JavaPoet and with the compiler API

JavaPoet is the comparison people search for, and the difference is directional. JavaPoet builds Java source from a programmatic description: you specify a type, its methods and its fields, and it emits the text. JavaParser goes the other way, taking existing source and giving you a tree you can inspect or edit. A code generator that writes new files from a schema fits JavaPoet. A tool that reads a repository and rewrites what it finds fits JavaParser. They can be used together, but neither substitutes for the other.

The compiler API is the closer alternative, since it also exposes a tree with type information. The practical difference is what each is built to do. The compiler API is designed around compilation: it wants a task, a classpath and diagnostics, and its tree is the compiler's internal model. JavaParser is designed around reading and rewriting source, keeps comments and formatting in the tree, and does not require a successful compilation to give you a result. That last point is why refactoring and migration tools tend to reach for it: you can process files that do not currently compile.

## Licence choice and the cost of staying current

The README states that JavaParser is available under the terms of the LGPL License or the Apache License, and that the user chooses which terms to adopt. Both licence files are in the repository root, and the badge reads LGPL-3/Apache-2.0. The dual arrangement matters for distribution: LGPL carries obligations around relinking that Apache-2.0 does not, so the choice is not cosmetic for a product that ships the library. This is a description of what the project states, not legal advice, and the decision belongs with whoever handles licensing in your organisation.

The maintenance picture is healthy on the evidence available. The repository is not archived, and the last push was on 2026-09-18. The recent releases listed are javaparser-parent-3.28.0 on 2026-01-10, 3.28.1 on 2026-05-04, and 3.28.2 on 2026-05-31. Upgrades are ordinary dependency bumps, with one caveat the README raises directly: there is a migration guide for moving from 2.5.1 to 3.0.0 and later, which tells you the 2.x to 3.x step was not a drop-in change. Anyone still on 2.x should read that guide before touching the version string.

If you build the project from source rather than consuming the artifact, the cost is different. The README warns that modifying AST node code, specifically adding or removing fields or node classes, requires regenerating code: run_core_metamodel_generator.sh rebuilds the metamodel, and run_core_generators.sh runs the generators that consume it, with javaparser-core compiling first. That is a build pipeline to learn, not a one-line change.

## Conclusion

Adopt JavaParser when you need to read or rewrite Java source as a tree: static analysis, migration scripts, generated-code checks, or tooling that must understand constructs the compiler API hides. Do not adopt it if you only need to evaluate expressions at runtime, or if you cannot take a dependency on an LGPL-3 or Apache-2.0 licensed library. Before committing, verify which artifact you actually need (javaparser-core versus javaparser-symbol-solver-core with version 3.28.2), and confirm that the Java release you target is inside the 1.0 to 25 range the project states it covers.

## FAQ

### How do I use JavaParser to parse a Java file?

Add javaparser-core or javaparser-symbol-solver-core from Maven Central, then call the parser facade to turn a file or string into a CompilationUnit, which is the root of the tree for that source file. From there you traverse nodes such as types and methods. The README does not include a full traversal example, only the dependency coordinates and build commands.

### What is JavaParser?

It is a set of libraries implementing a Java 1.0 through Java 25 parser with analysis features. The core produces an abstract syntax tree, and the included JavaSymbolSolver analyzes that tree to relate an element to its declaration.

### How does JavaParser compare with JavaPoet?

They work in opposite directions. JavaParser reads existing Java source into a tree you can inspect or modify, while JavaPoet generates new Java source from a programmatic description. Neither replaces the other, and a project can use both.

### What is a JavaParser alternative?

The compiler API is the closest alternative, since it also exposes a tree with type information. The difference is that the compiler API is built around compilation and wants a classpath and diagnostics, while JavaParser is built around reading and rewriting source and does not require a successful compilation to return a tree.

## Sources

- [Issues](https://github.com/javaparser/javaparser/issues)
- [javaparser/javaparser on GitHub](https://github.com/javaparser/javaparser)
- [Project website](https://javaparser.org)
- [README](https://github.com/javaparser/javaparser/blob/master/README.md)
- [Releases](https://github.com/javaparser/javaparser/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/javaparser-javaparser
