Gangmax Blog

自由之思想,独立之精神

Fix the 'Unable to Reach a Settlement' Issue of Java SSH Connection

| Comments

This is a weird issue. There is some Java code which uses SSH connection to run some comands remotely on a server. When running it in Eclipse, everything works; while if runs it from an pacakged uber jar, it reports the following issue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
start log analysis and generate report
start to download log files, how long it takes depends on the size of log file and network
Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: execute command:  grep network_standalone_ipaddr /etc/ovf*.properties on host 10.247.103.181 failed
      at com.abc.bone.se.LogMain.main(LogMain.java:222)
Caused by: java.lang.RuntimeException: execute command:  grep network_standalone_ipaddr /etc/ovf*.properties on host 10.247.103.181 failed
      at com.abc.bone.se.ssh.SSHUtil.executeCmdInViPR(SSHUtil.java:33)
      at com.abc.bone.se.ssh.SSHUtil.excuteCmd(SSHUtil.java:124)
      at com.abc.bone.se.log.LogFinder.isStandalone(LogFinder.java:31)
      at com.abc.bone.se.log.LogFinder.splitViPRIfNotStandalone(LogFinder.java:69)
      at com.abc.bone.se.log.AllLogFinder.downloadAllLogs(AllLogFinder.java:34)
      at com.abc.bone.se.LogMain.main(LogMain.java:92)
Caused by: net.schmizz.sshj.transport.TransportException: Unable to reach a settlement: [diffie-hellman-group1-sha1] and [ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, diffie-hellman-group14-sha1]
      at net.schmizz.sshj.transport.Proposal.firstMatch(Proposal.java:165)
      at net.schmizz.sshj.transport.Proposal.negotiate(Proposal.java:147)
      at net.schmizz.sshj.transport.KeyExchanger.gotKexInit(KeyExchanger.java:239)
      at net.schmizz.sshj.transport.KeyExchanger.handle(KeyExchanger.java:364)
      at net.schmizz.sshj.transport.TransportImpl.handle(TransportImpl.java:478)
      at net.schmizz.sshj.transport.Decoder.decode(Decoder.java:127)
      at net.schmizz.sshj.transport.Decoder.received(Decoder.java:195)
      at net.schmizz.sshj.transport.Reader.run(Reader.java:72)

Google a lot and find the solution from here:

vpartington commented on Apr 5, 2014

I can only imagine the problem is again caused by the uberjar setup. bcprov-jdk16 has a file called META-INF/BCKEY.SF that might get mangled in a similar manner to the META-INF/services files of TrueZip.

Actually the best advice I can give you is to just not create an uberjar. We’ve tried it numerous times but spent so much time chasing this kind of JAR packaging demons (and again when we added a dependency or upgraded to a new version of a dependency) that we decided to just package JAR dependencies in a lib directory and add a shell script/batch file to build a classpath based on the JARs in that lib directory.

Regards, Vincent.

An uber jar means that when packaging the project, it includes all the depended jar files by adding all the classes of them(extracted) into its jar file, this is just my case. Vincent said if using such packaging mechanism, some file(META-INF/BCKEY.SF) of “bcprov-jdk16” will be overrided by other package’s file, which causes this issue.

So the fix is not to use the uber jar packaging mechanism.

After some investigation, the solution is to make a “lib” directory, put all the depended jar files in it, and the project’s jar file in it as well, then use the following command to start it(from here):

1
java -cp "lib/*" com.abc.bone.se.LogMain $*

How to:

  1. Copy all the depended jar files out first(from here) when running the Maven build;
  2. Copy the project jar into the same directory as step 1 in the build script;
  3. In the build script, put everything into a “build” directory including jar files both step above and the startup script, then zip all the content in it as the final package file.

Comments