{"id":278,"date":"2026-10-13T07:41:13","date_gmt":"2026-10-13T07:41:13","guid":{"rendered":"http:\/\/www.scmgalaxy.com\/tutorials\/2010\/07\/22\/how-to-put-comment-in-ant-comments-in-apache-ant\/"},"modified":"2026-10-13T07:41:13","modified_gmt":"2026-10-13T07:41:13","slug":"how-to-put-comment-in-ant-comments-in-apache-ant","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/how-to-put-comment-in-ant-comments-in-apache-ant\/","title":{"rendered":"Apache Ant Comments and echo Task: Write Clear build.xml Files and Control Log Output"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><em>Originally published on 2010-07-22; fully revised and updated.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you maintain Ant build files, comments and logging are essential for readability and troubleshooting. This guide explains how to use XML comments in <code>build.xml<\/code>, how the <code>echo<\/code> task behaves at different log levels, and how to choose the right approach for documentation versus runtime diagnostics.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2010\/07\/comments-in-apache-ant.png\" alt=\"comments-in-apache-ant\" width=\"600\" height=\"400\"\/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Commenting in Ant build files (build.xml)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ant build files are XML, so comments use standard XML comment syntax: <code>&lt;!-- ... --&gt;<\/code>. These comments are for humans reading the file and are not shown during normal build output.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-xml\"><span class=\"hljs-meta\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">project<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"demo\"<\/span> <span class=\"hljs-attr\">default<\/span>=<span class=\"hljs-string\">\"compile\"<\/span>&gt;<\/span>\n    <span class=\"hljs-comment\">&lt;!-- Compile Java sources into build\/classes --&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">target<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"compile\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">javac<\/span> <span class=\"hljs-attr\">srcdir<\/span>=<span class=\"hljs-string\">\"src\"<\/span> <span class=\"hljs-attr\">destdir<\/span>=<span class=\"hljs-string\">\"build\/classes\"<\/span>\/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">target<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">project<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Keep comments short and intention-focused (why a target exists, assumptions, non-obvious behavior). As with XML generally, avoid malformed comment syntax and avoid nesting comments.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">XML comments vs echo messages: choose the right mechanism<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Mechanism<\/th><th>Purpose<\/th><th>Visible during build run<\/th><th>Best for<\/th><th>Caveats<\/th><\/tr><\/thead><tbody><tr><td>XML comment (&lt;!&#8211; &#8230; &#8211;&gt;)<\/td><td>Inline documentation in build.xml<\/td><td>No<\/td><td>Design notes, rationale, maintainer guidance<\/td><td>Not available in runtime logs<\/td><\/tr><tr><td>&lt;echo &#8230;\/&gt; to console<\/td><td>Runtime logging<\/td><td>Yes, depending on <code>level<\/code> and Ant log mode<\/td><td>Status updates, warnings, debug traces<\/td><td>Can create noisy logs if overused<\/td><\/tr><tr><td>&lt;echo file=&quot;&#8230;&quot;\/&gt;<\/td><td>Write text to a file<\/td><td>Writes to file output<\/td><td>Generating scripts\/config snippets<\/td><td>When writing to file, log <code>level<\/code> filtering is not the primary behavior<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Using the echo task effectively<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Ant <code>echo<\/code> task writes messages to Ant loggers\/listeners (typically console output unless logging is redirected). You can pass text with the <code>message<\/code> attribute or as nested text, and you can also write output to a file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Key echo attributes<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Attribute<\/th><th>Description<\/th><th>Required<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td>message<\/td><td>Message to echo<\/td><td>No<\/td><td>Can also be provided as nested text; without message\/text, emits a blank line<\/td><\/tr><tr><td>file<\/td><td>Output file path<\/td><td>No<\/td><td>Writes message content to file<\/td><\/tr><tr><td>append<\/td><td>Append to existing file or overwrite<\/td><td>No<\/td><td>Default is false; related behavior aligns with Java file writing semantics in <a href=\"http:\/\/java.sun.com\/j2se\/1.4.2\/docs\/api\/java\/io\/FileWriter.html#FileWriter(java.lang.String, boolean)\" target=\"_blank\" rel=\"noopener\">FileWriter<\/a><\/td><\/tr><tr><td>level<\/td><td>Log severity filter: error, warning, info, verbose, debug<\/td><td>No<\/td><td>Default shown in source material: warning<\/td><\/tr><tr><td>encoding<\/td><td>Encoding for file output<\/td><td>No<\/td><td>Source material notes availability since Ant 1.7<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Common echo styles<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-xml\">&lt;<span class=\"hljs-keyword\">echo<\/span> message=<span class=\"hljs-string\">\"Hello, world\"<\/span>\/&gt;\n\n&lt;<span class=\"hljs-keyword\">echo<\/span> message=<span class=\"hljs-string\">\"Embed a line break:${line.separator}\"<\/span>\/&gt;\n\n&lt;<span class=\"hljs-keyword\">echo<\/span>&gt;This is a longer message\nacross multiple lines.&lt;\/<span class=\"hljs-keyword\">echo<\/span>&gt;\n\n&lt;<span class=\"hljs-keyword\">echo<\/span> message=<span class=\"hljs-string\">\"Deleting drive C:\"<\/span> level=<span class=\"hljs-string\">\"debug\"<\/span>\/&gt;\n\n&lt;<span class=\"hljs-keyword\">echo<\/span> level=<span class=\"hljs-string\">\"error\"<\/span>&gt;\nImminent failure in the antimatter containment facility.\nPlease withdraw to a safe location.\n&lt;\/<span class=\"hljs-keyword\">echo<\/span>&gt;\n\n&lt;<span class=\"hljs-keyword\">echo<\/span> file=<span class=\"hljs-string\">\"runner.csh\"<\/span> append=<span class=\"hljs-string\">\"false\"<\/span>&gt;<span class=\"hljs-comment\">#!\/bin\/tcsh<\/span>\njava -mx1024m ${project.entrypoint} $$*\n&lt;\/<span class=\"hljs-keyword\">echo<\/span>&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">How Ant decides whether an echo message is shown<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Console visibility depends on both the <code>echo<\/code> level and how Ant is started (<code>-q<\/code>, default, <code>-v<\/code>, <code>-d<\/code>). Higher-verbosity modes show more messages.<\/p>\n\n\n\n<pre class=\"mermaid\">\nflowchart TD\n    A[Ant runs target] --> B[Echo task executes]\n    B --> C{File attribute set}\n    C -- yes --> D[Write message to file]\n    C -- no --> E{Current log mode allows this level}\n    E -- yes --> F[Show in console output]\n    E -- no --> G[Suppress from console]\n<\/pre>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Echo statement<\/th><th>-quiet (-q)<\/th><th>Default run (no flag)<\/th><th>-verbose (-v)<\/th><th>-debug (-d)<\/th><\/tr><\/thead><tbody><tr><td>&lt;echo message=&quot;This is error message.&quot; level=&quot;error&quot; \/&gt;<\/td><td>ok<\/td><td>ok<\/td><td>ok<\/td><td>ok<\/td><\/tr><tr><td>&lt;echo message=&quot;This is warning message.&quot; \/&gt;<\/td><td>ok<\/td><td>ok<\/td><td>ok<\/td><td>ok<\/td><\/tr><tr><td>&lt;echo message=&quot;This is info message.&quot; level=&quot;info&quot; \/&gt;<\/td><td>not logged<\/td><td>ok<\/td><td>ok<\/td><td>ok<\/td><\/tr><tr><td>&lt;echo message=&quot;This is verbose message.&quot; level=&quot;verbose&quot; \/&gt;<\/td><td>not logged<\/td><td>not logged<\/td><td>ok<\/td><td>ok<\/td><\/tr><tr><td>&lt;echo message=&quot;This is debug message.&quot; level=&quot;debug&quot; \/&gt;<\/td><td>not logged<\/td><td>not logged<\/td><td>not logged<\/td><td>ok<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-bash\">ant -q\nant\nant -v\nant -d<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Practical build.xml example: comments plus actionable logging<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">project<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"sample-app\"<\/span> <span class=\"hljs-attr\">default<\/span>=<span class=\"hljs-string\">\"package\"<\/span>&gt;<\/span>\n\n    <span class=\"hljs-comment\">&lt;!-- Central output directory used by all targets --&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">property<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"build.dir\"<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"build\"<\/span>\/&gt;<\/span>\n\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">target<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"clean\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">echo<\/span> <span class=\"hljs-attr\">level<\/span>=<span class=\"hljs-string\">\"info\"<\/span> <span class=\"hljs-attr\">message<\/span>=<span class=\"hljs-string\">\"Cleaning ${build.dir}\"<\/span>\/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">delete<\/span> <span class=\"hljs-attr\">dir<\/span>=<span class=\"hljs-string\">\"${build.dir}\"<\/span>\/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">target<\/span>&gt;<\/span>\n\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">target<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"package\"<\/span> <span class=\"hljs-attr\">depends<\/span>=<span class=\"hljs-string\">\"clean\"<\/span>&gt;<\/span>\n        <span class=\"hljs-comment\">&lt;!-- This warning is important for operators in standard runs --&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">echo<\/span> <span class=\"hljs-attr\">level<\/span>=<span class=\"hljs-string\">\"warning\"<\/span> <span class=\"hljs-attr\">message<\/span>=<span class=\"hljs-string\">\"Packaging started\"<\/span>\/&gt;<\/span>\n\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">mkdir<\/span> <span class=\"hljs-attr\">dir<\/span>=<span class=\"hljs-string\">\"${build.dir}\"<\/span>\/&gt;<\/span>\n\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">echo<\/span> <span class=\"hljs-attr\">file<\/span>=<span class=\"hljs-string\">\"${build.dir}\/build-meta.txt\"<\/span> <span class=\"hljs-attr\">append<\/span>=<span class=\"hljs-string\">\"false\"<\/span>&gt;<\/span>\nproject=sample-app\nbuild.timestamp=${DSTAMP}-${TSTAMP}\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">echo<\/span>&gt;<\/span>\n\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">echo<\/span> <span class=\"hljs-attr\">level<\/span>=<span class=\"hljs-string\">\"debug\"<\/span> <span class=\"hljs-attr\">message<\/span>=<span class=\"hljs-string\">\"Wrote ${build.dir}\/build-meta.txt\"<\/span>\/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">target<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">project<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Best practices<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Use <strong>XML comments<\/strong> for maintainers and <strong>echo<\/strong> for runtime visibility.<\/li><li>Choose log levels intentionally: <code>warning<\/code>\/<code>error<\/code> for important messages, <code>debug<\/code> for deep diagnostics.<\/li><li>Avoid excessive echo noise in frequently executed targets.<\/li><li>When generating files with <code>echo file=<\/code>, be explicit about <code>append<\/code> to prevent accidental overwrites.<\/li><li>Run builds in multiple log modes (<code>-q<\/code>, default, <code>-v<\/code>, <code>-d<\/code>) to confirm message visibility is what you expect.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn the correct way to add comments in Apache Ant and when to use the echo task instead. This guide covers echo attributes, log-level behavior, and practical build.xml examples.<\/p>\n","protected":false},"author":1,"featured_media":4418,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[12],"tags":[209,4238,4239,4242,4243,4235,4237,4236,1122,3113,4241,919,4240,104],"class_list":["post-278","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-apache-ant","tag-ant","tag-ant-comment-block","tag-ant-commenting","tag-ant-comments","tag-ant-multiline-comments","tag-comment","tag-comments-in-ant-build","tag-comments-in-apache-ant","tag-guide","tag-how-to","tag-how-to-put-comment-in-ant","tag-instructions","tag-method","tag-tutorials"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/278","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=278"}],"version-history":[{"count":4,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/278\/revisions"}],"predecessor-version":[{"id":79107,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/278\/revisions\/79107"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/4418"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}