Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-53151

withContext not working as expected in combination with consoleLogFilter

    Details

    • Similar Issues:

      Description

      I'm trying to make a custom ConsoleLogFilter in my pipeline script, however for some reason it breaks the echo functionality.

       

      Here's my code:

      final class TestStream extends OutputStream {  
        private final OutputStream delegate;  
        TestStream(OutputStream delegate) {
          this.delegate = delegate
        }  
        public void write(int b) throws IOException {
          delegate.write(b);
        }  
        public void write(byte[] b) throws IOException {
          delegate.write(b);
        }  
        public void write(byte[] b, int off, int len) throws IOException {
          delegate.write(b, off, len);
        }  
        public void flush() throws IOException {
          delegate.flush();
        }  
         public void close() throws IOException {
          delegate.close();
        }
      }
      class TestFilter extends ConsoleLogFilter  {     
          @Override
          public OutputStream decorateLogger(AbstractBuild build, OutputStream logger)
                  throws IOException, InterruptedException {
              if (logger == null) {
                  return null;
              }
           
              return new TestStream(logger)
          }
      }
      ConsoleLogFilter subsequent = new TestFilter();
      ConsoleLogFilter original = getContext(ConsoleLogFilter.class);
      println original //prints null
      timestamps {
          original = getContext(ConsoleLogFilter.class);
          println original //prints  TimestampNotesConsoleLogFilter object
          echo "Out of Context" //Visible
          withContext(BodyInvoker.mergeConsoleLogFilters(original, subsequent)) {
              echo "In context " //Not visible
          }
          withContext(new TestFilter()) {
              echo "In context " //Not visible
          }
      }
      

      Here is the output:

      Started by user jenkins
      Running in Durability level: PERFORMANCE_OPTIMIZED
      [Pipeline] getContext
      [Pipeline] echo
      null
      [Pipeline] timestamps
      [Pipeline] {
      [Pipeline] getContext
      [Pipeline] echo
      07:22:58 hudson.plugins.timestamper.pipeline.TimestamperStep$TimestampNotesConsoleLogFilter@1d678d7a
      [Pipeline] echo
      07:22:58 Out of Context
      [Pipeline] withContext
      [Pipeline] {
      [Pipeline] echo
      [Pipeline] }
      [Pipeline] // withContext
      [Pipeline] withContext
      [Pipeline] {
      [Pipeline] echo
      [Pipeline] }
      [Pipeline] // withContext
      [Pipeline] }
      [Pipeline] // timestamps
      [Pipeline] End of Pipeline
      Finished: SUCCESS
      

       

      The 'in context' print is never written to the outputstream

        Attachments

          Activity

          Hide
          jsmith45 Joe Smith added a comment -

          I was able to get this to work, by way of adding "NonCPS" annotations to each method in both classes. 

          The exact I tested:

           

          import hudson.console.ConsoleLogFilterclass TestStream extends OutputStream {  
            private final OutputStream delegate;  
            TestStream(OutputStream delegate) {
              this.delegate = delegate
            }  
            @NonCPS
            public void write(int b) throws IOException {
              delegate.write(b);
            }  
            @NonCPS
            public void write(byte[] b) throws IOException {
              delegate.write(b);
            }  
            @NonCPS
            public void write(byte[] b, int off, int len) throws IOException {
              delegate.write(b, off, len);
            }  
            @NonCPS
            public void flush() throws IOException {
              delegate.flush();
            }  
            @NonCPS
             public void close() throws IOException {
              delegate.close();
            }
          }
          class TestFilter extends ConsoleLogFilter  {     
              @Override @NonCPS
              public OutputStream decorateLogger(AbstractBuild build, OutputStream logger)
                      throws IOException, InterruptedException {
                  if (logger == null) {
                      return null;
                  }
               
                  return new TestStream(logger)
              }
          }
          node {
              withContext(new TestFilter()){
                  echo "test"
                  bat 'echo 123'
                  echo "test2"
              }
          }

          So it seems like the issue is that the CPS transformation is breaking these classes. This might actually be by design? I'm not familar enough with the transformation to say for sure, but it does seem odd that it breaks this.

           

          Show
          jsmith45 Joe Smith added a comment - I was able to get this to work, by way of adding "NonCPS" annotations to each method in both classes.  The exact I tested:   import hudson.console.ConsoleLogFilterclass TestStream extends OutputStream { private final OutputStream delegate; TestStream(OutputStream delegate) { this .delegate = delegate } @NonCPS public void write( int b) throws IOException { delegate.write(b); } @NonCPS public void write( byte [] b) throws IOException { delegate.write(b); } @NonCPS public void write( byte [] b, int off, int len) throws IOException { delegate.write(b, off, len); } @NonCPS public void flush() throws IOException { delegate.flush(); } @NonCPS public void close() throws IOException { delegate.close(); } } class TestFilter extends ConsoleLogFilter { @Override @NonCPS public OutputStream decorateLogger(AbstractBuild build, OutputStream logger) throws IOException, InterruptedException { if (logger == null ) { return null ; } return new TestStream(logger) } } node { withContext( new TestFilter()){ echo "test" bat 'echo 123' echo "test2" } } So it seems like the issue is that the CPS transformation is breaking these classes. This might actually be by design? I'm not familar enough with the transformation to say for sure, but it does seem odd that it breaks this.  

            People

            • Assignee:
              Unassigned
              Reporter:
              roel0 roel postelmans
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated: