我正在尝试让嵌入式Spring Config Server实现工作从GitHub读取配置。我正在关注本教程:
https://mromeh.com/2017/12/04/spring-boot-with-embedded-config-server-via-spring-cloud-config/
当我的Spring Boot应用尝试启动时,出现以下异常:
引起原因:com.jcraft.jsch.JSchException:没有可用的
密码。在com.jcraft.jsch.Session.send_kexinit(Session.java:629)
在com.jcraft.jsch.Session.connect(Session.java:307)处
org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:146)
...另外23个
我的代码中唯一对此感兴趣的地方是我的bootstrap.yml
文件,它看起来像这样:
spring:
application:
name: DemoApplication.yml
---
spring:
cloud:
config:
failFast: true
server:
bootstrap: true
git:
uri: [email protected]:mycompany/demo-config.git
我在MacOS上运行OpenJDK 8 v212,每次运行以下命令:
#> java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)
我已经搜索了Spring代码和文档,但尚未找到有关传递配置参数或添加代码以影响Spring正在使用的Jsch会话的构造的任何内容。我发现的一切都表明我正在做的事情应该起作用。
我不知道该从哪里去。有人可以告诉我我所缺少的...为了克服这个问题我需要做什么?
最佳答案
为了更早地整合评论...
在后台,Spring使用JGit建立SSH连接。默认情况下,它使用JSch建立SSH连接,该连接由~/.ssh/config
文件配置。
The wiki还提供了有关如何绕过JSch并使用本机ssh
命令的详细信息,可以设置GIT_SSH
环境变量,例如在OS X或Linux中甚至是/usr/bin/ssh
之类的C:\Program Files\TortoiseGit\bin\TortoiseGitPlink.exe
。
在关于如何避免依赖于设置环境变量的注释之后,请注意如何在TransportGitSsh.useExtSession()方法中使用GIT_SSH
检查SystemReader
环境变量。
这意味着一种方法是重写SystemReader
类。但是,它不是一个很小的接口,因此会涉及很多包装代码-使用getenv()
中的自定义位:
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;
public class CustomSystemReader extends SystemReader {
private final SystemReader systemReader;
public CustomSystemReader(SystemReader systemReader) {
this.systemReader = systemReader;
}
@Override
public String getHostname() {
return systemReader.getHostname();
}
@Override
public String getenv(String variable) {
if ("GIT_SSH".equals(variable))
return "/usr/bin/ssh";
return systemReader.getenv(variable);
}
@Override
public String getProperty(String key) {
return systemReader.getProperty(key);
}
@Override
public FileBasedConfig openUserConfig(Config parent, FS fs) {
return systemReader.openUserConfig(parent, fs);
}
@Override
public FileBasedConfig openSystemConfig(Config parent, FS fs) {
return systemReader.openSystemConfig(parent, fs);
}
@Override
public long getCurrentTime() {
return systemReader.getCurrentTime();
}
@Override
public int getTimezone(long when) {
return systemReader.getTimezone(when);
}
}
然后可以这样连接:
SystemReader.setInstance(
new CustomSystemReader(SystemReader.getInstance()));