Skip to content

Commit 9e4944f

Browse files
committedNov 24, 2020
8256308: Send arguments to javac server in a config file
Reviewed-by: erikj, jfranck
1 parent 8f7caa4 commit 9e4944f

File tree

3 files changed

+96
-77
lines changed

3 files changed

+96
-77
lines changed
 

‎make/common/JavaCompilation.gmk

+33-17
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ define SetupJavaCompilationBody
177177
$$(error Must specify BIN (in $1))
178178
endif
179179

180+
ifneq ($$($1_MODULE), )
181+
$1_MODULE_SUBDIR := /$$($1_MODULE)
182+
endif
183+
184+
$1_SAFE_NAME := $$(strip $$(subst /,_, $1))
185+
180186
ifeq ($$($1_SMALL_JAVA), )
181187
# If unspecified, default to true
182188
$1_SMALL_JAVA := true
@@ -215,18 +221,35 @@ define SetupJavaCompilationBody
215221
ifeq ($$(ENABLE_JAVAC_SERVER)+$$($1_CLASSPATH), true+)
216222
$1_JAVAC := $$(INTERIM_LANGTOOLS_ARGS) -m jdk.compiler.interim/com.sun.tools.sjavac.Main
217223

218-
# How to launch the server. This must use JAVA_DETACH, which is the "big" java
219-
# with an ability to detach from fixpath (on Windows)
220-
# This will be executed by the client, if needed.
221-
$1_JAVAC_SERVER_CMD := $$(JAVA_DETACH) $$($1_JAVA_FLAGS) $$($1_JAVAC)
222-
$1_ESCAPED_CMD := $$(subst $$(SPACE),%20,$$(subst $$(COMMA),%2C,$$(strip $$($1_JAVAC_SERVER_CMD))))
224+
# Create a configuration file with the needed information for the javac
225+
# server to function properly.
226+
$1_JAVAC_SERVER_CONFIG := $$($1_BIN)$$($1_MODULE_SUBDIR)/_the.$$($1_SAFE_NAME)-server.conf
223227

224-
# The port file contains the tcp/ip on which the server listens
228+
# The portfile contains the tcp/ip on which the server listens
225229
# and the cookie necessary to talk to the server.
226-
$1_JAVA_SERVER_FLAGS := --server:portfile=$$(JAVAC_SERVER_DIR)/server.port,sjavac=$$($1_ESCAPED_CMD)
230+
$1_JAVAC_PORT_FILE := $$(JAVAC_SERVER_DIR)/server.port
231+
232+
# The servercmd specified how to launch the server. This must use
233+
# JAVA_DETACH, which is the "big" java with an ability to detach from
234+
# fixpath (on Windows) This will be executed by the client, if needed.
235+
$1_JAVAC_SERVER_CMD := $$(JAVA_DETACH) $$($1_JAVA_FLAGS) $$($1_JAVAC)
236+
237+
$1_CONFIG_VARDEPS := $$($1_JAVAC_PORT_FILE) $$($1_JAVAC_SERVER_CMD)
238+
$1_CONFIG_VARDEPS_FILE := $$(call DependOnVariable, $1_CONFIG_VARDEPS, \
239+
$$($1_BIN)$$($1_MODULE_SUBDIR)/_the.$1.config_vardeps)
227240

228-
# Always use small to launch client
229-
$1_JAVAC_CMD := $$(JAVA_SMALL) $$($1_JAVA_FLAGS) $$($1_JAVAC) $$($1_JAVA_SERVER_FLAGS)
241+
ifeq ($(call isBuildOs, windows), true)
242+
$1_ECHO_COMMAND := $(FIXPATH) cmd /c echo
243+
else
244+
$1_ECHO_COMMAND := $(ECHO)
245+
endif
246+
$$($1_JAVAC_SERVER_CONFIG): $$($1_CONFIG_VARDEPS_FILE)
247+
$$($1_ECHO_COMMAND) portfile=$$($1_JAVAC_PORT_FILE) > $$@
248+
$$($1_ECHO_COMMAND) servercmd=$$($1_JAVAC_SERVER_CMD) >> $$@
249+
250+
# Always use small java to launch client
251+
$1_JAVAC_CMD := $$(JAVA_SMALL) $$($1_JAVA_FLAGS) $$($1_JAVAC) \
252+
--server:conf=$$($1_JAVAC_SERVER_CONFIG)
230253
else
231254
# No javac server
232255
$1_JAVAC := $$(INTERIM_LANGTOOLS_ARGS) -m jdk.compiler.interim/com.sun.tools.javac.Main
@@ -263,10 +286,6 @@ define SetupJavaCompilationBody
263286
$1_FLAGS += -cp $$(call PathList, $$($1_CLASSPATH))
264287
endif
265288

266-
ifneq ($$($1_MODULE), )
267-
$1_MODULE_SUBDIR := /$$($1_MODULE)
268-
endif
269-
270289
# Make sure the dirs exist, or that one of the EXTRA_FILES, that may not
271290
# exist yet, is in it.
272291
$$(foreach d, $$($1_SRC), \
@@ -331,9 +350,6 @@ define SetupJavaCompilationBody
331350
$$(error No source files found for $1)
332351
endif
333352
else
334-
335-
$1_SAFE_NAME := $$(strip $$(subst /,_, $1))
336-
337353
# All files below META-INF are always copied.
338354
$1_ALL_COPIES := $$(filter $$(addsuffix /META-INF%,$$($1_SRC)),$$($1_ALL_SRCS))
339355
# Find all files to be copied from source to bin.
@@ -442,7 +458,7 @@ define SetupJavaCompilationBody
442458

443459
# Do the actual compilation
444460
$$($1_COMPILE_TARGET): $$($1_SRCS) $$($1_FILELIST) $$($1_DEPENDS) \
445-
$$($1_VARDEPS_FILE) $$($1_EXTRA_DEPS)
461+
$$($1_VARDEPS_FILE) $$($1_EXTRA_DEPS) $$($1_JAVAC_SERVER_CONFIG)
446462
$$(call MakeDir, $$(@D))
447463
$$(call ExecuteWithLog, $$($1_BIN)$$($1_MODULE_SUBDIR)/_the.$$($1_SAFE_NAME)_batch, \
448464
$$($1_JAVAC_CMD) $$($1_FLAGS) \

‎src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -79,15 +79,23 @@ public static String extractStringOption(String opName, String s) {
7979
return extractStringOption(opName, s, null);
8080
}
8181

82-
public static String extractStringOption(String opName, String s, String deflt) {
82+
private static String extractStringOptionWithDelimiter(String opName, String s, String deflt, char delimiter) {
8383
int p = s.indexOf(opName+"=");
8484
if (p == -1) return deflt;
8585
p+=opName.length()+1;
86-
int pe = s.indexOf(',', p);
86+
int pe = s.indexOf(delimiter, p);
8787
if (pe == -1) pe = s.length();
8888
return s.substring(p, pe);
8989
}
9090

91+
public static String extractStringOption(String opName, String s, String deflt) {
92+
return extractStringOptionWithDelimiter(opName, s, deflt, ',');
93+
}
94+
95+
public static String extractStringOptionLine(String opName, String s, String deflt) {
96+
return extractStringOptionWithDelimiter(opName, s, deflt, '\n').strip();
97+
}
98+
9199
public static boolean extractBooleanOption(String opName, String s, boolean deflt) {
92100
String str = extractStringOption(opName, s);
93101
return "true".equals(str) ? true

‎src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java

+52-57
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,9 @@
3434
import java.net.InetAddress;
3535
import java.net.InetSocketAddress;
3636
import java.net.Socket;
37+
import java.nio.charset.StandardCharsets;
38+
import java.nio.file.Files;
39+
import java.nio.file.Path;
3740
import java.util.ArrayList;
3841
import java.util.Arrays;
3942
import java.util.List;
@@ -42,15 +45,11 @@
4245
import com.sun.tools.javac.main.Main.Result;
4346
import com.sun.tools.sjavac.Log;
4447
import com.sun.tools.sjavac.Util;
45-
import com.sun.tools.sjavac.options.OptionHelper;
4648
import com.sun.tools.sjavac.options.Options;
47-
import com.sun.tools.sjavac.server.CompilationSubResult;
4849
import com.sun.tools.sjavac.server.PortFile;
4950
import com.sun.tools.sjavac.server.Sjavac;
5051
import com.sun.tools.sjavac.server.SjavacServer;
5152

52-
import static java.util.stream.Collectors.joining;
53-
5453
/**
5554
* Sjavac implementation that delegates requests to a SjavacServer.
5655
*
@@ -61,59 +60,58 @@
6160
*/
6261
public class SjavacClient implements Sjavac {
6362

64-
// The id can perhaps be used in the future by the javac server to reuse the
65-
// JavaCompiler instance for several compiles using the same id.
66-
private final String id;
67-
private final PortFile portFile;
68-
69-
// Default keepalive for server is 120 seconds.
70-
// I.e. it will accept 120 seconds of inactivity before quitting.
71-
private final int keepalive;
72-
private final int poolsize;
63+
private PortFile portFile;
7364

74-
// The sjavac option specifies how the server part of sjavac is spawned.
75-
// If you have the experimental sjavac in your path, you are done. If not, you have
76-
// to point to a com.sun.tools.sjavac.Main that supports --startserver
77-
// for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
78-
private final String sjavacForkCmd;
65+
// The servercmd option specifies how the server part of sjavac is spawned.
66+
// It should point to a com.sun.tools.sjavac.Main that supports --startserver
67+
private String serverCommand;
7968

69+
// Accept 120 seconds of inactivity before quitting.
70+
private static final int KEEPALIVE = 120;
71+
private static final int POOLSIZE = Runtime.getRuntime().availableProcessors();
8072
// Wait 2 seconds for response, before giving up on javac server.
81-
static int CONNECTION_TIMEOUT = 2000;
82-
static int MAX_CONNECT_ATTEMPTS = 3;
83-
static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 2000;
84-
85-
// Store the server conf settings here.
86-
private final String settings;
73+
private static final int CONNECTION_TIMEOUT = 2000;
74+
private static final int MAX_CONNECT_ATTEMPTS = 3;
75+
private static final int WAIT_BETWEEN_CONNECT_ATTEMPTS = 2000;
8776

8877
public SjavacClient(Options options) {
89-
String tmpServerConf = options.getServerConf();
90-
String serverConf = (tmpServerConf!=null)? tmpServerConf : "";
91-
String tmpId = Util.extractStringOption("id", serverConf);
92-
id = (tmpId!=null) ? tmpId : "id"+(((new java.util.Random()).nextLong())&Long.MAX_VALUE);
93-
String defaultPortfile = options.getDestDir()
94-
.resolve("javac_server")
95-
.toAbsolutePath()
96-
.toString();
97-
String portfileName = Util.extractStringOption("portfile", serverConf, defaultPortfile);
98-
portFile = SjavacServer.getPortFile(portfileName);
99-
sjavacForkCmd = Util.extractStringOption("sjavac", serverConf, "sjavac");
100-
int poolsize = Util.extractIntOption("poolsize", serverConf);
101-
keepalive = Util.extractIntOption("keepalive", serverConf, 120);
78+
String serverConf = options.getServerConf();
79+
String configFile = Util.extractStringOption("conf", serverConf, "");
10280

103-
this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
104-
settings = (serverConf.equals("")) ? "id="+id+",portfile="+portfileName : serverConf;
105-
}
81+
try {
82+
List<String> configFileLines = Files.readAllLines(Path.of(configFile), StandardCharsets.UTF_8);
83+
String configFileContent = String.join("\n", configFileLines);
10684

107-
/**
108-
* Hand out the server settings.
109-
* @return The server settings, possibly a default value.
110-
*/
111-
public String serverSettings() {
112-
return settings;
85+
String portfileName = Util.extractStringOptionLine("portfile", configFileContent, "");
86+
if (portfileName.isEmpty()) {
87+
Log.error("Configuration file missing value for 'portfile'");
88+
portFile = null;
89+
} else {
90+
portFile = SjavacServer.getPortFile(portfileName);
91+
}
92+
93+
String serverCommandString = Util.extractStringOptionLine("servercmd", configFileContent, "");
94+
if (serverCommandString.isEmpty()) {
95+
Log.error("Configuration file missing value for 'servercmd'");
96+
serverCommand = null;
97+
} else {
98+
serverCommand = serverCommandString;
99+
}
100+
} catch (IOException e) {
101+
Log.error("Cannot read configuration file " + configFile);
102+
Log.debug(e);
103+
portFile = null;
104+
serverCommand = null;
105+
}
113106
}
114107

115108
@Override
116109
public Result compile(String[] args) {
110+
if (portFile == null || serverCommand == null) {
111+
Log.error("Incorrect configuration, portfile and/or servercmd missing");
112+
return Result.ERROR;
113+
}
114+
117115
Result result = null;
118116
try (Socket socket = tryConnect()) {
119117
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
@@ -176,7 +174,7 @@ public Result compile(String[] args) {
176174
* Makes MAX_CONNECT_ATTEMPTS attempts to connect to server.
177175
*/
178176
private Socket tryConnect() throws IOException, InterruptedException {
179-
makeSureServerIsRunning(portFile);
177+
makeSureServerIsRunning();
180178
int attempt = 0;
181179
while (true) {
182180
Log.debug("Trying to connect. Attempt " + (++attempt) + " of " + MAX_CONNECT_ATTEMPTS);
@@ -206,7 +204,7 @@ private Socket makeConnectionAttempt() throws IOException {
206204
* Will return immediately if a server already seems to be running,
207205
* otherwise fork a new server and block until it seems to be running.
208206
*/
209-
private void makeSureServerIsRunning(PortFile portFile)
207+
private void makeSureServerIsRunning()
210208
throws IOException, InterruptedException {
211209

212210
if (portFile.exists()) {
@@ -221,10 +219,7 @@ private void makeSureServerIsRunning(PortFile portFile)
221219
}
222220

223221
// Fork a new server and wait for it to start
224-
SjavacClient.fork(sjavacForkCmd,
225-
portFile,
226-
poolsize,
227-
keepalive);
222+
startNewServer();
228223
}
229224

230225
@Override
@@ -235,14 +230,14 @@ public void shutdown() {
235230
/*
236231
* Fork a server process process and wait for server to come around
237232
*/
238-
public static void fork(String sjavacCmd, PortFile portFile, int poolsize, int keepalive)
233+
public void startNewServer()
239234
throws IOException, InterruptedException {
240235
List<String> cmd = new ArrayList<>();
241-
cmd.addAll(Arrays.asList(OptionHelper.unescapeCmdArg(sjavacCmd).split(" ")));
236+
cmd.addAll(Arrays.asList(serverCommand.split(" ")));
242237
cmd.add("--startserver:"
243238
+ "portfile=" + portFile.getFilename()
244-
+ ",poolsize=" + poolsize
245-
+ ",keepalive="+ keepalive);
239+
+ ",poolsize=" + POOLSIZE
240+
+ ",keepalive="+ KEEPALIVE);
246241

247242
Process serverProcess;
248243
Log.debug("Starting server. Command: " + String.join(" ", cmd));

0 commit comments

Comments
 (0)
Please sign in to comment.