2727import java .io .InputStreamReader ;
2828import java .io .Reader ;
2929import java .nio .charset .StandardCharsets ;
30+ import java .nio .file .DirectoryStream ;
3031import java .nio .file .Files ;
32+ import java .nio .file .Path ;
3133import java .nio .file .Paths ;
3234import java .util .ArrayList ;
3335import java .util .Arrays ;
4345import java .util .regex .Matcher ;
4446import java .util .regex .Pattern ;
4547import java .util .stream .Collectors ;
48+ import java .util .stream .StreamSupport ;
4649
4750/**
4851 * Parses JVM options from a file and prints a single line with all JVM options to standard output.
@@ -53,82 +56,90 @@ final class JvmOptionsParser {
5356 * The main entry point. The exit code is 0 if the JVM options were successfully parsed, otherwise the exit code is 1. If an improperly
5457 * formatted line is discovered, the line is output to standard error.
5558 *
56- * @param args the args to the program which should consist of a single option, the path to the JVM options
59+ * @param args the args to the program which should consist of a single option, the path to ES_PATH_CONF
5760 */
5861 public static void main (final String [] args ) throws InterruptedException , IOException {
5962 if (args .length != 1 ) {
60- throw new IllegalArgumentException ("expected one argument specifying path to jvm.options but was " + Arrays .toString (args ));
61- }
62- final List <String > jvmOptions = new ArrayList <>();
63- final SortedMap <Integer , String > invalidLines = new TreeMap <>();
64- try (
65- InputStream is = Files .newInputStream (Paths .get (args [0 ]));
66- Reader reader = new InputStreamReader (is , StandardCharsets .UTF_8 );
67- BufferedReader br = new BufferedReader (reader )
68- ) {
69- parse (JavaVersion .majorVersion (JavaVersion .CURRENT ), br , new JvmOptionConsumer () {
70- @ Override
71- public void accept (final String jvmOption ) {
72- jvmOptions .add (jvmOption );
73- }
74- }, new InvalidLineConsumer () {
75- @ Override
76- public void accept (final int lineNumber , final String line ) {
77- invalidLines .put (lineNumber , line );
78- }
79- });
63+ throw new IllegalArgumentException ("expected one argument specifying path to ES_PATH_CONF but was " + Arrays .toString (args ));
8064 }
8165
82- if (invalidLines .isEmpty ()) {
83- // now append the JVM options from ES_JAVA_OPTS
84- final String environmentJvmOptions = System .getenv ("ES_JAVA_OPTS" );
85- if (environmentJvmOptions != null ) {
86- jvmOptions .addAll (
87- Arrays .stream (environmentJvmOptions .split ("\\ s+" ))
88- .filter (Predicate .not (String ::isBlank ))
89- .collect (Collectors .toUnmodifiableList ())
90- );
66+ final ArrayList <Path > jvmOptionsFiles = new ArrayList <>();
67+ jvmOptionsFiles .add (Paths .get (args [0 ], "jvm.options" ));
68+
69+ final Path jvmOptionsDirectory = Paths .get (args [0 ], "jvm.options.d" );
70+
71+ if (Files .isDirectory (jvmOptionsDirectory )) {
72+ try (
73+ DirectoryStream <Path > jvmOptionsDirectoryStream = Files .newDirectoryStream (Paths .get (args [0 ], "jvm.options.d" ), "*.options" )
74+ ) {
75+ // collect the matching JVM options files after sorting them by Path::compareTo
76+ StreamSupport .stream (jvmOptionsDirectoryStream .spliterator (), false ).sorted ().forEach (jvmOptionsFiles ::add );
9177 }
92- final Map <String , String > substitutions = new HashMap <>();
93- substitutions .put ("ES_TMPDIR" , System .getenv ("ES_TMPDIR" ));
94- if (null != System .getenv ("ES_PATH_CONF" )) {
95- substitutions .put ("ES_PATH_CONF" , System .getenv ("ES_PATH_CONF" ));
78+ }
79+
80+ final List <String > jvmOptions = new ArrayList <>();
81+
82+ for (final Path jvmOptionsFile : jvmOptionsFiles ) {
83+ final SortedMap <Integer , String > invalidLines = new TreeMap <>();
84+ try (
85+ InputStream is = Files .newInputStream (jvmOptionsFile );
86+ Reader reader = new InputStreamReader (is , StandardCharsets .UTF_8 );
87+ BufferedReader br = new BufferedReader (reader )
88+ ) {
89+ parse (JavaVersion .majorVersion (JavaVersion .CURRENT ), br , jvmOptions ::add , invalidLines ::put );
9690 }
97- final List <String > substitutedJvmOptions = substitutePlaceholders (jvmOptions , Collections .unmodifiableMap (substitutions ));
98- final List <String > ergonomicJvmOptions = JvmErgonomics .choose (substitutedJvmOptions );
99- final List <String > systemJvmOptions = SystemJvmOptions .systemJvmOptions ();
100- final List <String > finalJvmOptions = new ArrayList <>(
101- systemJvmOptions .size () + substitutedJvmOptions .size () + ergonomicJvmOptions .size ()
102- );
103- finalJvmOptions .addAll (systemJvmOptions ); // add the system JVM options first so that they can be overridden
104- finalJvmOptions .addAll (substitutedJvmOptions );
105- finalJvmOptions .addAll (ergonomicJvmOptions );
106- final String spaceDelimitedJvmOptions = spaceDelimitJvmOptions (finalJvmOptions );
107- Launchers .outPrintln (spaceDelimitedJvmOptions );
108- Launchers .exit (0 );
109- } else {
110- final String errorMessage = String .format (
111- Locale .ROOT ,
112- "encountered [%d] error%s parsing [%s]" ,
113- invalidLines .size (),
114- invalidLines .size () == 1 ? "" : "s" ,
115- args [0 ]
116- );
117- Launchers .errPrintln (errorMessage );
118- int count = 0 ;
119- for (final Map .Entry <Integer , String > entry : invalidLines .entrySet ()) {
120- count ++;
121- final String message = String .format (
91+ if (invalidLines .isEmpty () == false ) {
92+ final String errorMessage = String .format (
12293 Locale .ROOT ,
123- "[%d]: encountered improperly formatted JVM option line [%s] on line number [%d ]" ,
124- count ,
125- entry . getValue () ,
126- entry . getKey ()
94+ "encountered [%d] error%s parsing [%s ]" ,
95+ invalidLines . size () ,
96+ invalidLines . size () == 1 ? "" : "s" ,
97+ jvmOptionsFile
12798 );
128- Launchers .errPrintln (message );
99+ Launchers .errPrintln (errorMessage );
100+ int count = 0 ;
101+ for (final Map .Entry <Integer , String > entry : invalidLines .entrySet ()) {
102+ count ++;
103+ final String message = String .format (
104+ Locale .ROOT ,
105+ "[%d]: encountered improperly formatted JVM option in [%s] on line number [%d]: [%s]" ,
106+ count ,
107+ jvmOptionsFile ,
108+ entry .getKey (),
109+ entry .getValue ()
110+ );
111+ Launchers .errPrintln (message );
112+ }
113+ Launchers .exit (1 );
129114 }
130- Launchers .exit (1 );
131115 }
116+
117+ // now append the JVM options from ES_JAVA_OPTS
118+ final String environmentJvmOptions = System .getenv ("ES_JAVA_OPTS" );
119+ if (environmentJvmOptions != null ) {
120+ jvmOptions .addAll (
121+ Arrays .stream (environmentJvmOptions .split ("\\ s+" ))
122+ .filter (Predicate .not (String ::isBlank ))
123+ .collect (Collectors .toUnmodifiableList ())
124+ );
125+ }
126+ final Map <String , String > substitutions = new HashMap <>();
127+ substitutions .put ("ES_TMPDIR" , System .getenv ("ES_TMPDIR" ));
128+ if (null != System .getenv ("ES_PATH_CONF" )) {
129+ substitutions .put ("ES_PATH_CONF" , System .getenv ("ES_PATH_CONF" ));
130+ }
131+ final List <String > substitutedJvmOptions = substitutePlaceholders (jvmOptions , Collections .unmodifiableMap (substitutions ));
132+ final List <String > ergonomicJvmOptions = JvmErgonomics .choose (substitutedJvmOptions );
133+ final List <String > systemJvmOptions = SystemJvmOptions .systemJvmOptions ();
134+ final List <String > finalJvmOptions = new ArrayList <>(
135+ systemJvmOptions .size () + substitutedJvmOptions .size () + ergonomicJvmOptions .size ()
136+ );
137+ finalJvmOptions .addAll (systemJvmOptions ); // add the system JVM options first so that they can be overridden
138+ finalJvmOptions .addAll (substitutedJvmOptions );
139+ finalJvmOptions .addAll (ergonomicJvmOptions );
140+ final String spaceDelimitedJvmOptions = spaceDelimitJvmOptions (finalJvmOptions );
141+ Launchers .outPrintln (spaceDelimitedJvmOptions );
142+ Launchers .exit (0 );
132143 }
133144
134145 static List <String > substitutePlaceholders (final List <String > jvmOptions , final Map <String , String > substitutions ) {
0 commit comments