我正在应用程序中使用JGit。此应用程序的位置为SecurityManager
,仅允许特定的白名单类和方法产生新进程。
JGit内部正在发现是否已安装本机git,并尝试在org.eclipse.jgit.util.FS.discoverGitSystemConfig()
中读取其配置,甚至尝试在org.eclipse.jgit.util.FS_POSIX.findHook()
中查找钩子,看它们是否可执行。
由于安装了上述安全管理器,因此JGit无法运行并失败。我试图在文档中查找是否有抑制这种行为的方法?
到目前为止,FS检测并不意味着可以在JGit中扩展(请参见FS.DETECTED
)。它将始终引用JGit提供的文件系统之一。
但是...
实现自己的FS
似乎可行,这避免了调用受限的API。
[通过Repository
创建FileRepositoryBuilder
时,您可以指定FS
,从而使存储库使用您的自定义FS
。如果所有JGit代码都咨询了要使用的文件系统的存储库,则应该解决您的问题。
在最新版本的JGit(3.3+)中,您可以将环境变量GIT_CONFIG_NOSYSTEM
设置为任何值,这将禁止读取本机系统范围的Git配置文件。这是通过Constants#GIT_CONFIG_NOSYSTEM_KEY
在JGit源中定义的。
这模拟有一个空的系统级配置文件,它防止代码在随机文件路径中四处搜索并引发安全异常,这是原始问题所要求的。请注意,即使在这种情况下,JGit仍会尝试使用用户级别的配置文件(通常在$HOME/.gitconfig
中)。
此问题的一个更常见的变体可能是使用一组预定义的配置选项,而不必担心任何环境污染(系统或用户级别的配置),因此上述解决方案无法弥补所有空白。
以下示例显示了如何使用JGit在定义的路径中使用特定的基于用户的Git配置文件,并且它提供了一个空的系统级Git配置文件,这意味着可以以编程方式控制整个配置。
要使用此功能,请在运行任何JGit命令之前使用以下代码安装您自己的SystemReader:
File userGitConfig = new File("/my/path/foo.config");
SystemReader.setInstance(new CustomConfigSystemReader(userGitConfig));
然后提供以下新的CustomConfigSystemReader
类:
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;
import java.io.File;
public class CustomConfigSystemReader extends SystemReader
{
private static final SystemReader proxy = SystemReader.getInstance();
private File userGitConfig;
public CustomConfigSystemReader(File userGitConfig)
{
super();
this.userGitConfig = userGitConfig;
}
@Override
public String getenv(String variable)
{
return proxy.getenv(variable);
}
@Override
public String getHostname()
{
return proxy.getHostname();
}
@Override
public String getProperty(String key)
{
return proxy.getProperty(key);
}
@Override
public long getCurrentTime()
{
return proxy.getCurrentTime();
}
@Override
public int getTimezone(long when)
{
return proxy.getTimezone(when);
}
@Override
public FileBasedConfig openUserConfig(Config parent, FS fs)
{
return new FileBasedConfig(parent, userGitConfig, fs);
}
// Return an empty system configuration, based on example in SystemReader.Default#openSystemConfig
@Override
public FileBasedConfig openSystemConfig(Config parent, FS fs)
{
return new FileBasedConfig(parent, null, fs)
{
@Override
public void load()
{
}
@Override
public boolean isOutdated()
{
return false;
}
};
}
}