ElasticSearch Windows Service and Specifying Java Version
Our company uses ElasticSearch for full-text search. During testing, I used the Linux version of ElasticSearch. However, when it came time for production, the company suddenly gave me a Windows machine and asked me to deploy ElasticSearch on it. I discovered that the Windows version of ElasticSearch supports running as a service (even though I used foreground running during testing - which would probably get me scolded by my leader). The server environment was quite complicated as it had JDK 1.7 installed and I needed to make ElasticSearch use a specific version of JDK 8. Although I added the set JAVA_HOME command in the elasticsearch-service.bat file and the service was successfully created, I consistently received an error message when trying to start it: “Windows could not start Elasticsearch 6.6.0 (elasticsearch-service-x64)…refer to specific service error code 4.”(English version Translated by GPT-3.5, 返回中文)
Environment
All of the following operations were conducted in a virtual machine. At the time of writing this article, the latest version available on the official website was 7.0.0.
ElasticSearch 6.6.0 Download Elasticsearch 6.6.0 - elastic.co
Common Practice
- Follow the official documentation to create a service as usual. Official documentation
- Encounter an error within minutes:
1 | C:\Users\ruter\Desktop\elasticsearch-6.6.0\bin>elasticsearch-service.bat install |
The error message is clear: “Version not sufficient.” However, upgrading the production environment is not always possible. So, I needed to find a way to specify that ElasticSearch should run with JDK 8.
Searching for a Solution
- The basic idea was to configure the set JAVA_HOME command in the bat file, similar to how it is done with Tomcat.
- I set the environment variable and added the line to the file as shown in the image below, hoping it would solve the problem.
Later, I noticed that elasticsearch-services.bat calls elasticsearch-env.bat. So, I moved the set command to that file.
- Then, I ran the command “elasticsearch-service.bat install” and it showed successful installation.
1 | C:\Users\ruter\Desktop\elasticsearch-6.6.0\bin>elasticsearch-service.bat install |
However, when I tried to start the service, I encountered an error immediately.
I went to the /logs/elasticsearch-service-x64-stderr.yyyy-mm-dd.log file to check the failure logs.
1 | 2019-04-23 20:27:46 Commons Daemon procrun stderr initialized |
The error “Unsupported major.minor version 52.0” indicated that the Java version did not match. “52” corresponds to Java 8. I found an article on StackOverflow that listed the major version numbers for Java class file format. Please refer to the list at the bottom of this article.
Resolution
Since the set command I wrote was not taking effect at startup, it meant that the service was reading the system variable %JAVA_HOME%, and the set command was not executed when starting the service.
To confirm this, I changed %JAVA_HOME% in the system on the virtual machine as shown in the image below.
The service started successfully immediately.
So, I think that during startup, the service sets and retrieves the JAVA_HOME environment variable. But if it is an exe-level environment variable, there is nothing more I can do since I cannot reverse engineer their exe file. However, I still examined the
elasticsearch-service.bat
script in detail.In the
doInstall
section, I found the following line.
I tried adding the echo command in front and obtained the following command. It seems that something was not being replaced. The script format used
%%JAVA_HOME%%
, so I guessed that%JAVA_HOME%
would be converted to the actual path while the%%JAVA_HOME%%
format would be treated as an escaped value, keeping the%JAVA_HOME%
intact.
I removed the % symbols on both sides and printed again, and the previous iteration was replaced with an absolute path.
I removed the echo command, removed the service, and reinstalled it. The service ran successfully!
1 | C:\Users\ruter\Desktop\elasticsearch-6.6.0\bin>elasticsearch-service.bat remove |
The Problem with This Approach
Although this approach allows the service to run, there is still a problem. By specifying the Java path in this way, it is hard-coded. If the Java path is relocated or changed, the service will no longer be able to start. If the javapath is changed, the following prompt will be displayed:
Attached: Java Version List
Java Version | major |
---|---|
Java 1.2 | 46 |
Java 1.3 | 47 |
Java 1.4 | 48 |
Java 5 | 49 |
Java 6 | 50 |
Java 7 | 51 |
Java 8 | 52 |
Java 9 | 53 |
Java 10 | 54 |
Java 11 | 55 |
Java 12 | 56 |
Java 13 | 57 |
“”” |