Entry points
An entry point is a method the runtime (or a framework) can invoke without an in-program caller: a main, a REST handler, a servlet, a scheduled job. They matter because they anchor the WALA call graph and seed reachability — a taint path has to start somewhere.
codeanalyzer-java detects entry points through an EntrypointsFinderFactory that dispatches to per-framework finders. Detected entry points surface in the schema as:
type.is_entrypoint_class—trueon the type when it’s a recognized entry-point class (including any class with amain(String[])).callable.is_entrypoint—trueon the callable for the specific entry-point method.
Supported frameworks
Section titled “Supported frameworks”Class-level annotations: @RestController, @Controller, @HandlerInterceptor, @SpringBootApplication, @Configuration, @Component, @Service, @Repository.
Interfaces: classes implementing CommandLineRunner or ApplicationRunner.
Method-level annotations: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping, @RequestMapping, @EventListener, @Scheduled, @KafkaListener, @RabbitListener, @JmsListener, @PreAuthorize, @PostAuthorize, @PostConstruct, @PreDestroy, plus AOP advice (@Around, @Before, @After) and batch scopes (@JobScope, @StepScope).
HTTP-method annotations (at class or method level) mark REST resource methods: @GET, @POST, @PUT, @DELETE, @HEAD.
Class-level annotations: @Action, @Namespace, @InterceptorRef.
Superclass / interface: classes extending ActionSupport or implementing Interceptor.
Method-level annotations: @Action, @Actions, @ValidationMethod, @InputConfig, @BeforeResult, @Before, @After, @Result, @Results.
Convention: a method named execute().
Class-level annotations: @WebServlet, @WebFilter, @WebListener, @ServerEndpoint, @MessageDriven, @WebService.
Superclasses: classes extending HttpServlet or GenericServlet.
Interfaces: classes implementing ServletContextListener, HttpSessionListener, ServletRequestListener, or MessageListener.
Method signature: methods taking HttpServletRequest or HttpServletResponse parameters.
Plain main methods
Section titled “Plain main methods”Independent of any framework, a class declaring public static void main(String[] args) is an entry point. Its type gets is_entrypoint_class: true and the main callable gets is_entrypoint: true. This is the baseline anchor for ordinary applications.
Why entry points matter for the call graph
Section titled “Why entry points matter for the call graph”WALA builds the call graph by traversing outward from entry points. If a project has no main and none of the framework patterns above match, WALA may have nothing to anchor on and the call_graph can come back empty. When that happens, confirm the project actually has a recognized entry point — see Troubleshooting.
Using entry points downstream
Section titled “Using entry points downstream”Once analyzed, you can filter on the flags to drive reachability. Via the Python SDK, against an in-process analysis:
analysis = CLDK(language="java").analysis( project_path="my-web-app", analysis_level=AnalysisLevel.call_graph,)
# Every method flagged as an entry pointentrypoints = [ (cls, sig) for cls in analysis.get_classes() for sig, m in analysis.get_methods_in_class(cls).items() if m.is_entrypoint]Seed a networkx reachability query from these to ask whether a sink is reachable from any externally-invocable method.
Entry points in the Neo4j projection
Section titled “Entry points in the Neo4j projection”When you project to a Neo4j property graph with --emit neo4j, the is_entrypoint / is_entrypoint_class properties are still carried on the :JCallable and :JType nodes — but the projection also layers a marker label, :JEntrypoint, onto the owning callable (and entry-point class). That turns reachability seeding into a one-line MATCH instead of a property filter:
// Every entry-point method in one application — the reachability seedsMATCH (a:JApplication {name: 'daytrader8'})-[:J_HAS_UNIT]->(:JCompilationUnit) -[:J_DECLARES_TYPE]->(:JType)-[:J_HAS_CALLABLE]->(c:JCallable:JEntrypoint)RETURN c.signatureFrom there you traverse J_CALLS edges (present once you analyze at level 2) to ask the same reachability question entirely in Cypher, across every application in the database. Reading the seeds back through the SDK is identical to the in-process path above — point the facade at the graph and the same typed JCallable objects come back, with no JDK, native binary, or project source on the consumer:
from cldk import CLDKfrom cldk.analysis import AnalysisLevelfrom cldk.analysis.commons.backend_config import Neo4jConnectionConfig
analysis = CLDK.java( analysis_level=AnalysisLevel.call_graph, backend=Neo4jConnectionConfig( uri="bolt://localhost:7687", username="neo4j", password="neo4j", # or set NEO4J_PASSWORD application_name="daytrader8", # must match the --app-name the graph was loaded with ),)
entrypoints = analysis.get_entry_point_methods()