环境
服务器:centos6
elasticsearch: 6.0.0
工具:CRT
操作系统:win7
疑惑
[yutao@master01 elasticsearch-6.0.0]$ bin/elasticsearch-plugin install file:///home/yutao/download/x-pack-6.0.0.zip
-> Downloading file:///home/yutao/download/x-pack-6.0.0.zip
Exception in thread "main" java.nio.file.AccessDeniedException: /tmp/2089611009639660923.zip
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.createFile(Files.java:632)
at java.nio.file.TempFileHelper.create(TempFileHelper.java:138)
at java.nio.file.TempFileHelper.createTempFile(TempFileHelper.java:161)
at java.nio.file.Files.createTempFile(Files.java:852)
at org.elasticsearch.plugins.InstallPluginCommand.downloadZip(InstallPluginCommand.java:322)
at org.elasticsearch.plugins.InstallPluginCommand.download(InstallPluginCommand.java:245)
at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:213)
at org.elasticsearch.plugins.InstallPluginCommand.execute(InstallPluginCommand.java:204)
at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:69)
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:134)
at org.elasticsearch.cli.MultiCommand.execute(MultiCommand.java:69)
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:134)
at org.elasticsearch.cli.Command.main(Command.java:90)
at org.elasticsearch.plugins.PluginCli.main(PluginCli.java:47)
这个错误,在上一篇博客中也提到过,就是因为我使用yutao
用户安装时,没有目录tmp
的权限。而我想这个目录它为什么要用到?我能不能通过配置文件来进行配置?
查看源码
带着这样的疑惑,我开始查看源码:
// 从这句看出,其调用的是org.elasticsearch.plugins包下的PluginCli类的main方法
org.elasticsearch.plugins.PluginCli.main(PluginCli.java:47)
// 和上面同理
org.elasticsearch.plugins.InstallPluginCommand.download(InstallPluginCommand.java:245)
其InstallPluginCommand
类路径elasticsearch-6.0.0.zip\elasticsearch-6.0.0\lib\plugin-cli-6.0.0.jar\org\elasticsearch\plugins\InstallPluginCommand.class
protected void execute(final Terminal terminal, final OptionSet options, final Environment env) throws Exception {
final String pluginId = (String)this.arguments.value(options);
final boolean isBatch = options.has((OptionSpec)this.batchOption) || System.console() == null;
this.execute(terminal, pluginId, isBatch, env);
}
void execute(final Terminal terminal, final String pluginId, final boolean isBatch, final Environment env) throws Exception {
if (pluginId == null) {
throw new UserException(64, "plugin id is required");
}
final Path pluginZip = this.download(terminal, pluginId, env.tmpFile());
final Path extractedZip = this.unzip(pluginZip, env.pluginsFile());
this.install(terminal, isBatch, extractedZip, env);
}
再看到其中的download
方法,其有个参数env.tmpFile()
;而这个方法是这个Environment
类中的。
路径:elasticsearch-6.0.0.jar\org\elasticsearch\env\Environment.class
public Environment(final Settings settings, final Path configPath) {
// 重点就是这句
this.tmpFile = PathUtils.get(System.getProperty("java.io.tmpdir"), new String[0]);
if (Environment.PATH_HOME_SETTING.exists(settings)) {
final Path homeFile = PathUtils.get((String)Environment.PATH_HOME_SETTING.get(settings), new String[0]).normalize();
if (configPath != null) {
this.configFile = configPath.normalize();
}
else {
this.configFile = homeFile.resolve("config");
}
this.pluginsFile = homeFile.resolve("plugins");
final List<String> dataPaths = (List<String>)Environment.PATH_DATA_SETTING.get(settings);
final ClusterName clusterName = (ClusterName)ClusterName.CLUSTER_NAME_SETTING.get(settings);
if (!dataPaths.isEmpty()) {
this.dataFiles = new Path[dataPaths.size()];
this.dataWithClusterFiles = new Path[dataPaths.size()];
for (int i = 0; i < dataPaths.size(); ++i) {
this.dataFiles[i] = PathUtils.get((String)dataPaths.get(i), new String[0]);
this.dataWithClusterFiles[i] = this.dataFiles[i].resolve(clusterName.value());
}
}
else {
this.dataFiles = new Path[] { homeFile.resolve("data") };
this.dataWithClusterFiles = new Path[] { homeFile.resolve("data").resolve(clusterName.value()) };
}
if (Environment.PATH_SHARED_DATA_SETTING.exists(settings)) {
this.sharedDataFile = PathUtils.get((String)Environment.PATH_SHARED_DATA_SETTING.get(settings), new String[0]).normalize();
}
else {
this.sharedDataFile = null;
}
final List<String> repoPaths = (List<String>)Environment.PATH_REPO_SETTING.get(settings);
if (!repoPaths.isEmpty()) {
this.repoFiles = new Path[repoPaths.size()];
for (int j = 0; j < repoPaths.size(); ++j) {
this.repoFiles[j] = PathUtils.get((String)repoPaths.get(j), new String[0]);
}
}
else {
this.repoFiles = new Path[0];
}
if (Environment.PATH_LOGS_SETTING.exists(settings)) {
this.logsFile = PathUtils.get((String)Environment.PATH_LOGS_SETTING.get(settings), new String[0]).normalize();
}
else {
this.logsFile = homeFile.resolve("logs");
}
if (Environment.PIDFILE_SETTING.exists(settings)) {
this.pidFile = PathUtils.get((String)Environment.PIDFILE_SETTING.get(settings), new String[0]).normalize();
}
else {
this.pidFile = null;
}
this.binFile = homeFile.resolve("bin");
this.libFile = homeFile.resolve("lib");
this.modulesFile = homeFile.resolve("modules");
final Settings.Builder finalSettings = Settings.builder().put(settings);
finalSettings.put(new Object[] { Environment.PATH_HOME_SETTING.getKey(), homeFile });
if (Environment.PATH_DATA_SETTING.exists(settings)) {
finalSettings.putArray(Environment.PATH_DATA_SETTING.getKey(), (List)dataPaths);
}
finalSettings.put(new Object[] { Environment.PATH_LOGS_SETTING.getKey(), this.logsFile });
this.settings = finalSettings.build();
return;
}
throw new IllegalStateException(Environment.PATH_HOME_SETTING.getKey() + " is not configured");
}
我们重点看看这句:
this.tmpFile = PathUtils.get(System.getProperty("java.io.tmpdir"), new String[0]);
很明显,通过jdk
提供的方法,获取到了,当前操作系统的临时文件tmp
。
看到这里也就说明,不能通过配置文件的方式来修改,毕竟源码写死啦!
不过我又对上面代码中的第二个参数new String[0]
,产生了兴趣,虽然弄到了凌晨1点,但是还是坚持多看了几眼。
为什么要传一个字符串数组呢?还是一个大小为0
的!
从源码角度来看,这个参数是选参,可传可不传;
PathUtils
类的源码:
public static Path get(final String first, final String... more) {
return PathUtils.DEFAULT.getPath(first, more);
}
而其中getPath
又是jdk
里的方法:
// 类 FileSystem
public abstract Path getPath(String first, String... more);
在往下就是java
底层如何去获取文件的路径啦!我就不分析啦!
那它需要这目录干什么呢?
从源码中看出,其下载的x-pack.jar
,视乎会临时存放在这个目录,进行压缩成zip
文件。