jenkinsfile-runner: jenkinsfile-runner-1.0-beta-25 binary Unhandled exception when exploding WAR.

I get a shell into the vanilla image:

root@ffd1873bfc20:/# bash /app/bin/jenkinsfile-runner-launcher cli
No explicit version has been selected, using latest LTS
Running pipeline on jenkins 2.263.4
Exploding,/root/.jenkinsfile-runner/war/2.263.4/jenkins-war-2.263.4.warthis might take some time.
java.lang.RuntimeException: Unhandled exception
        at io.jenkins.jenkinsfile.runner.bootstrap.commands.JenkinsLauncherCommand.call(JenkinsLauncherCommand.java:59)
        at io.jenkins.jenkinsfile.runner.bootstrap.commands.JenkinsLauncherCommand.call(JenkinsLauncherCommand.java:35)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1933)
        at picocli.CommandLine.access$1200(CommandLine.java:145)
        at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2332)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2326)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2291)
        at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2159)
        at picocli.CommandLine.execute(CommandLine.java:2058)
        at io.jenkins.jenkinsfile.runner.bootstrap.Bootstrap.main(Bootstrap.java:45)
Caused by: java.util.zip.ZipException: error in opening zip file
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:225)
        at java.util.zip.ZipFile.<init>(ZipFile.java:155)
        at java.util.jar.JarFile.<init>(JarFile.java:166)
        at java.util.jar.JarFile.<init>(JarFile.java:130)
        at io.jenkins.jenkinsfile.runner.bootstrap.Util.explodeWar(Util.java:60)
        at io.jenkins.jenkinsfile.runner.bootstrap.commands.JenkinsLauncherCommand.postConstruct(JenkinsLauncherCommand.java:91)
        at io.jenkins.jenkinsfile.runner.bootstrap.commands.JenkinsLauncherCommand.call(JenkinsLauncherCommand.java:56)
        ... 9 more

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 1
  • Comments: 16 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Note that while jenkinsfile-runner-1.0-beta-23 works like above, trying to do the same thing with jenkinsfile-runner-1.0-beta-25 does not work. The following is consistently hit.

Exploding,/cx/deploy/jenkinsfile-runner-1.0-beta-25/../jenkins.warthis might take some time.
java.lang.RuntimeException: Unhandled exception
	at io.jenkins.jenkinsfile.runner.bootstrap.commands.JenkinsLauncherCommand.call(JenkinsLauncherCommand.java:59)
	at io.jenkins.jenkinsfile.runner.bootstrap.Bootstrap.call(Bootstrap.java:70)
	at io.jenkins.jenkinsfile.runner.bootstrap.Bootstrap.call(Bootstrap.java:21)
	at picocli.CommandLine.executeUserObject(CommandLine.java:1933)
	at picocli.CommandLine.access$1200(CommandLine.java:145)
	at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2332)
	at picocli.CommandLine$RunLast.handle(CommandLine.java:2326)
	at picocli.CommandLine$RunLast.handle(CommandLine.java:2291)
	at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2159)
	at picocli.CommandLine.execute(CommandLine.java:2058)
	at io.jenkins.jenkinsfile.runner.bootstrap.Bootstrap.main(Bootstrap.java:45)
Caused by: java.lang.NoClassDefFoundError: com/cloudbees/plugins/credentials/CredentialsUnavailableException
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
	at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
	at java.lang.Class.getMethod0(Class.java:3018)
	at java.lang.Class.getMethod(Class.java:1784)
	at io.jenkins.jenkinsfile.runner.JenkinsfileRunnerLauncher.doLaunch(JenkinsfileRunnerLauncher.java:36)
	at io.jenkins.jenkinsfile.runner.JenkinsLauncher.launch(JenkinsLauncher.java:103)
	at io.jenkins.jenkinsfile.runner.App.run(App.java:21)
	at io.jenkins.jenkinsfile.runner.bootstrap.commands.JenkinsLauncherCommand.runJenkinsfileRunnerApp(JenkinsLauncherCommand.java:198)
	at io.jenkins.jenkinsfile.runner.bootstrap.commands.JenkinsLauncherCommand.call(JenkinsLauncherCommand.java:57)
	... 10 more
Caused by: java.lang.ClassNotFoundException: com.cloudbees.plugins.credentials.CredentialsUnavailableException
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 20 more

@oleg-nenashev Thanks for the info. Much appreciated. So just to clarify a few things:

Yes, it is how Jenkinsfile Runner is used normally in containers (pre-exploded WAR)

I was reading the detailed argument behaviors in the README and it sounded like omitting -w was acceptable. Would you accept a fix for this bug where Jenkins isn’t quite getting downloaded and as a result we get the zip exception? Or is this only ever used, in practice, within a container where Jenkins is pre-provisioned? I ask because you alluded to “normal” use and I was curious even though it’s not “normal”, is downloading Jenkins on-the-fly still supported? The README makes me think ‘yes’.

Need to profile it to say anything, but unarchiving operation by @sladyn98 uses a very simple sequential unpacking algorithm in a single thread. Since Jenkins WAR includes MANY files, it is expected to be quite slow.

Okay no worries. I might take a look at the unpacking, but if there’s a way to only do it once then that’s likely not necessary.

Vanilla image includes all the plugins required for running. It is not a case for a stripped executable JAR. There you need to specify plugins using -p

So when we say in the README that “Jenkinsfile Runner bundle includes the Jenkins core and a minimum set of plugins” - that only applies to the Docker image? Should we clarify that? Also, where in the code might I find the list of plugins that would normally ship with the docker image? I was looking for a plugins.txt in the packaging/docker and vanilla-package areas but didn’t see any. Is it getting dynamically generated per the pom in vanilla-package by chance?

It should not be required. If -w points to the exploded directory, Jenkins will just use it every time

Aha! This is very helpful. I verified it indeed worked.

I’ll consider submitting some README improvements (if you like) to make the above a little clearer to newcomers. I appreciate your time.

In my current understanding of jenkinsfile-runner-1.0-beta-25 it downloads the war and then attempts to explode it using a basic extraction. This would need some additional testing with the pipeline you are running to figure out the exact reason of the failure. You could make a case for not exploding the war and falling back to telling the user to do it himself. With respect to your suggestions to the readme, I do agree there is definitely scope for certain improvements.

Here’s my story. I’m not sure if it’s a recurring situation.

  • I’m comfortable writing pipelines / automating things using the DSL, but I’ve never administered or setup Jenkins myself. I’m not against learning, but there’s never been a need to go that far on the cross-functional skill landscape and is typically a task that falls to support staff. Obviously this will vary by company.
  • I’m looking for faster feedback on pipeline code; I discover jenkinsfile-runner.
  • Getting started with the project involves concepts native to Jenkins, and concepts native to the runner, and it’s hard to sort out which is which. Getting started (without Docker) requires sorting that out first.

Ultimately I think learning the new concepts for newcomers should be an expectation if you want to do intermediate or advanced things; but not for the base “working” case in a README.

Some potential suggestions:

  • Adding a “user guide” page, which is more of a step-by-step process, will help users get to a bare minimal working state faster. Link outward to Jenkins docs where necessary, but include enough commands so following the process results in a working state.
  • Possibly do the same for Docker so there’s consistency but not immediately necessary.
  • README can link out to the guide early on.
  • README can detail what’s supported or not; if Docker is the priority, might be worth having that section first.
  • Might be worth splitting out the command references for both zip and docker uses into their own pages

All that being said, I was able to get things working with the standalone zip of jenkinsfile-runner, without Docker. It was pretty straight forward and these steps might make a good foundation for the guide. Here’s how:

  • Take note of https://plugins.jenkins.io/ and search for what’s needed there. In particular, to get the links to .hpi files.
  • Assume current working directory is jenkinsfile-runner-1.0-beta-23/
  • Had the WAR exploded to jenkins/
  • ./bin/jenkinsfile-runner cli -w jenkins/
  • install-plugin https://updates.jenkins.io/download/plugins/durable-task/1.35/durable-task.hpi -deploy
  • shutdown
  • ./bin/jenkinsfile-runner -w jenkins/ -f MY_PATH/Jenkinsfile

Works great. Going to use this to iterate on my next automation. I’ll post updates as I go.

Started
Resume disabled by user, switching to high-performance, low-durability mode.
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/folders/vj/c0gkmnv97tq77v6jwf_h9k8r0000gn/T/jenkinsfileRunner.tmp/jfr1272810717839708878.run/workspace/job
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Checkout SCM)
[Pipeline] checkout
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Build)
[Pipeline] echo
Hello world!
[Pipeline] echo
message:
[Pipeline] echo
param2:
[Pipeline] sh
+ ls -la
total 8
drwxr-xr-x  3 lambeaux  staff   96 Mar 10 15:35 .
drwxr-xr-x  4 lambeaux  staff  128 Mar 10 15:35 ..
-rw-r--r--  1 lambeaux  staff  459 Mar  9 18:02 Jenkinsfile
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Sure, happy to help. Will respond to the comments later today or tomorrow

Downloading jenkins.war myself from https://www.jenkins.io/download/ and specifying it with -w appeared to address the issue. That being said:

Yes, it is how Jenkinsfile Runner is used normally in containers (pre-exploded WAR)

Exploding the war takes longer than I would have expected for a simple unzip operation,

Need to profile it to say anything, but unarchiving operation by @sladyn98 uses a very simple sequential unpacking algorithm in a single thread. Since Jenkins WAR includes MANY files, it is expected to be quite slow.

“vanilla” distribution and necessary plugins being insufficient to run the most basic example successfully.

Vanilla image includes all the plugins required for running. It is not a case for a stripped executable JAR. There you need to specify plugins using -p

It’s also strange that the Jenkins war needs to be re-exploded for each subsequent run. I’d really prefer faster feedback.

It should not be required. If -w points to the exploded directory, Jenkins will just use it every time