概述:
因为旧项目需要对Es做一些扩展,需要搭建一个源码环境; 在搭建的过程中遇到很多问题, 抱着死磕的精神, 终于顺利运行; 对于在搭建过程中出现的问题, 下面都有详细的记录; 解决的过程需要更改部分源码, 仅供参考, 后续有空再写一个es7版本的源码搭建流程.
步骤梳理
1. 下载源码, 解压;
2. 下载Gradle4.5版本, 解压, 添加init.d/init.gradle
allprojects{
repositories {
def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public/'maven { url REPOSITORY_URL }
}}
3. 下载JDK1.10, 并配置JAVA_HOME
4. 执行gradle idea命令
这个命令的执行很重要的一环, 国外源下载JAR会很慢, 需要在子模块中的build.gradle更改为国内的(如阿里云), 需要更改module有: qa, client/benchmarks, buildSrc,benchmarks
5. 导入到IDEA中, 执行Gradle的Reimport操作
有几个注意的地方, IDEA要配置gradle的目录, 源码目录下的gradle/gradle-warpper的配置也可能需要更改
6. 配置JDK的安全策略
具体查看 --> 问题10: JDK权限不足问题
7. 运行和验证
package org.elasticsearch.bootstrap;
import org.elasticsearch.test.ESTestCase;
import org.junit.Test;
public class MyEsStartTest extends ESTestCase {
@Test public void testEsStart() throws Exception {
String homeDir = "D:\\dev\\elasticsearch-6.3.0\\";
System.setProperty("es.path.conf", homeDir + "config");
System.setProperty("es.path.home", homeDir);
Elasticsearch.main(new String[]{});
while(true){}
}}启动成功后, 在浏览器中输入http://127.0.0.1:9200, 有信息输出则说明正常了
问题记录和处理
问题1: gradle->reimport的时候会出现该错误
解决
在导入源码之前先要执行gradle idea; gradle的版本必须和上面的版本保持一致,否则会报错找不到类, 如果不配置gradle的环境变量,则先进到es的源码根目录,然后再gradle全路径执行
问题2: gradle idea执行过程报错, 没有操作权限
解决
https://my.oschina.net/u/946606/blog/152608
修改注册表, 设置权限
问题3: 编译benchmarks模块出错
解决
图1 网络太慢导致一些文件无法下载下来, 下载过程非常缓慢, 改为阿里云的仓库;
图2 JDK版本升级为10, 图中说gradle的警告可忽略
问题4: 配置了hadoop的环境变量, 报错
解决:
方法1: 把HADOOP_HOME从系统的环境变量中删除
方法2: 注释掉源代码, 让后面的编译工作先正常运作
问题5 下载太漫长,出错
gradle配了全局的源, 没有生效, 因为es的子模块配置中央仓库
解决
将仓库改为阿里云, 搜索build.gradle发现很多文件, 其实模块内的几个就可以, 大概是是qa, client/benchmarks, buildSrc,benchmarks
找到build.gradle中的仓库配置部分代码, 如果没有则添加
问题6 依赖下载完后, 编译依旧失败,Gradle出现AssertionError
exception during working with external system: java.lang.AssertionError at org.jetbrains.plugins.gradle.service.project.BaseGradleProjectResolverExtension.createModule(BaseGradleProjectResolverExtension.java:154) at org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension.createModule(AbstractProjectResolverExtension.java:86) at org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver.createModule(KotlinMPPGradleProjectResolver.kt:67) at org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension.createModule(AbstractProjectResolverExtension.java:86) at org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension.createModule(AbstractProjectResolverExtension.java:86)
解决
百度上搜索了一圈, 大部分说和IDEA的版本有关, 我的版本的2019.3 , 升级为2020.1版本
IDEA版本升级之后, 编译正常, 随便写个测试类, 能正常运行说明源码搭建完成, 可以进入下一环节了
问题7: 测试类点击执行无反应, no tasks available
解决
更改idea的gradle编译运行方式为Intellij IDEA
问题8: 运行Es启动测试用例, 出现JarHell相关报错
报错的关键字为found jar hell in test classpath, NoClassDefFoundError
解决
从报错来看,发现了在不同的路径存在两份相同的classh或者jar导致检测不通过, 注释掉JarHell的检测代码即可, 250行处
调试思路
通过点击源码的引用和测试类, 得知BootstrapTests测试类继承自ESTestCase,会执行环境的初始化操作;
所以, 继承该类即可编写自己的测试类, JarHell的检测是在BootstrapForTesting.ensureInitialized()中的staic块完成的
问题9: VM启动配置不对, 导致启动失败
如找不到modules目录, 配置文件找不到, es.path.conf没有配置等等
ERROR: the system property [es.path.conf] must be set
java.lang.IllegalStateException: modules directory [F:\Study_Code\elasticsearch\server\es_test_temp\modules] not foundorg.elasticsearch.bootstrap.BootstrapException: java.nio.file.NoSuchFileException:
F:\Study_Code\elasticsearch\modules\reindex\plugin-descriptor.propertiesLikely root cause: java.nio.file.NoSuchFileException: F:\Study_Code\elasticsearch\modules\reindex\plugin-descriptor.properties
解决
下面代码中的conf和home是必须要配置的, 刚才找不到modules是因为源码中的文件还没经过Gradle打包处理, 所以缺失运行的文件;
这时候从官网下载一个6.3.0 tar.gz的发行版, 下载完成后解压, 代码中的路径改为解压的路径
package org.elasticsearch.bootstrap;
import org.elasticsearch.test.ESTestCase;
import org.junit.Test;
public class MyEsStartTest extends ESTestCase {@Test public void testEsStart() throws Exception {
String homeDir = "D:\\dev\\elasticsearch-6.3.0\\";
System.setProperty("es.path.conf", homeDir + "config");
System.setProperty("es.path.home", homeDir);
Elasticsearch.main(new String[]{});
}
}
问题10: JDK权限不足问题
JDK10增强了安全的权限控制,导致Es的一些操作不具备权限,如 MBeanTrustPermission,MBeanTrustPermission,PropertyPermission等
java.security.AccessControlException: access denied ("java.util.PropertyPermission" "tests.security.manager" "write")
java.security.AccessControlException: access denied ("java.lang.MBeanTrustPermission" "createSecurityManager")
Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrustPermission" "register")
.......
解决
方式1 更改JDK的安全策略配置, JDK安装目录/config/security/java.policy, 在文件末尾处添加如下信息:
permission java.util.PropertyPermission "*", "read,write";
permission java.lang.RuntimePermission "*", "read,write";
permission java.io.FilePermission "*", "read,write";
方式2 添加VM参数, 指定自定义的策略, -Djava.security.policy=policy/xx.policy
问题11: 加载x-pack报错, CreateProcess error=1816, 配额不足无法处理此命令
org.elasticsearch.bootstrap.BootstrapException: java.io.IOException:
Cannot run program "\\?\D:\dev\elasticsearch-6.3.0\modules\x-pack\x-pack-ml\platform\windows-x86_64\bin\controller.exe": CreateProcess error=1816, 配额不足,无法处理此命令。
Likely root cause: java.io.IOException: CreateProcess error=1816, 配额不足,无法处理此命令。
解决
可能是资源不足导致, 将x-pack的ml目录移除到非modules目录
问题12: 加载插件时找不到类
ElasticsearchException[Could not find plugin class []]; nested: ClassNotFoundException[];
Likely root cause: java.lang.ClassNotFoundException:
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:466)
解决
通过debug调试发现有一个插件的className为空, 导致后面的步骤无法正常, 这时候更改PluginsService的源码, 返回空实现, 让后续步骤正常
最终, 终于解决了
因为时Junit Test方法, 所以需要让当前线程阻塞, 出现started就大功告成了, 最后在简单测试下http的接口就Ok了