java - 线程中的异常 "main"java.io.StreamCorruptedException : invalid stream header: 0BDAACED

标签 java jenkins

我正在尝试从 master 执行 jenkins cli 命令。

ssh [email protected] -C“/usr/bin/java -jar/home/user/slave.jar”

出现以下错误:

<===[JENKINS REMOTING CAPACITY]===>Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: 0BDAACED
  at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:808)
  at java.io.ObjectInputStream.<init>(ObjectInputStream.java:301)
  at hudson.remoting.ObjectInputStreamEx.<init>(ObjectInputStreamEx.java:48)
  at hudson.remoting.ChannelBuilder.makeTransport(ChannelBuilder.java:430)
  at hudson.remoting.ChannelBuilder.negotiate(ChannelBuilder.java:389)
  at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:310)
  at hudson.remoting.Launcher.main(Launcher.java:528)
  at hudson.remoting.Launcher.runWithStdinStdout(Launcher.java:468)
  at hudson.remoting.Launcher.run(Launcher.java:242)
  at hudson.remoting.Launcher.main(Launcher.java:195)
ERROR: Unexpected error in launching an agent. This is probably a bug in Jenkins
hudson.remoting.RequestAbortedException: java.io.IOException: Unexpected EOF
  at hudson.remoting.Request.abort(Request.java:303)
  at hudson.remoting.Channel.terminate(Channel.java:847)
  at hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:92)
  at ......remote call to ubuntu-slave(Native Method)
  at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1416)
  at hudson.remoting.Request.call(Request.java:172)
  at hudson.remoting.Channel.call(Channel.java:780)
  at hudson.slaves.SlaveComputer.setChannel(SlaveComputer.java:508)
  at hudson.slaves.SlaveComputer.setChannel(SlaveComputer.java:381)
  at hudson.slaves.CommandLauncher.launch(CommandLauncher.java:131)
  at hudson.slaves.SlaveComputer$1.call(SlaveComputer.java:253)
  at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: Unexpected EOF
  at hudson.remoting.ChunkedInputStream.readUntilBreak(ChunkedInputStream.java:99)
  at hudson.remoting.ChunkedCommandTransport.readBlock(ChunkedCommandTransport.java:39)
  at hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read(AbstractSynchronousByteArrayCommandTransport.java:34)
  at hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:59)
ERROR: Connection terminated
java.io.IOException: Unexpected EOF
  at hudson.remoting.ChunkedInputStream.readUntilBreak(ChunkedInputStream.java:99)
  at hudson.remoting.ChunkedCommandTransport.readBlock(ChunkedCommandTransport.java:39)
  at hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read(AbstractSynchronousByteArrayCommandTransport.java:34)
  at hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:59)
ERROR: Process terminated with exit code 1

请告诉我可能是什么问题?

最佳答案

简短回答

Jenkins的slave.jar通过slave的stdin/stdout与Jenkins服务器通信。您依靠 ssh 将标准输入/标准输出传输到从站或从从站传输标准输入/标准输出。

在标准输入到达从站之前,您不知道的东西会对其进行篡改,并且由此产生的通信协议(protocol)违规会导致您看到的异常。

更长的解释和修复

我想您的问题中有 ssh 命令,该命令在 jenkins 服务器上的 shell 脚本中启动从属设备,并且该 shell 脚本中还包含在此命令之前的其他命令。因为这就是我的情况,受到 jenkins 远程文档的启发,该文档建议您可以执行诸如将正确的 Slave.jar 复制到从属设备之类的操作。

因此,我们都使用“通过在服务器上执行命令来启动代理”选项来启动从属代理。在我的例子中,我这样做是为了能够使用 ssh 跳转主机来到达从站,但这与这个答案无关。

我现在将给出非工作和工作 shell 脚本的示例,以在远程节点上启动 Slave.jar,然后对可能导致观察到的行为的原因进行推理。我使用/bin/bash作为shell,随意使用其他的。

1) 如果您已经在从属设备上安装了slave.jar,那么这些版本都可以工作

#!/bin/bash                                                                     
ssh user@host "java -jar /home/user/slave.jar"

.

#!/bin/bash                                                                     
exec ssh user@host "java -jar /home/user/slave.jar"

两个版本都只有一个命令。这里没有其他东西会篡改标准输入或标准输出。在第一个版本中,shell 徘徊并将 stdin/stdout 转发到 ssh 命令或从 ssh 命令转发。在第二个版本中,shell被ssh进程取代,并直接继承其stdin/stdout。两个版本都可以正常工作,并且第一个版本中的附加 shell 进程在任何系统上都应该无关紧要。

2)此版本将slave.jar从服务器上的某个位置复制到从站,然后在从站上执行它

#!/bin/bash
scp -q /some/location/slave.jar user@host:.
exec ssh user@host "java -jar /home/user/slave.jar"

当然,只有当服务器上有/some/location/slave.jar 时,这才有效。

3)此版本尝试在启动从属代理之前对从属进行一些额外的清理。

#!/bin/bash
ssh user@host "rm -rf /home/user/tmp/jenkins"
exec ssh user@host "java -jar /home/user/slave.jar"

从站上的/home/user/tmp/jenkins 位置只是一个示例。 此版本在 4 分钟超时后失败。带有问题中的确切错误消息。该失败不是由/home/user/tmp/jenkins 中缺少任何重要内容引起的,正如您将在下一个示例中看到的:

4) 使示例 3 工作的不同方法

#!/bin/bash
ssh user@host "rm -rf /home/user/tmp/jenkins" </dev/null
exec ssh user@host "java -jar /home/user/slave.jar"

.

#!/bin/bash
exec ssh user@host "rm -rf /home/user/tmp/jenkins && java -jar /home/user/slave.jar"

在第一个修复中,我们确保与从站通信的标准输入不会转发到远程 rm 命令。 rm 不读取其标准输入,但显然 ssh 不知道这一点,并缓冲其自己的标准输入中的一些字节并将它们转发到远程命令,以防万一需要?通过将/dev/null 作为标准输入转发到 rm 命令而不是用于从属通信的标准输入可以解决此问题。

在第二个修复中,只使用了一个 ssh 命令,rm 命令再次不从 stdin 读取任何内容,并且slave.jar 接收未篡改的流。

关于java - 线程中的异常 "main"java.io.StreamCorruptedException : invalid stream header: 0BDAACED,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39868030/

相关文章:

javascript - 如何将从 MySQL 检索到的数组列表值设置到 JavaScript 中的文本框中?

java - 为什么 BufferedImage 不能正常工作?!!是因为我用错了吗?

java - 相对路径说明

java - Java 中软引用的用例是什么?

jenkins - 有没有办法检查 Jenkins 重启历史记录

docker - 如何使用 Jenkins 管道发布 docker 镜像

jenkins - 如何访问共享库中的文件?

jenkins - 在 JenkinsPipelineUnit 中模拟 findFiles

java - org.openqa.selenium.WebDriverException : unknown error: Chrome failed to start: crashed using ChromeDriver Selenium in Jenkins on Ubuntu 18. 04

java - OpenEntityManagerInViewFilter 和 LazyInitializationException