FilePath act fails with an exception

764 views
Skip to first unread message

Sverre Moe

unread,
Mar 24, 2015, 1:03:20 PM3/24/15
to jenkin...@googlegroups.com
Trying the following in Jenkins Script Console:

import hudson.FilePath.FileCallable
import hudson.remoting.VirtualChannel

def jenkinsInstance = jenkins.model.Jenkins.getInstance()
def project = jenkinsInstance.getItem("myMatrixProject")
def rootProject = project.getRootProject()
def someWorkspace = rootProject.getSomeWorkspace()

try { 
    def test = someWorkspace.act(new FileCallable<String>() {
        private static final long serialVersionUID = 1;
        @Override
        public String invoke(File file, VirtualChannel channel) {
            return "Testing Testing";
        }
    });
} catch (IOException e) { 
  e.printStackTrace(); 
} catch (InterruptedException e) { 
  e.printStackTrace(); 
}

It throws an exception:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script1.groovy: 10: Can't have an abstract method in a non-abstract class. The class 'Script1$1' must be declared abstract or the method 'void checkRoles(org.jenkinsci.remoting.RoleChecker)' must be implemented.
 @ line 10, column 61.
   ct(new FileCallable<String>() {

Ulli Hafner

unread,
Mar 24, 2015, 1:29:12 PM3/24/15
to jenkin...@googlegroups.com
You need to implement the new method checkRoles. See JavaDoc of latest FileCallable version. (Or you can use the provided abstract base classes as parent).

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/b2502c2c-8a02-46df-8bce-90ee10724090%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

signature.asc

Sverre Moe

unread,
Mar 25, 2015, 5:03:35 AM3/25/15
to jenkin...@googlegroups.com
I have added checkRoles within my FileCallable implementation, but it still fails. Though this time with a different message.

remote file operation failed: /home/build/jenkins/workspace/myMatrixProject at hudson.remoting.Channel@54e95cec:Development-opensuse-x86_64: java.io.IOException: Unable to serialize hudson.FilePath$FileCallableWrapper@5a17f7bd

import hudson.FilePath.FileCallable
import hudson.remoting.VirtualChannel
import org.jenkinsci.remoting.RoleChecker

def jenkinsInstance = jenkins.model.Jenkins.getInstance()
def project = jenkinsInstance.getItem("myMatrixProject")
def rootProject = project.getRootProject()
def someWorkspace = rootProject.getSomeWorkspace()

try { 
    def test = someWorkspace.act(new FileCallable<String>() {
        private static final long serialVersionUID = 1;
        @Override
        public String invoke(File file, VirtualChannel channel) {
            return "Testing Testing";
        }
      
        @Override
        public void checkRoles(RoleChecker checker) throws SecurityException {
        
        }
    });
  
    println test
} catch (IOException e) {
  println e.getMessage()
} catch (InterruptedException e) { 
  println e.getMessage()
}


Could you ellaborate on "use the provided abstract base classes as parent" ?

Sverre Moe

unread,
Mar 25, 2015, 6:59:55 AM3/25/15
to jenkin...@googlegroups.com
Tried the following that got rid of "Unable to serialize", but still does not work. Most of the examples I find online for FilePath.act does not work in Script Console.

import hudson.FilePath.FileCallable
import hudson.remoting.VirtualChannel
import org.jenkinsci.remoting.RoleChecker

def jenkinsInstance = jenkins.model.Jenkins.getInstance()
def project = jenkinsInstance.getItem("myMatrixProject")
def rootProject = project.getRootProject()
def someWorkspace = rootProject.getSomeWorkspace()

private class MyFileCallable implements FileCallable<String> {
  private static final long serialVersionUID = 1L;
  @Override
  public String invoke(File file, VirtualChannel channel) throws IOException, InterruptedException {
    return "Testing Testing";
  }
  
  @Override
  public void checkRoles(RoleChecker checker) throws SecurityException {
    
  }
}

try { 
    def test = someWorkspace.act(new MyFileCallable());
    println test
} catch (IOException e) { 
    println e.getMessage()
} catch (InterruptedException e) { 
    println e.getMessage()
}

remote file operation failed: /home/build/jenkins/workspace/myMatrixProject at hudson.remoting.Channel@54e95cec:Development-opensuse-x86_64: java.io.IOException: Remote call on Development-opensuse-x86_64 failed

Sverre Moe

unread,
Apr 15, 2015, 11:04:27 AM4/15/15
to jenkin...@googlegroups.com
Tried an example code I found on GitHub. It fails excactly the same.
It cannot serialize my class implementation of the FileCallable

import java.util.*;
import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;

import hudson.FilePath.FileCallable;
import hudson.remoting.VirtualChannel;
import org.jenkinsci.remoting.RoleChecker

public class RemoteListDir implements FileCallable< Set<String> > { 
  private static final long serialVersionUID = 1452212500874165127L;

  public RemoteListDir() {}
  public Set<String> invoke(File workspace, VirtualChannel channel) throws IOException {
    manager.listener.logger.println "RemoteListDir invoke"
    Collection<File> list = FileUtils.listFiles(workspace, null, true);
    Set<String> set = new HashSet<String>();
    for(File file : list) {
      String relativePath = FolderDiff.getRelativeName(file.getAbsolutePath(), workspace.getAbsolutePath());
      set.add(relativePath);
    }
    return set;
  }

  @Override
  public void checkRoles(RoleChecker checker) throws SecurityException {
   
  }
}

def project = manager.build.getProject()
def someWorkspace = project.getSomeWorkspace()
manager.listener.logger.println "Trying FileCallable on workspace " + someWorkspace

try {
  def files = someWorkspace.act(new RemoteListDir());
  files.each { file ->
    manager.listener.logger.println file
  }
} catch (IOException e) {
  e.printStackTrace(manager.listener.logger);
} catch (InterruptedException e) {
  e.printStackTrace(manager.listener.logger);
}


java.io.IOException: remote file operation failed: /home/build/jenkins/workspace/myLib-test/SLAVE_NODES/Development-opensuse-x86_64 at hudson.remoting.Channel@76706a10:Development-opensuse-x86_64: java.io.IOException: Remote call on Development-opensuse-x86_64 failed
	at hudson.FilePath.act(FilePath.java:985)
	at hudson.FilePath.act(FilePath.java:967)
	at hudson.FilePath$act.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
	at Script1.run(Script1.groovy:38)
	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:580)
	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:618)
	at groovy.lang.GroovyShell.evaluate(GroovyShell.java:589)
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(SecureGroovyScript.java:166)
	at org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder.perform(GroovyPostbuildRecorder.java:361)
	at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
	at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:761)
	at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:721)
	at hudson.model.Build$BuildExecution.post2(Build.java:183)
	at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:670)
	at hudson.model.Run.execute(Run.java:1766)
	at hudson.matrix.MatrixRun.run(MatrixRun.java:146)
	at hudson.model.ResourceController.execute(ResourceController.java:98)
	at hudson.model.Executor.run(Executor.java:374)
Caused by: java.io.IOException: Remote call on Development-opensuse-x86_64 failed
	at hudson.remoting.Channel.call(Channel.java:761)
	at hudson.FilePath.act(FilePath.java:978)
	... 20 more
Caused by: java.lang.Error: Failed to deserialize the Callable object.
	at hudson.remoting.UserRequest.perform(UserRequest.java:105)
	at hudson.remoting.UserRequest.perform(UserRequest.java:49)
	at hudson.remoting.Request$2.run(Request.java:325)
	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)
	at ......remote call to Development-opensuse-x86_64(Native Method)
	at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1360)
	at hudson.remoting.UserResponse.retrieve(UserRequest.java:221)
	at hudson.remoting.Channel.call(Channel.java:753)
	... 21 more
Caused by: java.lang.IllegalArgumentException: Unable to locate class file for class RemoteListDir
	at hudson.remoting.Which.classFileUrl(Which.java:60)

Sverre Moe

unread,
Apr 15, 2015, 12:44:55 PM4/15/15
to jenkin...@googlegroups.com
I have tried that code in both "Execute system Groovy script" and "Groovy Postbuild". Same problem in either of them.

Jesse Glick

unread,
Apr 15, 2015, 2:54:40 PM4/15/15
to Jenkins Dev
On Tue, Mar 24, 2015 at 1:29 PM, Ulli Hafner <ullrich...@gmail.com> wrote:
> You need to implement the new method checkRoles.

No, you do not. You just need to use MasterToSlaveFileCallable.

Sverre Moe

unread,
Apr 16, 2015, 2:49:25 AM4/16/15
to jenkin...@googlegroups.com
I changed the code to extend MasterToSlaveFileCallable, but the exception is still the same.

Changed:
private static class RemoteListDir implements FileCallable<Set<String>> { 
To:
private static class RemoteListDir extends MasterToSlaveFileCallable<Set<String>> { 


Caused by: java.io.IOException: Remote call on Development-opensuse-x86_64 failed
	at hudson.remoting.Channel.call(Channel.java:761)
	at hudson.FilePath.act(FilePath.java:978)
	... 28 more
Caused by: java.lang.Error: Failed to deserialize the Callable object.
	at hudson.remoting.UserRequest.perform(UserRequest.java:105)
	at hudson.remoting.UserRequest.perform(UserRequest.java:49)
	at hudson.remoting.Request$2.run(Request.java:325)
	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)
	at ......remote call to Development-opensuse-x86_64(Native Method)
	at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1360)
	at hudson.remoting.UserResponse.retrieve(UserRequest.java:221)
	at hudson.remoting.Channel.call(Channel.java:753)
	... 29 more
Caused by: java.lang.IllegalArgumentException: Unable to locate class file for class MyClass$RemoteListDir

Jesse Glick

unread,
Apr 20, 2015, 10:23:34 AM4/20/15
to Jenkins Dev
On Thu, Apr 16, 2015 at 2:49 AM, Sverre Moe <sverr...@gmail.com> wrote:
> I changed the code to extend MasterToSlaveFileCallable, but the exception is still the same.

No, that is a totally unrelated exception, which smells like a failure
to do a clean build.

Daniel Anechitoaie

unread,
May 25, 2015, 11:22:35 AM5/25/15
to jenkin...@googlegroups.com
Just wanting to say thanks. I had the same issue, Googled a little bit and found the answer here. Changing it to MasterToSlaveFileCallable worked.

Stuart Rowe

unread,
Jul 13, 2016, 1:40:16 AM7/13/16
to Jenkins Developers
Jesse, are you suggesting that the RemoteClassLoader is failing to find the class file because the groovy script didn't compile?

I've hit the same problem trying to implement a FileCallable in groovy and I assumed the issue was related to runtime generated class not being visible to the RemoteClassLoader.

Do you have any suggestions for debugging this further?

Jesse Glick

unread,
Jul 13, 2016, 10:53:05 AM7/13/16
to Jenkins Dev
On Wed, Jul 13, 2016 at 1:40 AM, Stuart Rowe <stuar...@gmail.com> wrote:
> I've hit the same problem trying to implement a FileCallable in groovy

It is possible you cannot make Remoting calls from the script console.
Cannot recall offhand. The Groovy runtime’s handling of class loading
is rather weird, and `RemoteClassLoader` has a lot of complicated
logic and caching layers etc., so it is quite possibly just not
supported.

Stuart Rowe

unread,
Jul 13, 2016, 3:28:47 PM7/13/16
to Jenkins Developers
What's the best way to run groovy code remotely? Something similar to how the executeGroovy method handles it in https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/util/RemotingDiagnostics.java?

I've tried this by implementing a FileCallable in my plugin that takes a String version of the script to be executed. I had hoped to serialize a Closure instance instead, but each instance is a new Class that the remote class loader doesn't understand.

Jesse Glick

unread,
Jul 13, 2016, 5:52:12 PM7/13/16
to Jenkins Dev
On Wed, Jul 13, 2016 at 3:28 PM, Stuart Rowe <stuar...@gmail.com> wrote:
> What's the best way to run groovy code remotely? Something similar to how
> the executeGroovy method handles it in
> https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/util/RemotingDiagnostics.java?

Yeah try just calling that method.
Reply all
Reply to author
Forward
0 new messages