1
1
/*
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.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
34
34
import java .net .InetAddress ;
35
35
import java .net .InetSocketAddress ;
36
36
import java .net .Socket ;
37
+ import java .nio .charset .StandardCharsets ;
38
+ import java .nio .file .Files ;
39
+ import java .nio .file .Path ;
37
40
import java .util .ArrayList ;
38
41
import java .util .Arrays ;
39
42
import java .util .List ;
42
45
import com .sun .tools .javac .main .Main .Result ;
43
46
import com .sun .tools .sjavac .Log ;
44
47
import com .sun .tools .sjavac .Util ;
45
- import com .sun .tools .sjavac .options .OptionHelper ;
46
48
import com .sun .tools .sjavac .options .Options ;
47
- import com .sun .tools .sjavac .server .CompilationSubResult ;
48
49
import com .sun .tools .sjavac .server .PortFile ;
49
50
import com .sun .tools .sjavac .server .Sjavac ;
50
51
import com .sun .tools .sjavac .server .SjavacServer ;
51
52
52
- import static java .util .stream .Collectors .joining ;
53
-
54
53
/**
55
54
* Sjavac implementation that delegates requests to a SjavacServer.
56
55
*
61
60
*/
62
61
public class SjavacClient implements Sjavac {
63
62
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 ;
73
64
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 ;
79
68
69
+ // Accept 120 seconds of inactivity before quitting.
70
+ private static final int KEEPALIVE = 120 ;
71
+ private static final int POOLSIZE = Runtime .getRuntime ().availableProcessors ();
80
72
// 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 ;
87
76
88
77
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 , "" );
102
80
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 );
106
84
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
+ }
113
106
}
114
107
115
108
@ Override
116
109
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
+
117
115
Result result = null ;
118
116
try (Socket socket = tryConnect ()) {
119
117
PrintWriter out = new PrintWriter (new OutputStreamWriter (socket .getOutputStream ()));
@@ -176,7 +174,7 @@ public Result compile(String[] args) {
176
174
* Makes MAX_CONNECT_ATTEMPTS attempts to connect to server.
177
175
*/
178
176
private Socket tryConnect () throws IOException , InterruptedException {
179
- makeSureServerIsRunning (portFile );
177
+ makeSureServerIsRunning ();
180
178
int attempt = 0 ;
181
179
while (true ) {
182
180
Log .debug ("Trying to connect. Attempt " + (++attempt ) + " of " + MAX_CONNECT_ATTEMPTS );
@@ -206,7 +204,7 @@ private Socket makeConnectionAttempt() throws IOException {
206
204
* Will return immediately if a server already seems to be running,
207
205
* otherwise fork a new server and block until it seems to be running.
208
206
*/
209
- private void makeSureServerIsRunning (PortFile portFile )
207
+ private void makeSureServerIsRunning ()
210
208
throws IOException , InterruptedException {
211
209
212
210
if (portFile .exists ()) {
@@ -221,10 +219,7 @@ private void makeSureServerIsRunning(PortFile portFile)
221
219
}
222
220
223
221
// Fork a new server and wait for it to start
224
- SjavacClient .fork (sjavacForkCmd ,
225
- portFile ,
226
- poolsize ,
227
- keepalive );
222
+ startNewServer ();
228
223
}
229
224
230
225
@ Override
@@ -235,14 +230,14 @@ public void shutdown() {
235
230
/*
236
231
* Fork a server process process and wait for server to come around
237
232
*/
238
- public static void fork ( String sjavacCmd , PortFile portFile , int poolsize , int keepalive )
233
+ public void startNewServer ( )
239
234
throws IOException , InterruptedException {
240
235
List <String > cmd = new ArrayList <>();
241
- cmd .addAll (Arrays .asList (OptionHelper . unescapeCmdArg ( sjavacCmd ) .split (" " )));
236
+ cmd .addAll (Arrays .asList (serverCommand .split (" " )));
242
237
cmd .add ("--startserver:"
243
238
+ "portfile=" + portFile .getFilename ()
244
- + ",poolsize=" + poolsize
245
- + ",keepalive=" + keepalive );
239
+ + ",poolsize=" + POOLSIZE
240
+ + ",keepalive=" + KEEPALIVE );
246
241
247
242
Process serverProcess ;
248
243
Log .debug ("Starting server. Command: " + String .join (" " , cmd ));
0 commit comments