Ok I’ve discussed with Guillaume Laforge from Groovy fame and here are more details:
* In our code we capture the output of the script and use it to display the rendered page
so any println located directly in the script will work.
* However for a println in a Class, Groovy call System.out.println(…) - which is why it
goes in the xwiki logs - and we would need to capture that in a thread safe way to
redirect it to the page rendering this is a bit more involved:
** Use System.set(PrintStream) with a custom PrintStream that would use for example a
threadlocal variable to direct the content to our page being rendered
** Use Groovy’s runtime metaprogramming feature, for
example: PrintStream.metaClass.println = { String s -> ...handle thread safety here..
}.
** Use Groovy’s compile-time metaprogramming feature and implement a Groovy AST
Transformation to transform all println calls into something else. For example by adding a
binding to the ScriptContext and using that binding instead of println. This requires
using a CompilationCustomizer (we already do that in XWiki btw) which returns
an ASTTransformationCustomizer to do the work.
Thanks
-Vincent
On 19 Dec 2014 at 00:10:18, Bryn Jeffries
(bryn.jeffries@sydney.edu.au(mailto:bryn.jeffries@sydney.edu.au)) wrote:
Vincent Massol said:
Ok I think I know...
Actually the message is printed in the console.
You see something in the page only if you print in the global scope because
this is what gets returned by script evaluation. Calling “println” in a class
doesn’t return anything in the evaluation and thus you don’t see anything.
That’s why the examples at
http://extensions.xwiki.org/xwiki/bin/view/Extension/Groovy+Macro work.
Right, makes sense. So looks like the best fix is to return the string and print it from
global (script) scope. This works:
{{groovy}}
class Callee {
def hello() {
return "hello, world"
}
}
c = new Callee()
println c.hello()
{{/groovy}}