src/share/classes/com/sun/tools/sjavac/server/JavacServiceClient.java

Print this page




  24  */
  25 
  26 package com.sun.tools.sjavac.server;
  27 
  28 import java.io.BufferedReader;
  29 import java.io.File;
  30 import java.io.FileReader;
  31 import java.io.IOException;
  32 import java.io.InputStreamReader;
  33 import java.io.PrintStream;
  34 import java.io.PrintWriter;
  35 import java.io.StringWriter;
  36 import java.net.InetAddress;
  37 import java.net.InetSocketAddress;
  38 import java.net.Socket;
  39 import java.net.SocketAddress;
  40 import java.net.URI;
  41 import java.util.Collections;
  42 import java.util.HashMap;
  43 import java.util.HashSet;

  44 import java.util.List;
  45 import java.util.Map;
  46 import java.util.Set;
  47 
  48 import com.sun.tools.sjavac.Util;
  49 import com.sun.tools.sjavac.options.Options;
  50 
  51 import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
  52 import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
  53 
  54 public class JavacServiceClient implements JavacService {
  55 
  56 
  57     // The id can perhaps be used in the future by the javac server to reuse the
  58     // JavaCompiler instance for several compiles using the same id.
  59     private final String id;
  60     private final String portfile;
  61     private final String logfile;
  62     private final String stdouterrfile;
  63     private final boolean background;


 119                                              Collections.<URI>emptySet(),
 120                                              Collections.<URI, Set<String>>emptyMap());
 121             return cr.sysinfo;
 122         } catch (Exception e) {
 123             return new SysInfo(-1, -1);
 124         }
 125     }
 126 
 127     @Override
 128     public CompilationResult compile(String protocolId,
 129                                      String invocationId,
 130                                      String[] args,
 131                                      List<File> explicitSources,
 132                                      Set<URI> sourcesToCompile,
 133                                      Set<URI> visibleSources) {
 134         // Delegate to useServer, which delegates to compileHelper
 135         return useServer(args, sourcesToCompile, visibleSources, null);
 136     }
 137 
 138     /**

























 139      * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
 140      * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
 141      */
 142     public CompilationResult compileHelper(String id,
 143                                            String[] args,
 144                                            Set<URI> sourcesToCompile,
 145                                            Set<URI> visibleSources) {
 146 
 147         CompilationResult rc = new CompilationResult(-3);
 148 
 149         try {
 150             PortFile portFile = JavacServer.getPortFile(this.portfile);
 151 
 152             int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
 153             if (port == 0) {
 154                 return new CompilationResult(ERROR_BUT_TRY_AGAIN);
 155             }
 156             long cookie = portFile.getCookie();
 157             // Acquire the localhost/127.0.0.1 address.
 158             InetAddress addr = InetAddress.getByName(null);


 264                     rc.packageArtifacts.put(pkg, lastUriSet);
 265                 } else if (l.length() > 1 && lastUriSet != null) {
 266                     lastUriSet.add(new URI(l.substring(1)));
 267                 }
 268             }
 269             // Load package dependencies
 270             Set<String> lastPackageSet = null;
 271             for (;;) {
 272                 String l = in.readLine();
 273                 if (l == null) {
 274                     return new CompilationResult(ERROR_FATAL);
 275                 }
 276                 if (l.equals(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS)) {
 277                     break;
 278                 }
 279                 if (l.length() > 1 && l.charAt(0) == '+') {
 280                     String pkg = l.substring(1);
 281                     lastPackageSet = new HashSet<>();
 282                     rc.packageDependencies.put(pkg, lastPackageSet);
 283                 } else if (l.length() > 1 && lastPackageSet != null) {





 284                     lastPackageSet.add(l.substring(1));
 285                 }
 286             }

 287             // Load package pubapis
 288             Map<String, StringBuffer> tmp = new HashMap<>();
 289             StringBuffer lastPublicApi = null;
 290             for (;;) {
 291                 String l = in.readLine();
 292                 if (l == null) {
 293                     return new CompilationResult(ERROR_FATAL);
 294                 }
 295                 if (l.equals(JavacServer.PROTOCOL_SYSINFO)) {
 296                     break;
 297                 }
 298                 if (l.length() > 1 && l.charAt(0) == '+') {
 299                     String pkg = l.substring(1);
 300                     lastPublicApi = new StringBuffer();
 301                     tmp.put(pkg, lastPublicApi);
 302                 } else if (l.length() > 1 && lastPublicApi != null) {
 303                     lastPublicApi.append(l.substring(1));
 304                     lastPublicApi.append("\n");
 305                 }
 306             }
 307             for (String p : tmp.keySet()) {
 308                 //assert (packagePublicApis.get(p) == null);
 309                 String api = tmp.get(p).toString();
 310                 rc.packagePubapis.put(p, api);
 311             }
 312             // Now reading the max memory possible.
 313             for (;;) {
 314                 String l = in.readLine();
 315                 if (l == null) {
 316                     return new CompilationResult(ERROR_FATAL);
 317                 }
 318                 if (l.equals(JavacServer.PROTOCOL_RETURN_CODE)) {
 319                     break;
 320                 }
 321                 if (l.startsWith("num_cores=")) {
 322                     rc.sysinfo.numCores = Integer.parseInt(l.substring(10));
 323                 }
 324                 if (l.startsWith("max_memory=")) {
 325                     rc.sysinfo.maxMemory = Long.parseLong(l.substring(11));
 326                 }
 327             }
 328             String l = in.readLine();
 329             if (l == null) {
 330                 rc.setReturnCode(ERROR_FATAL);
 331                 rc.stderr = "No return value from the server!";
 332                 return rc;
 333             }
 334             rc.setReturnCode(Integer.parseInt(l));
 335             rc.stdout = stdout.toString();
 336             rc.stderr = stderr.toString();


 337         } catch (Exception e) {
 338             StringWriter sw = new StringWriter();
 339             e.printStackTrace(new PrintWriter(sw));
 340             rc.stderr = sw.toString();
 341         }
 342         return rc;
 343     }
 344 
 345     /**
 346      * Dispatch a compilation request to a javac server.
 347      *
 348      * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
 349      *
 350      * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
 351      *
 352      * @param sources_to_compile The sources to compile.
 353      *
 354      * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
 355      * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
 356      *




  24  */
  25 
  26 package com.sun.tools.sjavac.server;
  27 
  28 import java.io.BufferedReader;
  29 import java.io.File;
  30 import java.io.FileReader;
  31 import java.io.IOException;
  32 import java.io.InputStreamReader;
  33 import java.io.PrintStream;
  34 import java.io.PrintWriter;
  35 import java.io.StringWriter;
  36 import java.net.InetAddress;
  37 import java.net.InetSocketAddress;
  38 import java.net.Socket;
  39 import java.net.SocketAddress;
  40 import java.net.URI;
  41 import java.util.Collections;
  42 import java.util.HashMap;
  43 import java.util.HashSet;
  44 import java.util.LinkedList;
  45 import java.util.List;
  46 import java.util.Map;
  47 import java.util.Set;
  48 
  49 import com.sun.tools.sjavac.Util;
  50 import com.sun.tools.sjavac.options.Options;
  51 
  52 import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
  53 import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
  54 
  55 public class JavacServiceClient implements JavacService {
  56 
  57 
  58     // The id can perhaps be used in the future by the javac server to reuse the
  59     // JavaCompiler instance for several compiles using the same id.
  60     private final String id;
  61     private final String portfile;
  62     private final String logfile;
  63     private final String stdouterrfile;
  64     private final boolean background;


 120                                              Collections.<URI>emptySet(),
 121                                              Collections.<URI, Set<String>>emptyMap());
 122             return cr.sysinfo;
 123         } catch (Exception e) {
 124             return new SysInfo(-1, -1);
 125         }
 126     }
 127 
 128     @Override
 129     public CompilationResult compile(String protocolId,
 130                                      String invocationId,
 131                                      String[] args,
 132                                      List<File> explicitSources,
 133                                      Set<URI> sourcesToCompile,
 134                                      Set<URI> visibleSources) {
 135         // Delegate to useServer, which delegates to compileHelper
 136         return useServer(args, sourcesToCompile, visibleSources, null);
 137     }
 138 
 139     /**
 140      * Extract the package name and the class from the string.
 141      * Deps will be a map from packag name to class name.
 142      */
 143     static void addClasspathPackageDependency(Map<String, Set<String>> deps, String fullname) {
 144         // Modules beware!
 145         String pkg;
 146         int p = fullname.lastIndexOf('.');
 147         if (p == -1) {
 148             // Arghh, a source file without a package.
 149             pkg = ":";
 150         }
 151         else {
 152             pkg = ":"+fullname.substring(0, p);
 153         }
 154         synchronized (deps) {
 155             Set<String> set = deps.get(pkg);
 156             if (set == null) {
 157                 set = new HashSet<String>();
 158                 deps.put(pkg, set);
 159             }
 160             set.add(fullname);
 161         }
 162     }
 163 
 164     /**
 165      * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
 166      * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
 167      */
 168     public CompilationResult compileHelper(String id,
 169                                            String[] args,
 170                                            Set<URI> sourcesToCompile,
 171                                            Set<URI> visibleSources) {
 172 
 173         CompilationResult rc = new CompilationResult(-3);
 174 
 175         try {
 176             PortFile portFile = JavacServer.getPortFile(this.portfile);
 177 
 178             int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
 179             if (port == 0) {
 180                 return new CompilationResult(ERROR_BUT_TRY_AGAIN);
 181             }
 182             long cookie = portFile.getCookie();
 183             // Acquire the localhost/127.0.0.1 address.
 184             InetAddress addr = InetAddress.getByName(null);


 290                     rc.packageArtifacts.put(pkg, lastUriSet);
 291                 } else if (l.length() > 1 && lastUriSet != null) {
 292                     lastUriSet.add(new URI(l.substring(1)));
 293                 }
 294             }
 295             // Load package dependencies
 296             Set<String> lastPackageSet = null;
 297             for (;;) {
 298                 String l = in.readLine();
 299                 if (l == null) {
 300                     return new CompilationResult(ERROR_FATAL);
 301                 }
 302                 if (l.equals(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS)) {
 303                     break;
 304                 }
 305                 if (l.length() > 1 && l.charAt(0) == '+') {
 306                     String pkg = l.substring(1);
 307                     lastPackageSet = new HashSet<>();
 308                     rc.packageDependencies.put(pkg, lastPackageSet);
 309                 } else if (l.length() > 1 && lastPackageSet != null) {
 310                             if (l.startsWith(" :. ")) {
 311                                     // This is a classpath dependency.
 312                                     addClasspathPackageDependency(rc.classpathPackageDependencies, l.substring(4));
 313                             } else {
 314                                     // Standard package dependency.
 315                         lastPackageSet.add(l.substring(1));
 316                     }
 317                 }
 318             }
 319             // Load package pubapis
 320             List<String> lastPublicApi = new LinkedList<>();

 321             for (;;) {
 322                 String l = in.readLine();
 323                 if (l == null) {
 324                     return new CompilationResult(ERROR_FATAL);
 325                 }
 326                 if (l.equals(JavacServer.PROTOCOL_SYSINFO)) {
 327                     break;
 328                 }
 329                 if (l.length() > 1 && l.charAt(0) == '+') {
 330                     String pkg = l.substring(1);
 331                     lastPublicApi = new LinkedList<>();
 332                     rc.packagePublicApis.put(pkg, lastPublicApi);
 333                 } else if (l.length() > 1 && lastPublicApi != null) {
 334                     lastPublicApi.add(l.substring(1));


 335                 }




 336             }
 337             // Now reading the max memory possible.
 338             for (;;) {
 339                 String l = in.readLine();
 340                 if (l == null) {
 341                     return new CompilationResult(ERROR_FATAL);
 342                 }
 343                 if (l.equals(JavacServer.PROTOCOL_RETURN_CODE)) {
 344                     break;
 345                 }
 346                 if (l.startsWith("num_cores=")) {
 347                     rc.sysinfo.numCores = Integer.parseInt(l.substring(10));
 348                 }
 349                 if (l.startsWith("max_memory=")) {
 350                     rc.sysinfo.maxMemory = Long.parseLong(l.substring(11));
 351                 }
 352             }
 353             String l = in.readLine();
 354             if (l == null) {
 355                 rc.setReturnCode(ERROR_FATAL);
 356                 rc.stderr = "No return value from the server!";
 357                 return rc;
 358             }
 359             rc.setReturnCode(Integer.parseInt(l));
 360             rc.stdout = stdout.toString();
 361             rc.stderr = stderr.toString();
 362             System.out.print(rc.stdout);
 363             System.err.print(rc.stderr);
 364         } catch (Exception e) {
 365             StringWriter sw = new StringWriter();
 366             e.printStackTrace(new PrintWriter(sw));
 367             rc.stderr = sw.toString();
 368         }
 369         return rc;
 370     }
 371 
 372     /**
 373      * Dispatch a compilation request to a javac server.
 374      *
 375      * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
 376      *
 377      * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
 378      *
 379      * @param sources_to_compile The sources to compile.
 380      *
 381      * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
 382      * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
 383      *