24

The output from println from within a class function is lost.

An example script (outputclass.groovy):

class OutputClass
{
    OutputClass()
    {
        println("Inside class")  // This will not show in the console
    }
}

println("Outside class")  // Only this is shown in the console
output = new OutputClass()

I use Jenkins CLI to execute the groovy script

java -jar ..\jenkins-cli.jar -s JENKINS_SERVER_URL groovy outputclass.groovy

It only outputs this:

Outside class

It seems like the class inmplicitly uses println from System.out.println, and System.out is directed to the log files, but the println outside the class is using something else, which is outputted in the script console. The following code shows the behavior.

System.out.println("First")
println("Second")

Output:

Second

How do I explicitly set the output device to output to the Jenkins script console?

Magnus
  • 1,261
  • 1
  • 12
  • 20

4 Answers4

32

I found the solution myself here http://mriet.wordpress.com.

When the Groovy plugin starts is passes two bindings to the script. From the bindings we can get the out variable. Get it and use out.println to output to the script console, not the plain println.

The script below shows full solution.

import hudson.model.*

// Get the out variable
def out = getBinding().out;

class OutputClass
{
    OutputClass(out)  // Have to pass the out variable to the class
    {
        out.println ("Inside class")
    }
}

out.println("Outside class")
output = new OutputClass(out)
Nux
  • 9,276
  • 5
  • 59
  • 72
Magnus
  • 1,261
  • 1
  • 12
  • 20
  • 2
    Passing in the `out` stream is also the simplest solution I could find. However the code could maybe be simplified by just doing `output = new OutputClass(getBinding().out)` and skipping the stuff at the beginning. – Peter Lamberg Oct 13 '14 at 05:09
  • 2
    As of 2018, `getBinding().out` results in a `No such property` error. [This SO post](https://stackoverflow.com/questions/42149652) works though, similar workaround – John Pink Jun 20 '18 at 18:36
5

If you use the skript as a post build step (I'm not shure whether it works with the mentioned CLI) you can use the build in logger:

manager.listener.logger.println("some output")

So in your case something like this may be helpful:

class OutputClass
{
    OutputClass(logger)  // Have to pass the out variable to the class
    {
         logger.println ("Inside class")
    }
}

output = new OutputClass(manager.listener.logger)

See also Example 10 in Groovy Plugin Doc

Sergej Werfel
  • 1,335
  • 2
  • 14
  • 25
  • This will only work in later build stages AFAICS. It just silently eats output when I try to invoke it from a `vars/` method during my build. – Craig Ringer Nov 06 '18 at 13:18
0

A simple solution that worked well for me was to add this line on top of each script. This enables usage of traditional println commands all over the code (inside and outside of classes) leaving the code intuitive.

import hudson.model.*
System.out = getBinding().out;

This enables to create log entries like this:

println("Outside class");

class OutputClass {
    OutputClass() {
        println ("Inside class")
    }
}

new OutputClass();

It replaces the default print stream in System.out with the one handed over from Jenkins via bindings.

Tom Fink
  • 532
  • 5
  • 17
0

Does this mailing list post help?

the output is sent to standard output, so if you check your log file, you will probably see something like this: INFO [STDOUT] Hello World

if you insist on using system script, you have to pass out variable to your class, as the binding is not visible inside the class (so it's passed to standard output). You should use something like this

public class Hello {
  static void say(out) {
    out << "Hello World "
  }
}
println "Started ..."
Hello.say(out)
tim_yates
  • 167,322
  • 27
  • 342
  • 338