API / Apache Velocity Interview questions
1. What is Apache Velocity?
Apache Velocity is a Java-based template engine from the Apache Software Foundation. It lets you separate presentation markup from application logic by writing templates in Velocity Template Language (VTL), which reference data placed into a context object by your Java code. Rather than embedding...
2. What are the main features of Apache Velocity?
A few characteristics come up repeatedly when Velocity is discussed against other Java templating options. Clean separation of concerns — templates hold presentation, Java code holds logic and data. Simple, minimal syntax — references, directives, and comments cover most needs without...
3. What is Velocity Template Language (VTL)?
Velocity Template Language, or VTL, is the small scripting language used inside .vm template files. It defines exactly three kinds of constructs: references ( $user.name ), directives ( #if , #foreach , #set , #macro ), and comments ( ## or #* *# ). VTL is intentionally not a general-purpose prog...
4. What file extension do Velocity templates typically use?
Velocity templates conventionally use the .vm extension (short for "Velocity Macro/Markup"), such as welcome.vm or invoice-email.vm . The extension itself isn't enforced by the engine — Velocity will happily parse and render any file regardless of its name, since the resource loader just re...
5. What is the purpose of the VelocityContext?
VelocityContext is the bridge between your Java code and a template. It's a simple key-value store, implementing the Context interface, that you populate before rendering and that VTL references read from during rendering. VelocityContext context = new VelocityContext(); context.put("user", curre...
6. What are Velocity directives?
Directives are the control-flow instructions in VTL, always prefixed with # . They're what let a template do more than just print values. Directive Purpose #set Assign a value to a variable #if / #elseif / #else Conditional branching #foreach Loop over a collection #include Insert a file's raw, u...
7. What are the types of loops available in Velocity?
VTL has a single loop directive, #foreach , but it can iterate over several kinds of sources. Source Example Java Collection or array #foreach($item in $items) Map (iterating values) #foreach($v in $map.values()) Map entries #foreach($entry in $map.entrySet()) Numeric range #foreach($i in [1..5])...
8. How do you use variable references in Velocity templates?
A reference starts a variable expression with $ . Velocity supports two notations: shorthand ( $name ) and formal ( ${name} ). The formal form is needed whenever the reference is immediately followed by text that could otherwise be read as part of the variable name. Hello, $user.firstName! Your t...
9. How do you apply conditional logic in a Velocity template?
Conditional branching uses #if , optional #elseif blocks, an optional #else , and a closing #end . #if($order.total > 100) Free shipping applied. #elseif($order.total > 50) Discounted shipping applied. #else Standard shipping rate applies. #end Conditions support the usual comparison operators ( ...
10. Define the #set directive in Velocity?
#set assigns a value to a reference within the current scope. The value can be a literal, another reference, a method call result, or an arithmetic/string expression. #set($count = 5) #set($fullName = "$user.firstName $user.lastName") #set($total = $price * $quantity) #set($isAdmin = $user.role =...
11. Describe the role of the VelocityEngine class?
VelocityEngine is the main entry point for embedding Velocity in a Java application. You configure it with properties (resource loader paths, logging, macro libraries), initialize it once, then use it repeatedly to look up and render templates. VelocityEngine engine = new VelocityEngine(); engine...
12. List the comment syntax options available in VTL?
VTL supports two comment forms, both stripped from the rendered output. Syntax Use case ## comment Single-line comment, rest of the line is ignored #* comment *# Multi-line block comment, can span several lines There's also a documentation-style block comment, #** ... *# , used just above a Veloc...
13. Explain the purpose of the #include directive?
#include pulls another file's raw content into the current template output verbatim, without parsing it as VTL. It's meant for static content, such as a legal disclaimer, a snippet of pre-formatted HTML, or a plain text block, that doesn't need any templating logic. #include("footer-disclaimer.tx...
14. What is the purpose of the #parse directive?
#parse loads another template file and processes it as VTL, evaluating any directives and references it contains, then splices the resulting output into the calling template at that point. #parse("header.vm")
15. What is a Velocimacro (#macro directive)?
A Velocimacro is a reusable block of VTL defined once with #macro and then invoked like a function elsewhere in templates. It's Velocity's main mechanism for avoiding copy-pasted markup. #macro(greet $name $formal) #if($formal) Dear $name, #else Hi $name! #end #end #greet("Alex" true) #greet("Sam...
16. What is the purpose of the #stop directive?
#stop immediately halts template processing at the point it's encountered. Nothing after it in the template, or in any calling template up the #parse / #include chain, gets rendered; whatever output was already generated up to that point is still returned. #if(!$user.isAuthenticated()) Access den...
17. What is silent/quiet reference notation ($!) used for?
Prefixing a reference with $! instead of $ suppresses the fallback literal output when the reference is undefined or null. With a plain $middleName , an unset variable prints as the literal text $middleName ; with $!middleName , it prints as an empty string instead. Name: $user.firstName $!user.m...
18. How do you use the #break directive?
#break exits the innermost enclosing #foreach loop (or a #macro block) immediately, skipping any remaining iterations or statements in that block, similar to break in Java. #foreach($item in $items) #if($item.id == $targetId) Found: $item.name #break #end #end It only exits the nearest enclosing ...
19. What are formal vs shorthand references in VTL?
Shorthand references, like $user or $user.name , are the everyday form and work fine as long as no adjacent text would be mistaken for part of the identifier. Formal references wrap the variable name in braces, like ${user.name} , which explicitly marks where the reference ends. This matters when...
20. How do you render array or list elements with #foreach?
#foreach iterates any Java array, Collection , or Iterator placed into the context, binding each element to a loop variable. #foreach($product in $products) $velocityCount : $product .name - $$ product.price #end The built-in $velocityCount reference (configurable, 1-based by default) gives the c...
21. Why is Velocity described as a "template engine" rather than a full programming language?
Velocity is deliberately restricted to a small set of constructs: references to display data, directives for basic control flow ( #if , #foreach ), and macros for reuse. It has no way to define classes, throw or catch exceptions, open files, or perform I/O from within a template. That narrow surf...
22. Why do we use Velocity instead of embedding logic in JSP?
Classic JSP allows scriptlets, raw Java code inside <% %> tags, directly on the page. That's convenient short-term but tends to blur the view and controller layers: business logic, data access, and formatting all end up mixed into the markup, which makes pages hard to test and hard to hand off to...
23. Why should you avoid putting business logic inside Velocity templates?
Even though VTL technically allows some computation via #set and method calls on context objects, piling real logic, validation rules, discount calculations, permission checks, into a template causes the same problems JSP scriptlets caused: the logic becomes hard to unit test, hard to reuse outsi...
24. Why doesn't Velocity throw an exception by default for an undefined reference?
Velocity ships with "lenient" reference resolution as its default behavior: if a template references a variable that was never added to the context, or calls a method/property that returns null, Velocity simply prints the reference's literal text (like $missingVar ) instead of raising an error an...
25. How does Velocity resolve a variable reference at render time?
When the renderer hits a reference node in the parsed template AST, it walks a defined resolution path rather than doing a single lookup. flowchart TD A[Renderer hits reference node, e.g. $user.name] --> B[Look up base key 'user' in VelocityContext] B --> C{Key found in context?} C -- No --> H[Le...
26. How is Apache Velocity different from Apache FreeMarker?
Both are mature Java template engines with a similar goal, but they differ in scope and current activity. Aspect Velocity FreeMarker Directive set Small: #if, #foreach, #set, #macro, #parse Larger: includes #switch, #list with else, #assign, #function, #compress, and more Built-in functions Minim...
27. When should you use #parse over #include?
Choose based on whether the target file needs its own VTL evaluated. Scenario Directive Static legal text, license notice, plain snippet #include Shared header/footer/nav that itself uses $references or #if #parse Content with $ or # characters that must appear literally #include Fragment that ne...
28. When would you choose a Velocimacro over a Java-side helper method?
A Velocimacro makes sense when the reusable piece is fundamentally presentation: repeated markup structure, formatting layout, or a small conditional block that a template author needs to control without touching Java code, like a standard way to render a labeled form field or a pagination widget...
29. What happens when a referenced property or method doesn't exist on an object in a template?
In default lenient mode, Velocity's Uberspector tries to resolve $obj.someProperty as a getter ( getSomeProperty() ) or public field. If neither exists on the object's class, resolution simply fails silently: the reference renders as its literal text, $obj.someProperty , and rendering continues n...
30. What is the difference between #set($x = $y) and context.put("x", y) in Java code?
Both make $x resolvable inside the template, but they act at different layers and different times. Aspect #set inside .vm context.put() in Java Where it runs During template rendering, inside VTL Before rendering starts, from application code Typical use Short-lived, template-local values and der...
31. Which is better for reusable rendering logic: a Velocimacro or a custom Directive class, and why?
A Velocimacro is the lighter-weight, more common choice: it's defined entirely in VTL (or a macro library file), requires no Java compilation step, and is easy for a template author to read, copy, and adjust. It's the right default for the vast majority of reuse cases, labeled fields, repeated ca...
32. How can you optimize Velocity template rendering performance?
A few practical levers make the most difference in real applications. Enable resource caching — set file.resource.loader.cache to true in production so parsed templates aren't re-read from disk on every render. Initialize the engine once — construct and init() a single VelocityEngine ...
33. How do you troubleshoot a "parse error" in a VTL template?
Velocity's ParseErrorException reports the template name, line, and column where the parser got stuck, which is the first place to look. Most parse errors trace back to one of a small set of causes. Unclosed block directive — a missing #end after #if, #foreach, or #macro. Mismatched quotes ...
34. Explain the lifecycle of a Velocity template from load to render?
Rendering a template goes through a consistent sequence of stages inside the engine, whether it's the first request or the thousandth. flowchart TD A[getTemplate name called] --> B{Cached and unmodified?} B -- Yes --> F[Return cached parsed Template/AST] B -- No --> C[ResourceLoader reads raw .vm...
35. What is the difference between local and global (library) Velocimacros?
Both are defined the same way, with #macro(name params) ... #end , but they differ in scope and where they're declared. Aspect Local macro Global (library) macro Defined in Directly inside the template that uses it A separate .vm file registered via velocimacro.library Visibility Only that one te...
36. What is strict reference mode in Velocity, and how does it differ from the default lenient mode?
By setting runtime.references.strict to true, Velocity switches from silently printing undefined references as literal text to throwing a MethodInvocationException (or similar) as soon as an undefined variable or a failed method/property lookup is hit. Aspect Lenient (default) Strict Undefined re...
37. How does Velocity integrate with the Apache Struts framework?
Struts 2 ships a Velocity result type that lets an action map to a .vm file instead of a JSP, so after an action executes, Struts merges the action's ValueStack into a VelocityContext and renders the configured template as the response. sequenceDiagram participant Browser participant StrutsAction...
38. How does Velocity handle null values inside #if conditions and references?
A null reference is treated as falsy under "Velocity truth," so #if($user.middleName) evaluates to false whether middleName is null, an empty string, or was never set, without throwing a NullPointerException. #if($user.middleName) Middle name: $user.middleName #end When a null value is printed di...
39. What is the RuntimeInstance in Velocity's architecture?
RuntimeInstance (in org.apache.velocity.runtime ) is the internal core that both VelocityEngine and the older static Velocity singleton delegate to. It's the piece that actually owns configuration, the directive registry, the parser pool, the resource cache, and the Velocimacro manager. When you ...
40. What is the role of the ResourceManager and ResourceLoader in Velocity?
ResourceLoader is the pluggable interface responsible for actually locating and reading a template's raw source, whether from the file system, the classpath, a JAR, a database, or a custom source you implement yourself. ResourceManager sits above it, coordinating one or more configured loaders an...
41. How do you configure a custom template ResourceLoader in Velocity?
Implement Velocity's ResourceLoader abstract class, overriding the methods that locate a resource's InputStream and detect whether it's changed since it was cached, then register the implementation by class name in the engine properties. public class DbResourceLoader extends ResourceLoader { publ...
42. What is the difference in templating philosophy between Apache Velocity and Thymeleaf?
Velocity templates are only valid once rendered; a raw .vm file full of $ references and #if blocks won't display sensibly if you just open it in a browser or hand it to a designer as static HTML. Thymeleaf takes the opposite approach, called "natural templating": its directives live inside stand...
43. How do you escape special characters like $ and # in a Velocity template?
A backslash immediately before $ or # prevents Velocity from treating it as the start of a reference or directive, so it's printed as a literal character instead. Price: \$19.99 Use the \ #include directive to insert static files. Escaping is only needed when the character would otherwise be pars...
44. What are Velocity Tools (VelocityTools) and why would you use them?
VelocityTools is a companion Apache project, a library of ready-made helper objects (called "tools") that you register into the context so templates get common conveniences without writing custom Java for each one. Tool Purpose EscapeTool ($esc) HTML/XML/JS/URL-safe escaping of output DateTool ($...
45. How do you handle internationalization (i18n) in Velocity templates?
Velocity itself has no built-in i18n mechanism, VTL has no concept of locale, so translated text is handled by pairing standard Java ResourceBundle s with VelocityTools' ResourceTool , which is exposed into the context (commonly under the key $text ). ## messages_en.properties: welcome.greeting=W...
46. Explain the internal working of Velocimacro resolution and invocation?
Calling a macro like #greet("Alex" true) triggers a distinct lookup and binding sequence separate from ordinary directive handling. flowchart TD A[Parser encounters #greet(...) call] --> B[VelocimacroManager looks up 'greet'] B --> C{Local macro defined in this template?} C -- Yes --> D[Use local...
47. Explain the internal working of the Velocity template parsing process?
Velocity's parser isn't hand-written; it's generated from a grammar file using JavaCC (Java Compiler Compiler), a parser generator, which produces the actual Java parsing classes used at build time. flowchart TD A[Raw .vm template text] --> B[Lexer/tokenizer splits text into tokens] B --> C[JavaC...
48. What security risks are associated with allowing untrusted users to submit Velocity templates?
Because VTL can call arbitrary getter/setter methods on any Java object exposed into the context, and can reach classes like java.lang.Runtime if introspection isn't restricted, letting untrusted users upload or edit templates is a genuine remote code execution risk, not just a theoretical one. T...
49. What is the Uberspector in Velocity and what problem does it solve?
The Uberspector is Velocity's pluggable introspection layer, the component responsible for turning a reference like $user.name or $order.getTotal() into an actual reflective method or field lookup against whatever Java object is bound to that name in the context. Without it, VTL would need hardco...
50. Why is Apache Velocity often considered a legacy choice for new Java projects today?
Velocity is still an actively maintained Apache Software Foundation project, Velocity Engine 2.5 shipped in mid-2026, so it isn't abandoned. What's changed is its position in the ecosystem relative to newer alternatives. Spring, the dominant Java web stack, deprecated its Velocity integration in ...