【问题标题】:Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: 0BDAACED线程“主”java.io.StreamCorruptedException 中的异常:无效的流标头:0BDAACED
【发布时间】:2017-02-13 13:09:21
【问题描述】:

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

ssh user@192.168.1.2 -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

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

【问题讨论】:

  • 它连接的不是对象流,所以很可能这是配置问题。

标签: java jenkins


【解决方案1】:

简短回答

Jenkins 的 slave.jar 通过 slave 的 stdin/stdout 与 Jenkins 服务器通信。您依靠 ssh 将 stdin/stdout 传输到从机/从从机传输。

在 stdin 到达从站之前,您不知道在 stdin 被篡改的事情,并且由此产生的通信协议违规会导致您看到的异常。

更长的解释和修复

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

所以我们都使用“通过在服务器上执行命令启动代理”选项来启动从代理。在我的情况下,我这样做是为了能够使用 ssh 跳转主机来访问从属服务器,但这与此答案无关。

我现在将给出在远程节点上启动 slave.jar 的非工作和工作 shell 脚本的示例,然后对可能导致观察到的行为的原因进行推理。我使用 /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 命令。在第二个版本中,shell被ssh进程替换,直接继承了它的stdin/stdout。两个版本都可以正常工作,并且第一个版本中的额外 shell 进程在任何系统上都无关紧要。

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

#!/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"

slave 上的 /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 接收到未篡改的流。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多