mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8048594: The sjavac client/server protocol should be hidden behind an interface
Reviewed-by: jfranck
This commit is contained in:
parent
ce0935812b
commit
8baafcf7ef
17 changed files with 697 additions and 459 deletions
|
@ -36,6 +36,7 @@ import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import com.sun.tools.sjavac.options.Options;
|
import com.sun.tools.sjavac.options.Options;
|
||||||
|
import com.sun.tools.sjavac.server.JavacService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The clean properties transform should not be necessary.
|
* The clean properties transform should not be necessary.
|
||||||
|
@ -56,7 +57,8 @@ public class CleanProperties implements Transformer
|
||||||
// Any extra information is ignored for clean properties.
|
// Any extra information is ignored for clean properties.
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean transform(Map<String,Set<URI>> pkgSrcs,
|
public boolean transform(JavacService javacService,
|
||||||
|
Map<String,Set<URI>> pkgSrcs,
|
||||||
Set<URI> visibleSrcs,
|
Set<URI> visibleSrcs,
|
||||||
Map<URI,Set<String>> visibleClasses,
|
Map<URI,Set<String>> visibleClasses,
|
||||||
Map<String,Set<String>> oldPackageDependencies,
|
Map<String,Set<String>> oldPackageDependencies,
|
||||||
|
|
|
@ -25,15 +25,18 @@
|
||||||
|
|
||||||
package com.sun.tools.sjavac;
|
package com.sun.tools.sjavac;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sun.tools.sjavac.options.Options;
|
import com.sun.tools.sjavac.options.Options;
|
||||||
import com.sun.tools.sjavac.server.JavacServer;
|
import com.sun.tools.sjavac.server.CompilationResult;
|
||||||
|
import com.sun.tools.sjavac.server.JavacService;
|
||||||
import com.sun.tools.sjavac.server.SysInfo;
|
import com.sun.tools.sjavac.server.SysInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,9 +67,10 @@ public class CompileJavaPackages implements Transformer {
|
||||||
args = a;
|
args = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean transform(Map<String,Set<URI>> pkgSrcs,
|
public boolean transform(final JavacService javacService,
|
||||||
Set<URI> visibleSources,
|
Map<String,Set<URI>> pkgSrcs,
|
||||||
Map<URI,Set<String>> visibleClasses,
|
final Set<URI> visibleSources,
|
||||||
|
final Map<URI,Set<String>> visibleClasses,
|
||||||
Map<String,Set<String>> oldPackageDependents,
|
Map<String,Set<String>> oldPackageDependents,
|
||||||
URI destRoot,
|
URI destRoot,
|
||||||
final Map<String,Set<URI>> packageArtifacts,
|
final Map<String,Set<URI>> packageArtifacts,
|
||||||
|
@ -75,24 +79,25 @@ public class CompileJavaPackages implements Transformer {
|
||||||
int debugLevel,
|
int debugLevel,
|
||||||
boolean incremental,
|
boolean incremental,
|
||||||
int numCores,
|
int numCores,
|
||||||
PrintStream out,
|
final PrintStream out,
|
||||||
PrintStream err)
|
final PrintStream err)
|
||||||
{
|
{
|
||||||
boolean rc = true;
|
boolean rc = true;
|
||||||
boolean concurrentCompiles = true;
|
boolean concurrentCompiles = true;
|
||||||
|
|
||||||
// Fetch the id.
|
// Fetch the id.
|
||||||
String id = Util.extractStringOption("id", args.getServerConf());
|
String idOpt = Util.extractStringOption("id", args.getServerConf());
|
||||||
if (id == null || id.equals("")) {
|
if (idOpt == null || idOpt.equals("")) {
|
||||||
// No explicit id set. Create a random id so that the requests can be
|
// No explicit id set. Create a random id so that the requests can be
|
||||||
// grouped properly in the server.
|
// grouped properly in the server.
|
||||||
id = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
|
idOpt = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
final String id = idOpt;
|
||||||
// Only keep portfile and sjavac settings..
|
// Only keep portfile and sjavac settings..
|
||||||
String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), args.getServerConf());
|
String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), args.getServerConf());
|
||||||
|
|
||||||
// Get maximum heap size from the server!
|
// Get maximum heap size from the server!
|
||||||
SysInfo sysinfo = JavacServer.connectGetSysInfo(psServerSettings, out, err);
|
SysInfo sysinfo = javacService.getSysInfo();
|
||||||
if (sysinfo.numCores == -1) {
|
if (sysinfo.numCores == -1) {
|
||||||
Log.error("Could not query server for sysinfo!");
|
Log.error("Could not query server for sysinfo!");
|
||||||
return false;
|
return false;
|
||||||
|
@ -201,13 +206,10 @@ public class CompileJavaPackages implements Transformer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The return values for each chunked compile.
|
// The return values for each chunked compile.
|
||||||
final int[] rn = new int[numCompiles];
|
final CompilationResult[] rn = new CompilationResult[numCompiles];
|
||||||
// The requets, might or might not run as a background thread.
|
// The requets, might or might not run as a background thread.
|
||||||
final Thread[] requests = new Thread[numCompiles];
|
final Thread[] requests = new Thread[numCompiles];
|
||||||
|
|
||||||
final Set<URI> fvisible_sources = visibleSources;
|
|
||||||
final Map<URI,Set<String>> fvisible_classes = visibleClasses;
|
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
for (int i=0; i<numCompiles; ++i) {
|
for (int i=0; i<numCompiles; ++i) {
|
||||||
|
@ -215,23 +217,20 @@ public class CompileJavaPackages implements Transformer {
|
||||||
final CompileChunk cc = compileChunks[i];
|
final CompileChunk cc = compileChunks[i];
|
||||||
|
|
||||||
// Pass the num_cores and the id (appended with the chunk number) to the server.
|
// Pass the num_cores and the id (appended with the chunk number) to the server.
|
||||||
final String cleanedServerSettings = psServerSettings+",poolsize="+numCores+",id="+id+"-"+ii;
|
final String cleanedServerSettings = psServerSettings+",poolsize="+numCores+",id="+id+"-"+i;
|
||||||
final PrintStream fout = out;
|
|
||||||
final PrintStream ferr = err;
|
|
||||||
|
|
||||||
requests[ii] = new Thread() {
|
requests[i] = new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
rn[ii] = JavacServer.useServer(cleanedServerSettings,
|
rn[ii] = javacService.compile("n/a",
|
||||||
args.prepJavacArgs(),
|
id + "-" + ii,
|
||||||
cc.srcs,
|
args.prepJavacArgs(),
|
||||||
fvisible_sources,
|
Collections.<File>emptyList(),
|
||||||
fvisible_classes,
|
cc.srcs,
|
||||||
packageArtifacts,
|
visibleSources);
|
||||||
packageDependencies,
|
packageArtifacts.putAll(rn[ii].packageArtifacts);
|
||||||
packagePubapis,
|
packageDependencies.putAll(rn[ii].packageDependencies);
|
||||||
null,
|
packagePubapis.putAll(rn[ii].packagePubapis);
|
||||||
fout, ferr);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -253,7 +252,7 @@ public class CompileJavaPackages implements Transformer {
|
||||||
else {
|
else {
|
||||||
requests[ii].run();
|
requests[ii].run();
|
||||||
// If there was an error, then stop early when running single threaded.
|
// If there was an error, then stop early when running single threaded.
|
||||||
if (rn[i] != 0) {
|
if (rn[i].returnCode != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +268,7 @@ public class CompileJavaPackages implements Transformer {
|
||||||
// Check the return values.
|
// Check the return values.
|
||||||
for (int i=0; i<numCompiles; ++i) {
|
for (int i=0; i<numCompiles; ++i) {
|
||||||
if (compileChunks[i].srcs.size() > 0) {
|
if (compileChunks[i].srcs.size() > 0) {
|
||||||
if (rn[i] != 0) {
|
if (rn[i].returnCode != 0) {
|
||||||
rc = false;
|
rc = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sun.tools.sjavac.options.Options;
|
import com.sun.tools.sjavac.options.Options;
|
||||||
|
import com.sun.tools.sjavac.server.JavacService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile properties transform a properties file into a Java source file.
|
* Compile properties transform a properties file into a Java source file.
|
||||||
|
@ -63,7 +64,8 @@ public class CompileProperties implements Transformer
|
||||||
public void setExtra(Options a) {
|
public void setExtra(Options a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean transform(Map<String,Set<URI>> pkgSrcs,
|
public boolean transform(JavacService javacService,
|
||||||
|
Map<String,Set<URI>> pkgSrcs,
|
||||||
Set<URI> visibleSrcs,
|
Set<URI> visibleSrcs,
|
||||||
Map<URI,Set<String>> visibleClasses,
|
Map<URI,Set<String>> visibleClasses,
|
||||||
Map<String,Set<String>> oldPackageDependents,
|
Map<String,Set<String>> oldPackageDependents,
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sun.tools.sjavac.options.Options;
|
import com.sun.tools.sjavac.options.Options;
|
||||||
|
import com.sun.tools.sjavac.server.JavacService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The copy file transform simply copies a matching file from -src to -d .
|
* The copy file transform simply copies a matching file from -src to -d .
|
||||||
|
@ -50,7 +51,8 @@ public class CopyFile implements Transformer {
|
||||||
public void setExtra(Options a) {
|
public void setExtra(Options a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean transform(Map<String,Set<URI>> pkgSrcs,
|
public boolean transform(JavacService javacService,
|
||||||
|
Map<String,Set<URI>> pkgSrcs,
|
||||||
Set<URI> visibleSrcs,
|
Set<URI> visibleSrcs,
|
||||||
Map<URI,Set<String>> visibleClasses,
|
Map<URI,Set<String>> visibleClasses,
|
||||||
Map<String,Set<String>> oldPackageDependents,
|
Map<String,Set<String>> oldPackageDependents,
|
||||||
|
|
|
@ -40,6 +40,7 @@ import java.util.*;
|
||||||
|
|
||||||
import com.sun.tools.sjavac.options.Options;
|
import com.sun.tools.sjavac.options.Options;
|
||||||
import com.sun.tools.sjavac.options.SourceLocation;
|
import com.sun.tools.sjavac.options.SourceLocation;
|
||||||
|
import com.sun.tools.sjavac.server.JavacService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The javac state class maintains the previous (prev) and the current (now)
|
* The javac state class maintains the previous (prev) and the current (now)
|
||||||
|
@ -625,7 +626,7 @@ public class JavacState
|
||||||
sr.put(e.getKey(), e.getValue());
|
sr.put(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
perform(binDir, sr);
|
perform(null, binDir, sr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -641,20 +642,21 @@ public class JavacState
|
||||||
|
|
||||||
sr.put(e.getKey(), e.getValue());
|
sr.put(e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
perform(gensrcDir, sr);
|
perform(null, gensrcDir, sr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile all the java sources. Return true, if it needs to be called again!
|
* Compile all the java sources. Return true, if it needs to be called again!
|
||||||
*/
|
*/
|
||||||
public boolean performJavaCompilations(Options args,
|
public boolean performJavaCompilations(JavacService javacService,
|
||||||
|
Options args,
|
||||||
Set<String> recentlyCompiled,
|
Set<String> recentlyCompiled,
|
||||||
boolean[] rcValue) {
|
boolean[] rcValue) {
|
||||||
Map<String,Transformer> suffixRules = new HashMap<>();
|
Map<String,Transformer> suffixRules = new HashMap<>();
|
||||||
suffixRules.put(".java", compileJavaPackages);
|
suffixRules.put(".java", compileJavaPackages);
|
||||||
compileJavaPackages.setExtra(args);
|
compileJavaPackages.setExtra(args);
|
||||||
|
|
||||||
rcValue[0] = perform(binDir, suffixRules);
|
rcValue[0] = perform(javacService, binDir, suffixRules);
|
||||||
recentlyCompiled.addAll(taintedPackages());
|
recentlyCompiled.addAll(taintedPackages());
|
||||||
clearTaintedPackages();
|
clearTaintedPackages();
|
||||||
boolean again = !packagesWithChangedPublicApis.isEmpty();
|
boolean again = !packagesWithChangedPublicApis.isEmpty();
|
||||||
|
@ -684,7 +686,9 @@ public class JavacState
|
||||||
* For all packages, find all sources belonging to the package, group the sources
|
* For all packages, find all sources belonging to the package, group the sources
|
||||||
* based on their transformers and apply the transformers on each source code group.
|
* based on their transformers and apply the transformers on each source code group.
|
||||||
*/
|
*/
|
||||||
private boolean perform(File outputDir, Map<String,Transformer> suffixRules)
|
private boolean perform(JavacService javacService,
|
||||||
|
File outputDir,
|
||||||
|
Map<String,Transformer> suffixRules)
|
||||||
{
|
{
|
||||||
boolean rc = true;
|
boolean rc = true;
|
||||||
// Group sources based on transforms. A source file can only belong to a single transform.
|
// Group sources based on transforms. A source file can only belong to a single transform.
|
||||||
|
@ -709,7 +713,8 @@ public class JavacState
|
||||||
Map<String,String> packagePublicApis =
|
Map<String,String> packagePublicApis =
|
||||||
Collections.synchronizedMap(new HashMap<String, String>());
|
Collections.synchronizedMap(new HashMap<String, String>());
|
||||||
|
|
||||||
boolean r = t.transform(srcs,
|
boolean r = t.transform(javacService,
|
||||||
|
srcs,
|
||||||
visibleSrcs,
|
visibleSrcs,
|
||||||
visibleClasses,
|
visibleClasses,
|
||||||
prev.dependents(),
|
prev.dependents(),
|
||||||
|
|
|
@ -33,7 +33,9 @@ import java.nio.file.Files;
|
||||||
|
|
||||||
import com.sun.tools.sjavac.options.Options;
|
import com.sun.tools.sjavac.options.Options;
|
||||||
import com.sun.tools.sjavac.options.SourceLocation;
|
import com.sun.tools.sjavac.options.SourceLocation;
|
||||||
|
import com.sun.tools.sjavac.server.JavacService;
|
||||||
import com.sun.tools.sjavac.server.JavacServer;
|
import com.sun.tools.sjavac.server.JavacServer;
|
||||||
|
import com.sun.tools.sjavac.server.JavacServiceClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main class of the smart javac wrapper tool.
|
* The main class of the smart javac wrapper tool.
|
||||||
|
@ -339,7 +341,12 @@ public class Main {
|
||||||
do {
|
do {
|
||||||
// Clean out artifacts in tainted packages.
|
// Clean out artifacts in tainted packages.
|
||||||
javac_state.deleteClassArtifactsInTaintedPackages();
|
javac_state.deleteClassArtifactsInTaintedPackages();
|
||||||
again = javac_state.performJavaCompilations(options, recently_compiled, rc);
|
// Create a JavacService to delegate the actual compilation to.
|
||||||
|
// Currently sjavac always connects to a server through a socket
|
||||||
|
// regardless if sjavac runs as a background service or not.
|
||||||
|
// This will most likely change in the future.
|
||||||
|
JavacService javacService = new JavacServiceClient(options.getServerConf());
|
||||||
|
again = javac_state.performJavaCompilations(javacService, options, recently_compiled, rc);
|
||||||
if (!rc[0]) break;
|
if (!rc[0]) break;
|
||||||
} while (again);
|
} while (again);
|
||||||
// Only update the state if the compile went well.
|
// Only update the state if the compile went well.
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Set;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sun.tools.sjavac.options.Options;
|
import com.sun.tools.sjavac.options.Options;
|
||||||
|
import com.sun.tools.sjavac.server.JavacService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The transform interface is used to transform content inside a package, from one form to another.
|
* The transform interface is used to transform content inside a package, from one form to another.
|
||||||
|
@ -82,7 +83,8 @@ public interface Transformer
|
||||||
* If num_cores is set to a non-zero value. The transform should attempt to use no more than these
|
* If num_cores is set to a non-zero value. The transform should attempt to use no more than these
|
||||||
* number of threads for heavy work.
|
* number of threads for heavy work.
|
||||||
*/
|
*/
|
||||||
boolean transform(Map<String,Set<URI>> pkgSrcs,
|
boolean transform(JavacService javacService,
|
||||||
|
Map<String,Set<URI>> pkgSrcs,
|
||||||
Set<URI> visibleSources,
|
Set<URI> visibleSources,
|
||||||
Map<URI,Set<String>> visibleClasses,
|
Map<URI,Set<String>> visibleClasses,
|
||||||
Map<String,Set<String>> oldPackageDependencies,
|
Map<String,Set<String>> oldPackageDependencies,
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
package com.sun.tools.sjavac;
|
package com.sun.tools.sjavac;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -67,17 +69,32 @@ public class Util {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String extractStringOption(String opName, String s) {
|
public static String extractStringOption(String opName, String s) {
|
||||||
|
return extractStringOption(opName, s, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String extractStringOption(String opName, String s, String deflt) {
|
||||||
int p = s.indexOf(opName+"=");
|
int p = s.indexOf(opName+"=");
|
||||||
if (p == -1) return null;
|
if (p == -1) return deflt;
|
||||||
p+=opName.length()+1;
|
p+=opName.length()+1;
|
||||||
int pe = s.indexOf(',', p);
|
int pe = s.indexOf(',', p);
|
||||||
if (pe == -1) pe = s.length();
|
if (pe == -1) pe = s.length();
|
||||||
return s.substring(p, pe);
|
return s.substring(p, pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean extractBooleanOption(String opName, String s, boolean deflt) {
|
||||||
|
String str = extractStringOption(opName, s);
|
||||||
|
return "true".equals(str) ? true
|
||||||
|
: "false".equals(str) ? false
|
||||||
|
: deflt;
|
||||||
|
}
|
||||||
|
|
||||||
public static int extractIntOption(String opName, String s) {
|
public static int extractIntOption(String opName, String s) {
|
||||||
|
return extractIntOption(opName, s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int extractIntOption(String opName, String s, int deflt) {
|
||||||
int p = s.indexOf(opName+"=");
|
int p = s.indexOf(opName+"=");
|
||||||
if (p == -1) return 0;
|
if (p == -1) return deflt;
|
||||||
p+=opName.length()+1;
|
p+=opName.length()+1;
|
||||||
int pe = s.indexOf(',', p);
|
int pe = s.indexOf(',', p);
|
||||||
if (pe == -1) pe = s.length();
|
if (pe == -1) pe = s.length();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -29,8 +29,6 @@ import java.util.StringTokenizer;
|
||||||
import com.sun.tools.javac.main.JavaCompiler;
|
import com.sun.tools.javac.main.JavaCompiler;
|
||||||
import com.sun.tools.javac.util.Context;
|
import com.sun.tools.javac.util.Context;
|
||||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||||
import com.sun.tools.sjavac.server.CompilerThread;
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/** Subclass to Resolve that overrides collect.
|
/** Subclass to Resolve that overrides collect.
|
||||||
*
|
*
|
||||||
|
@ -44,16 +42,16 @@ public class JavaCompilerWithDeps extends JavaCompiler {
|
||||||
/** The dependency database
|
/** The dependency database
|
||||||
*/
|
*/
|
||||||
protected Dependencies deps;
|
protected Dependencies deps;
|
||||||
protected CompilerThread compilerThread;
|
protected JavacServiceImpl javacService;
|
||||||
|
|
||||||
public JavaCompilerWithDeps(Context context, CompilerThread t) {
|
public JavaCompilerWithDeps(Context context, JavacServiceImpl jsi) {
|
||||||
super(context);
|
super(context);
|
||||||
deps = Dependencies.instance(context);
|
deps = Dependencies.instance(context);
|
||||||
compilerThread = t;
|
javacService = jsi;
|
||||||
needRootClasses = true;
|
needRootClasses = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void preRegister(Context context, final CompilerThread t) {
|
public static void preRegister(Context context, final JavacServiceImpl t) {
|
||||||
context.put(compilerKey, new Context.Factory<JavaCompiler>() {
|
context.put(compilerKey, new Context.Factory<JavaCompiler>() {
|
||||||
public JavaCompiler make(Context c) {
|
public JavaCompiler make(Context c) {
|
||||||
JavaCompiler instance = new JavaCompilerWithDeps(c, t);
|
JavaCompiler instance = new JavaCompilerWithDeps(c, t);
|
||||||
|
@ -99,7 +97,7 @@ public class JavaCompilerWithDeps extends JavaCompiler {
|
||||||
|
|
||||||
// Now check if the truncated uri ends with the path. (It does not == failure!)
|
// Now check if the truncated uri ends with the path. (It does not == failure!)
|
||||||
if (path.length() > 0 && !path.equals("/unnamed package/") && !pp.endsWith(path)) {
|
if (path.length() > 0 && !path.equals("/unnamed package/") && !pp.endsWith(path)) {
|
||||||
compilerThread.logError("Error: The source file "+sym.sourcefile.getName()+
|
javacService.logError("Error: The source file "+sym.sourcefile.getName()+
|
||||||
" is located in the wrong package directory, because it contains the class "+
|
" is located in the wrong package directory, because it contains the class "+
|
||||||
sym.getQualifiedName());
|
sym.getQualifiedName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
package com.sun.tools.sjavac.comp;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.tools.JavaCompiler.CompilationTask;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import javax.tools.StandardJavaFileManager;
|
||||||
|
|
||||||
|
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||||
|
import com.sun.tools.javac.api.JavacTool;
|
||||||
|
import com.sun.tools.javac.util.Context;
|
||||||
|
import com.sun.tools.javac.util.ListBuffer;
|
||||||
|
import com.sun.tools.sjavac.Util;
|
||||||
|
import com.sun.tools.sjavac.server.CompilationResult;
|
||||||
|
import com.sun.tools.sjavac.server.JavacServer;
|
||||||
|
import com.sun.tools.sjavac.server.JavacService;
|
||||||
|
import com.sun.tools.sjavac.server.SysInfo;
|
||||||
|
|
||||||
|
public class JavacServiceImpl implements JavacService {
|
||||||
|
|
||||||
|
JavacServer javacServer;
|
||||||
|
private ThreadLocal<Boolean> forcedExit;
|
||||||
|
|
||||||
|
public JavacServiceImpl(JavacServer javacServer) {
|
||||||
|
this.javacServer = javacServer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logError(String msg) {
|
||||||
|
// stderr.println(msg);
|
||||||
|
forcedExit.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysInfo getSysInfo() {
|
||||||
|
return new SysInfo(Runtime.getRuntime().availableProcessors(),
|
||||||
|
Runtime.getRuntime().maxMemory());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompilationResult compile(String protocolId,
|
||||||
|
String invocationId,
|
||||||
|
String[] args,
|
||||||
|
List<File> explicitSources,
|
||||||
|
Set<URI> sourcesToCompile,
|
||||||
|
Set<URI> visibleSources) {
|
||||||
|
|
||||||
|
JavacTool compiler = JavacTool.create();
|
||||||
|
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
|
||||||
|
SmartFileManager smartFileManager = new SmartFileManager(fileManager);
|
||||||
|
Context context = new Context();
|
||||||
|
ResolveWithDeps.preRegister(context);
|
||||||
|
AttrWithDeps.preRegister(context);
|
||||||
|
JavaCompilerWithDeps.preRegister(context, this);
|
||||||
|
|
||||||
|
// Now setup the actual compilation....
|
||||||
|
CompilationResult compilationResult = new CompilationResult(0);
|
||||||
|
|
||||||
|
// First deal with explicit source files on cmdline and in at file.
|
||||||
|
ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
|
||||||
|
for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(explicitSources)) {
|
||||||
|
compilationUnits.append(i);
|
||||||
|
}
|
||||||
|
// Now deal with sources supplied as source_to_compile.
|
||||||
|
ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
|
||||||
|
for (URI u : sourcesToCompile) {
|
||||||
|
sourcesToCompileFiles.append(new File(u));
|
||||||
|
}
|
||||||
|
for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
|
||||||
|
compilationUnits.append(i);
|
||||||
|
}
|
||||||
|
// Log the options to be used.
|
||||||
|
StringBuilder options = new StringBuilder();
|
||||||
|
for (String s : args) {
|
||||||
|
options.append(">").append(s).append("< ");
|
||||||
|
}
|
||||||
|
javacServer.log(protocolId+" <"+invocationId+"> options "+options.toString());
|
||||||
|
|
||||||
|
forcedExit.set(false);
|
||||||
|
// Create a new logger.
|
||||||
|
StringWriter stdoutLog = new StringWriter();
|
||||||
|
StringWriter stderrLog = new StringWriter();
|
||||||
|
PrintWriter stdout = new PrintWriter(stdoutLog);
|
||||||
|
PrintWriter stderr = new PrintWriter(stderrLog);
|
||||||
|
com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
|
||||||
|
try {
|
||||||
|
if (compilationUnits.size() > 0) {
|
||||||
|
smartFileManager.setVisibleSources(visibleSources);
|
||||||
|
smartFileManager.cleanArtifacts();
|
||||||
|
smartFileManager.setLog(stdout);
|
||||||
|
|
||||||
|
|
||||||
|
// Do the compilation!
|
||||||
|
CompilationTask task = compiler.getTask(stderr, smartFileManager, null, Arrays.asList(args), null, compilationUnits, context);
|
||||||
|
rc = ((JavacTaskImpl) task).doCall();
|
||||||
|
smartFileManager.flush();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
stderr.println(e.getMessage());
|
||||||
|
forcedExit.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
compilationResult.packageArtifacts = smartFileManager.getPackageArtifacts();
|
||||||
|
|
||||||
|
Dependencies deps = Dependencies.instance(context);
|
||||||
|
compilationResult.packageDependencies = deps.getDependencies();
|
||||||
|
compilationResult.packagePubapis = deps.getPubapis();
|
||||||
|
|
||||||
|
compilationResult.stdout = stdoutLog.toString();
|
||||||
|
compilationResult.stderr = stderrLog.toString();
|
||||||
|
compilationResult.returnCode = rc.exitCode == 0 && forcedExit.get() ? -1 : rc.exitCode;
|
||||||
|
|
||||||
|
return compilationResult;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.sun.tools.sjavac.server;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class CompilationResult {
|
||||||
|
|
||||||
|
// Return code constants
|
||||||
|
public final static int ERROR_BUT_TRY_AGAIN = -4712;
|
||||||
|
public final static int ERROR_FATAL = -1;
|
||||||
|
|
||||||
|
public int returnCode;
|
||||||
|
public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
|
||||||
|
public Map<String, Set<String>> packageDependencies = new HashMap<>();
|
||||||
|
public Map<String, String> packagePubapis = new HashMap<>();
|
||||||
|
public SysInfo sysinfo;
|
||||||
|
public String stdout;
|
||||||
|
public String stderr;
|
||||||
|
|
||||||
|
public CompilationResult(int returnCode) {
|
||||||
|
this.returnCode = returnCode;
|
||||||
|
this.sysinfo = new SysInfo(-1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReturnCode(int returnCode) {
|
||||||
|
this.returnCode = returnCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -31,6 +31,8 @@ import java.util.concurrent.Semaphore;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import com.sun.tools.sjavac.comp.JavacServiceImpl;
|
||||||
|
|
||||||
/** The compiler pool maintains compiler threads.
|
/** The compiler pool maintains compiler threads.
|
||||||
*
|
*
|
||||||
* <p><b>This is NOT part of any supported API.
|
* <p><b>This is NOT part of any supported API.
|
||||||
|
@ -147,7 +149,7 @@ public class CompilerPool {
|
||||||
public CompilerThread grabCompilerThread() throws InterruptedException {
|
public CompilerThread grabCompilerThread() throws InterruptedException {
|
||||||
available.acquire();
|
available.acquire();
|
||||||
if (compilers.empty()) {
|
if (compilers.empty()) {
|
||||||
return new CompilerThread(this);
|
return new CompilerThread(this, new JavacServiceImpl(javacServer));
|
||||||
}
|
}
|
||||||
return compilers.pop();
|
return compilers.pop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ import com.sun.tools.javac.util.StringUtils;
|
||||||
import com.sun.tools.sjavac.comp.AttrWithDeps;
|
import com.sun.tools.sjavac.comp.AttrWithDeps;
|
||||||
import com.sun.tools.sjavac.comp.Dependencies;
|
import com.sun.tools.sjavac.comp.Dependencies;
|
||||||
import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
|
import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
|
||||||
|
import com.sun.tools.sjavac.comp.JavacServiceImpl;
|
||||||
import com.sun.tools.sjavac.comp.ResolveWithDeps;
|
import com.sun.tools.sjavac.comp.ResolveWithDeps;
|
||||||
import com.sun.tools.sjavac.comp.SmartFileManager;
|
import com.sun.tools.sjavac.comp.SmartFileManager;
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ import com.sun.tools.sjavac.comp.SmartFileManager;
|
||||||
public class CompilerThread implements Runnable {
|
public class CompilerThread implements Runnable {
|
||||||
private JavacServer javacServer;
|
private JavacServer javacServer;
|
||||||
private CompilerPool compilerPool;
|
private CompilerPool compilerPool;
|
||||||
|
private JavacServiceImpl javacServiceImpl;
|
||||||
private List<Future<?>> subTasks;
|
private List<Future<?>> subTasks;
|
||||||
|
|
||||||
// Communicating over this socket.
|
// Communicating over this socket.
|
||||||
|
@ -85,9 +87,10 @@ public class CompilerThread implements Runnable {
|
||||||
// If true, then this thread is serving a request.
|
// If true, then this thread is serving a request.
|
||||||
private boolean inUse = false;
|
private boolean inUse = false;
|
||||||
|
|
||||||
CompilerThread(CompilerPool cp) {
|
CompilerThread(CompilerPool cp, JavacServiceImpl javacServiceImpl) {
|
||||||
compilerPool = cp;
|
compilerPool = cp;
|
||||||
javacServer = cp.getJavacServer();
|
javacServer = cp.getJavacServer();
|
||||||
|
this.javacServiceImpl = javacServiceImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,7 +134,7 @@ public class CompilerThread implements Runnable {
|
||||||
context = new Context();
|
context = new Context();
|
||||||
ResolveWithDeps.preRegister(context);
|
ResolveWithDeps.preRegister(context);
|
||||||
AttrWithDeps.preRegister(context);
|
AttrWithDeps.preRegister(context);
|
||||||
JavaCompilerWithDeps.preRegister(context, this);
|
JavaCompilerWithDeps.preRegister(context, javacServiceImpl);
|
||||||
subTasks = new ArrayList<>();
|
subTasks = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,30 +24,22 @@
|
||||||
*/
|
*/
|
||||||
package com.sun.tools.sjavac.server;
|
package com.sun.tools.sjavac.server;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.net.URI;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.sun.tools.sjavac.Util;
|
import com.sun.tools.sjavac.Util;
|
||||||
import com.sun.tools.sjavac.ProblemException;
|
import com.sun.tools.sjavac.ProblemException;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
|
* The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
|
||||||
|
@ -73,8 +65,6 @@ public class JavacServer {
|
||||||
// Though usually only one javac server is started by a client.
|
// Though usually only one javac server is started by a client.
|
||||||
private static Map<String, PortFile> allPortFiles;
|
private static Map<String, PortFile> allPortFiles;
|
||||||
private static Map<String, Long> maxServerMemory;
|
private static Map<String, Long> maxServerMemory;
|
||||||
final static int ERROR_FATAL = -1;
|
|
||||||
final static int ERROR_BUT_TRY_AGAIN = -4712;
|
|
||||||
final static String PROTOCOL_COOKIE_VERSION = "----THE-COOKIE-V2----";
|
final static String PROTOCOL_COOKIE_VERSION = "----THE-COOKIE-V2----";
|
||||||
final static String PROTOCOL_CWD = "----THE-CWD----";
|
final static String PROTOCOL_CWD = "----THE-CWD----";
|
||||||
final static String PROTOCOL_ID = "----THE-ID----";
|
final static String PROTOCOL_ID = "----THE-ID----";
|
||||||
|
@ -99,7 +89,7 @@ public class JavacServer {
|
||||||
/**
|
/**
|
||||||
* Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
|
* Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
|
||||||
*/
|
*/
|
||||||
private static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
|
public static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
|
||||||
if (allPortFiles == null) {
|
if (allPortFiles == null) {
|
||||||
allPortFiles = new HashMap<>();
|
allPortFiles = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
@ -179,17 +169,12 @@ public class JavacServer {
|
||||||
// and stderr are redirected already.
|
// and stderr are redirected already.
|
||||||
// The pool size is a limit the number of concurrent compiler threads used.
|
// The pool size is a limit the number of concurrent compiler threads used.
|
||||||
// The server might use less than these to avoid memory problems.
|
// The server might use less than these to avoid memory problems.
|
||||||
int poolsize = Util.extractIntOption("poolsize", settings);
|
int defaultPoolSize = Runtime.getRuntime().availableProcessors();
|
||||||
if (poolsize <= 0) {
|
int poolsize = Util.extractIntOption("poolsize", settings, defaultPoolSize);
|
||||||
// If not set, default to the number of cores.
|
|
||||||
poolsize = Runtime.getRuntime().availableProcessors();
|
|
||||||
}
|
|
||||||
|
|
||||||
// How many seconds of inactivity will the server accept before quitting?
|
// How many seconds of inactivity will the server accept before quitting?
|
||||||
int keepalive = Util.extractIntOption("keepalive", settings);
|
int keepalive = Util.extractIntOption("keepalive", settings, 120);
|
||||||
if (keepalive <= 0) {
|
|
||||||
keepalive = 120;
|
|
||||||
}
|
|
||||||
// The port file is locked and the server port and cookie is written into it.
|
// The port file is locked and the server port and cookie is written into it.
|
||||||
PortFile portFile = getPortFile(portfile);
|
PortFile portFile = getPortFile(portfile);
|
||||||
JavacServer s;
|
JavacServer s;
|
||||||
|
@ -219,134 +204,6 @@ public class JavacServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatch a compilation request to a javac server.
|
|
||||||
*
|
|
||||||
* @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
|
|
||||||
*
|
|
||||||
* The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
|
|
||||||
*
|
|
||||||
* @param sources_to_compile The sources to compile.
|
|
||||||
*
|
|
||||||
* @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!
|
|
||||||
* (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
|
|
||||||
*
|
|
||||||
* @param visibleClasses If visible classes for a specific root/jar has a non zero size, then visible_classes are the only class files that the javac server
|
|
||||||
* can see, in that root/jar. It maps from a classpath root or a jar file to the set of visible classes for that root/jar.
|
|
||||||
*
|
|
||||||
* The server return meta data about the build in the following parameters.
|
|
||||||
* @param package_artifacts, map from package name to set of created artifacts for that package.
|
|
||||||
* @param package_dependencies, map from package name to set of packages that it depends upon.
|
|
||||||
* @param package_pubapis, map from package name to unique string identifying its pub api.
|
|
||||||
*/
|
|
||||||
public static int useServer(String settings, String[] args,
|
|
||||||
Set<URI> sourcesToCompile,
|
|
||||||
Set<URI> visibleSources,
|
|
||||||
Map<URI, Set<String>> visibleClasses,
|
|
||||||
Map<String, Set<URI>> packageArtifacts,
|
|
||||||
Map<String, Set<String>> packageDependencies,
|
|
||||||
Map<String, String> packagePubapis,
|
|
||||||
SysInfo sysinfo,
|
|
||||||
PrintStream out,
|
|
||||||
PrintStream err) {
|
|
||||||
try {
|
|
||||||
// The id can perhaps be used in the future by the javac server to reuse the
|
|
||||||
// JavaCompiler instance for several compiles using the same id.
|
|
||||||
String id = Util.extractStringOption("id", settings);
|
|
||||||
String portfile = Util.extractStringOption("portfile", settings);
|
|
||||||
String logfile = Util.extractStringOption("logfile", settings);
|
|
||||||
String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
|
|
||||||
String background = Util.extractStringOption("background", settings);
|
|
||||||
if (background == null || !background.equals("false")) {
|
|
||||||
background = "true";
|
|
||||||
}
|
|
||||||
// The sjavac option specifies how the server part of sjavac is spawned.
|
|
||||||
// If you have the experimental sjavac in your path, you are done. If not, you have
|
|
||||||
// to point to a com.sun.tools.sjavac.Main that supports --startserver
|
|
||||||
// for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
|
|
||||||
String sjavac = Util.extractStringOption("sjavac", settings);
|
|
||||||
int poolsize = Util.extractIntOption("poolsize", settings);
|
|
||||||
int keepalive = Util.extractIntOption("keepalive", settings);
|
|
||||||
|
|
||||||
if (keepalive <= 0) {
|
|
||||||
// Default keepalive for server is 120 seconds.
|
|
||||||
// I.e. it will accept 120 seconds of inactivity before quitting.
|
|
||||||
keepalive = 120;
|
|
||||||
}
|
|
||||||
if (portfile == null) {
|
|
||||||
err.println("No portfile was specified!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (logfile == null) {
|
|
||||||
logfile = portfile + ".javaclog";
|
|
||||||
}
|
|
||||||
if (stdouterrfile == null) {
|
|
||||||
stdouterrfile = portfile + ".stdouterr";
|
|
||||||
}
|
|
||||||
// Default to sjavac and hope it is in the path.
|
|
||||||
if (sjavac == null) {
|
|
||||||
sjavac = "sjavac";
|
|
||||||
}
|
|
||||||
|
|
||||||
int attempts = 0;
|
|
||||||
int rc = -1;
|
|
||||||
do {
|
|
||||||
PortFile port_file = getPortFile(portfile);
|
|
||||||
synchronized (port_file) {
|
|
||||||
port_file.lock();
|
|
||||||
port_file.getValues();
|
|
||||||
port_file.unlock();
|
|
||||||
}
|
|
||||||
if (!port_file.containsPortInfo()) {
|
|
||||||
String cmd = fork(sjavac, port_file.getFilename(), logfile, poolsize, keepalive, err, stdouterrfile, background);
|
|
||||||
|
|
||||||
if (background.equals("true") && !port_file.waitForValidValues()) {
|
|
||||||
// Ouch the server did not start! Lets print its stdouterrfile and the command used.
|
|
||||||
printFailedAttempt(cmd, stdouterrfile, err);
|
|
||||||
// And give up.
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rc = connectAndCompile(port_file, id, args, sourcesToCompile, visibleSources,
|
|
||||||
packageArtifacts, packageDependencies, packagePubapis, sysinfo,
|
|
||||||
out, err);
|
|
||||||
// Try again until we manage to connect. Any error after that
|
|
||||||
// will cause the compilation to fail.
|
|
||||||
if (rc == ERROR_BUT_TRY_AGAIN) {
|
|
||||||
// We could not connect to the server. Try again.
|
|
||||||
attempts++;
|
|
||||||
try {
|
|
||||||
Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS * 1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (rc == ERROR_BUT_TRY_AGAIN && attempts < MAX_NUM_CONNECT_ATTEMPTS);
|
|
||||||
return rc;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace(err);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void printFailedAttempt(String cmd, String f, PrintStream err) {
|
|
||||||
err.println("---- Failed to start javac server with this command -----");
|
|
||||||
err.println(cmd);
|
|
||||||
try {
|
|
||||||
BufferedReader in = new BufferedReader(new FileReader(f));
|
|
||||||
err.println("---- stdout/stderr output from attempt to start javac server -----");
|
|
||||||
for (;;) {
|
|
||||||
String l = in.readLine();
|
|
||||||
if (l == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
err.println(l);
|
|
||||||
}
|
|
||||||
err.println("------------------------------------------------------------------");
|
|
||||||
} catch (Exception e) {
|
|
||||||
err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spawn the server instance.
|
* Spawn the server instance.
|
||||||
*/
|
*/
|
||||||
|
@ -367,15 +224,15 @@ public class JavacServer {
|
||||||
/**
|
/**
|
||||||
* Fork a background process. Returns the command line used that can be printed if something failed.
|
* Fork a background process. Returns the command line used that can be printed if something failed.
|
||||||
*/
|
*/
|
||||||
private static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
|
public static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
|
||||||
final PrintStream err, String stdouterrfile, String background)
|
final PrintStream err, String stdouterrfile, boolean background)
|
||||||
throws IOException, ProblemException {
|
throws IOException, ProblemException {
|
||||||
if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
|
if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
|
||||||
stdouterrfile = null;
|
stdouterrfile = null;
|
||||||
}
|
}
|
||||||
final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
|
final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
|
||||||
|
|
||||||
if (background.equals("true")) {
|
if (background) {
|
||||||
sjavac += "%20" + startserver;
|
sjavac += "%20" + startserver;
|
||||||
sjavac = sjavac.replaceAll("%20", " ");
|
sjavac = sjavac.replaceAll("%20", " ");
|
||||||
sjavac = sjavac.replaceAll("%2C", ",");
|
sjavac = sjavac.replaceAll("%2C", ",");
|
||||||
|
@ -420,243 +277,6 @@ public class JavacServer {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Expect this key on the next line read from the reader.
|
|
||||||
*/
|
|
||||||
private static boolean expect(BufferedReader in, String key) throws IOException {
|
|
||||||
String s = in.readLine();
|
|
||||||
if (s != null && s.equals(key)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a request to the server only to get the maximum possible heap size to use for compilations.
|
|
||||||
*
|
|
||||||
* @param port_file The port file used to synchronize creation of this server.
|
|
||||||
* @param id The identify of the compilation.
|
|
||||||
* @param out Standard out information.
|
|
||||||
* @param err Standard err information.
|
|
||||||
* @return The maximum heap size in bytes.
|
|
||||||
*/
|
|
||||||
public static SysInfo connectGetSysInfo(String serverSettings, PrintStream out, PrintStream err) {
|
|
||||||
SysInfo sysinfo = new SysInfo(-1, -1);
|
|
||||||
String id = Util.extractStringOption("id", serverSettings);
|
|
||||||
String portfile = Util.extractStringOption("portfile", serverSettings);
|
|
||||||
try {
|
|
||||||
PortFile pf = getPortFile(portfile);
|
|
||||||
useServer(serverSettings, new String[0],
|
|
||||||
new HashSet<URI>(),
|
|
||||||
new HashSet<URI>(),
|
|
||||||
new HashMap<URI, Set<String>>(),
|
|
||||||
new HashMap<String, Set<URI>>(),
|
|
||||||
new HashMap<String, Set<String>>(),
|
|
||||||
new HashMap<String, String>(),
|
|
||||||
sysinfo, out, err);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace(err);
|
|
||||||
}
|
|
||||||
return sysinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
|
|
||||||
* supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
|
|
||||||
*/
|
|
||||||
private static int connectAndCompile(PortFile portFile, String id, String[] args,
|
|
||||||
Set<URI> sourcesToCompile,
|
|
||||||
Set<URI> visibleSources,
|
|
||||||
Map<String, Set<URI>> packageArtifacts,
|
|
||||||
Map<String, Set<String>> packageDependencies,
|
|
||||||
Map<String, String> packagePublicApis,
|
|
||||||
SysInfo sysinfo,
|
|
||||||
PrintStream out,
|
|
||||||
PrintStream err) {
|
|
||||||
int rc = -3;
|
|
||||||
try {
|
|
||||||
int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
|
|
||||||
if (port == 0) {
|
|
||||||
return ERROR_BUT_TRY_AGAIN;
|
|
||||||
}
|
|
||||||
long cookie = portFile.getCookie();
|
|
||||||
|
|
||||||
// Acquire the localhost/127.0.0.1 address.
|
|
||||||
InetAddress addr = InetAddress.getByName(null);
|
|
||||||
SocketAddress sockaddr = new InetSocketAddress(addr, port);
|
|
||||||
Socket sock = new Socket();
|
|
||||||
int timeoutMs = CONNECTION_TIMEOUT * 1000;
|
|
||||||
try {
|
|
||||||
sock.connect(sockaddr, timeoutMs);
|
|
||||||
} catch (java.net.ConnectException e) {
|
|
||||||
err.println("Could not connect to javac server found in portfile: " + portFile.getFilename() + " " + e);
|
|
||||||
return ERROR_BUT_TRY_AGAIN;
|
|
||||||
}
|
|
||||||
if (!sock.isConnected()) {
|
|
||||||
err.println("Could not connect to javac server found in portfile: " + portFile.getFilename());
|
|
||||||
return ERROR_BUT_TRY_AGAIN;
|
|
||||||
}
|
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
|
|
||||||
PrintWriter sockout = new PrintWriter(sock.getOutputStream());
|
|
||||||
|
|
||||||
sockout.println(PROTOCOL_COOKIE_VERSION);
|
|
||||||
sockout.println("" + cookie);
|
|
||||||
sockout.println(PROTOCOL_CWD);
|
|
||||||
sockout.println(System.getProperty("user.dir"));
|
|
||||||
sockout.println(PROTOCOL_ID);
|
|
||||||
sockout.println(id);
|
|
||||||
sockout.println(PROTOCOL_ARGS);
|
|
||||||
for (String s : args) {
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
String[] paths = s.split(File.pathSeparator);
|
|
||||||
int c = 0;
|
|
||||||
for (String path : paths) {
|
|
||||||
File f = new File(path);
|
|
||||||
if (f.isFile() || f.isDirectory()) {
|
|
||||||
buf.append(f.getAbsolutePath());
|
|
||||||
c++;
|
|
||||||
if (c < paths.length) {
|
|
||||||
buf.append(File.pathSeparator);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
buf = new StringBuffer(s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sockout.println(buf.toString());
|
|
||||||
}
|
|
||||||
sockout.println(PROTOCOL_SOURCES_TO_COMPILE);
|
|
||||||
for (URI uri : sourcesToCompile) {
|
|
||||||
sockout.println(uri.toString());
|
|
||||||
}
|
|
||||||
sockout.println(PROTOCOL_VISIBLE_SOURCES);
|
|
||||||
for (URI uri : visibleSources) {
|
|
||||||
sockout.println(uri.toString());
|
|
||||||
}
|
|
||||||
sockout.println(PROTOCOL_END);
|
|
||||||
sockout.flush();
|
|
||||||
|
|
||||||
StringBuffer stdout = new StringBuffer();
|
|
||||||
StringBuffer stderr = new StringBuffer();
|
|
||||||
|
|
||||||
if (!expect(in, PROTOCOL_STDOUT)) {
|
|
||||||
return ERROR_FATAL;
|
|
||||||
}
|
|
||||||
// Load stdout
|
|
||||||
for (;;) {
|
|
||||||
String l = in.readLine();
|
|
||||||
if (l == null) {
|
|
||||||
return ERROR_FATAL;
|
|
||||||
}
|
|
||||||
if (l.equals(PROTOCOL_STDERR)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
stdout.append(l);
|
|
||||||
stdout.append('\n');
|
|
||||||
}
|
|
||||||
// Load stderr
|
|
||||||
for (;;) {
|
|
||||||
String l = in.readLine();
|
|
||||||
if (l == null) {
|
|
||||||
return ERROR_FATAL;
|
|
||||||
}
|
|
||||||
if (l.equals(PROTOCOL_PACKAGE_ARTIFACTS)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
stderr.append(l);
|
|
||||||
stderr.append('\n');
|
|
||||||
}
|
|
||||||
// Load the package artifacts
|
|
||||||
Set<URI> lastUriSet = null;
|
|
||||||
for (;;) {
|
|
||||||
String l = in.readLine();
|
|
||||||
if (l == null) {
|
|
||||||
return ERROR_FATAL;
|
|
||||||
}
|
|
||||||
if (l.equals(PROTOCOL_PACKAGE_DEPENDENCIES)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (l.length() > 1 && l.charAt(0) == '+') {
|
|
||||||
String pkg = l.substring(1);
|
|
||||||
lastUriSet = new HashSet<>();
|
|
||||||
packageArtifacts.put(pkg, lastUriSet);
|
|
||||||
} else if (l.length() > 1 && lastUriSet != null) {
|
|
||||||
lastUriSet.add(new URI(l.substring(1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Load package dependencies
|
|
||||||
Set<String> lastPackageSet = null;
|
|
||||||
for (;;) {
|
|
||||||
String l = in.readLine();
|
|
||||||
if (l == null) {
|
|
||||||
return ERROR_FATAL;
|
|
||||||
}
|
|
||||||
if (l.equals(PROTOCOL_PACKAGE_PUBLIC_APIS)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (l.length() > 1 && l.charAt(0) == '+') {
|
|
||||||
String pkg = l.substring(1);
|
|
||||||
lastPackageSet = new HashSet<>();
|
|
||||||
packageDependencies.put(pkg, lastPackageSet);
|
|
||||||
} else if (l.length() > 1 && lastPackageSet != null) {
|
|
||||||
lastPackageSet.add(l.substring(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Load package pubapis
|
|
||||||
Map<String, StringBuffer> tmp = new HashMap<>();
|
|
||||||
StringBuffer lastPublicApi = null;
|
|
||||||
for (;;) {
|
|
||||||
String l = in.readLine();
|
|
||||||
if (l == null) {
|
|
||||||
return ERROR_FATAL;
|
|
||||||
}
|
|
||||||
if (l.equals(PROTOCOL_SYSINFO)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (l.length() > 1 && l.charAt(0) == '+') {
|
|
||||||
String pkg = l.substring(1);
|
|
||||||
lastPublicApi = new StringBuffer();
|
|
||||||
tmp.put(pkg, lastPublicApi);
|
|
||||||
} else if (l.length() > 1 && lastPublicApi != null) {
|
|
||||||
lastPublicApi.append(l.substring(1));
|
|
||||||
lastPublicApi.append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (String p : tmp.keySet()) {
|
|
||||||
assert (packagePublicApis.get(p) == null);
|
|
||||||
String api = tmp.get(p).toString();
|
|
||||||
packagePublicApis.put(p, api);
|
|
||||||
}
|
|
||||||
// Now reading the max memory possible.
|
|
||||||
for (;;) {
|
|
||||||
String l = in.readLine();
|
|
||||||
if (l == null) {
|
|
||||||
return ERROR_FATAL;
|
|
||||||
}
|
|
||||||
if (l.equals(PROTOCOL_RETURN_CODE)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (l.startsWith("num_cores=") && sysinfo != null) {
|
|
||||||
sysinfo.numCores = Integer.parseInt(l.substring(10));
|
|
||||||
}
|
|
||||||
if (l.startsWith("max_memory=") && sysinfo != null) {
|
|
||||||
sysinfo.maxMemory = Long.parseLong(l.substring(11));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String l = in.readLine();
|
|
||||||
if (l == null) {
|
|
||||||
err.println("No return value from the server!");
|
|
||||||
return ERROR_FATAL;
|
|
||||||
}
|
|
||||||
rc = Integer.parseInt(l);
|
|
||||||
out.print(stdout);
|
|
||||||
err.print(stderr);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace(err);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the server thread until it exits. Either because of inactivity or because the port file has been deleted by someone else, or overtaken by some other
|
* Run the server thread until it exits. Either because of inactivity or because the port file has been deleted by someone else, or overtaken by some other
|
||||||
* javac server.
|
* javac server.
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.sun.tools.sjavac.server;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface JavacService {
|
||||||
|
|
||||||
|
SysInfo getSysInfo();
|
||||||
|
|
||||||
|
CompilationResult compile(String protocolId,
|
||||||
|
String invocationId,
|
||||||
|
String[] args,
|
||||||
|
List<File> explicitSources,
|
||||||
|
Set<URI> sourcesToCompile,
|
||||||
|
Set<URI> visibleSources);
|
||||||
|
}
|
|
@ -0,0 +1,408 @@
|
||||||
|
package com.sun.tools.sjavac.server;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.sun.tools.sjavac.Util;
|
||||||
|
|
||||||
|
import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
|
||||||
|
import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
|
||||||
|
|
||||||
|
public class JavacServiceClient implements JavacService {
|
||||||
|
|
||||||
|
|
||||||
|
// The id can perhaps be used in the future by the javac server to reuse the
|
||||||
|
// JavaCompiler instance for several compiles using the same id.
|
||||||
|
private final String id;
|
||||||
|
private final String portfile;
|
||||||
|
private final String logfile;
|
||||||
|
private final String stdouterrfile;
|
||||||
|
private final boolean background;
|
||||||
|
|
||||||
|
// Default keepalive for server is 120 seconds.
|
||||||
|
// I.e. it will accept 120 seconds of inactivity before quitting.
|
||||||
|
private final int keepalive;
|
||||||
|
private final int poolsize;
|
||||||
|
|
||||||
|
// The sjavac option specifies how the server part of sjavac is spawned.
|
||||||
|
// If you have the experimental sjavac in your path, you are done. If not, you have
|
||||||
|
// to point to a com.sun.tools.sjavac.Main that supports --startserver
|
||||||
|
// for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
|
||||||
|
private final String sjavac;
|
||||||
|
|
||||||
|
public JavacServiceClient(String settings) {
|
||||||
|
id = Util.extractStringOption("id", settings);
|
||||||
|
portfile = Util.extractStringOption("portfile", settings);
|
||||||
|
logfile = Util.extractStringOption("logfile", settings, portfile + ".javaclog");
|
||||||
|
stdouterrfile = Util.extractStringOption("stdouterrfile", settings, portfile + ".stdouterr");
|
||||||
|
background = Util.extractBooleanOption("background", settings, true);
|
||||||
|
sjavac = Util.extractStringOption("sjavac", settings, "sjavac");
|
||||||
|
int poolsize = Util.extractIntOption("poolsize", settings);
|
||||||
|
keepalive = Util.extractIntOption("keepalive", settings, 120);
|
||||||
|
|
||||||
|
this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a request to the server only to get the maximum possible heap size to use for compilations.
|
||||||
|
*
|
||||||
|
* @param port_file The port file used to synchronize creation of this server.
|
||||||
|
* @param id The identify of the compilation.
|
||||||
|
* @param out Standard out information.
|
||||||
|
* @param err Standard err information.
|
||||||
|
* @return The maximum heap size in bytes.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SysInfo getSysInfo() {
|
||||||
|
try {
|
||||||
|
CompilationResult cr = useServer(new String[0],
|
||||||
|
Collections.<URI>emptySet(),
|
||||||
|
Collections.<URI>emptySet(),
|
||||||
|
Collections.<URI, Set<String>>emptyMap());
|
||||||
|
return cr.sysinfo;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return new SysInfo(-1, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompilationResult compile(String protocolId,
|
||||||
|
String invocationId,
|
||||||
|
String[] args,
|
||||||
|
List<File> explicitSources,
|
||||||
|
Set<URI> sourcesToCompile,
|
||||||
|
Set<URI> visibleSources) {
|
||||||
|
// Delegate to useServer, which delegates to compileHelper
|
||||||
|
return useServer(args, sourcesToCompile, visibleSources, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
|
||||||
|
* supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
|
||||||
|
*/
|
||||||
|
public CompilationResult compileHelper(String id,
|
||||||
|
String[] args,
|
||||||
|
Set<URI> sourcesToCompile,
|
||||||
|
Set<URI> visibleSources) {
|
||||||
|
|
||||||
|
CompilationResult rc = new CompilationResult(-3);
|
||||||
|
|
||||||
|
try {
|
||||||
|
PortFile portFile = JavacServer.getPortFile(this.portfile);
|
||||||
|
|
||||||
|
int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
|
||||||
|
if (port == 0) {
|
||||||
|
return new CompilationResult(ERROR_BUT_TRY_AGAIN);
|
||||||
|
}
|
||||||
|
long cookie = portFile.getCookie();
|
||||||
|
// Acquire the localhost/127.0.0.1 address.
|
||||||
|
InetAddress addr = InetAddress.getByName(null);
|
||||||
|
SocketAddress sockaddr = new InetSocketAddress(addr, port);
|
||||||
|
Socket sock = new Socket();
|
||||||
|
int timeoutMs = JavacServer.CONNECTION_TIMEOUT * 1000;
|
||||||
|
try {
|
||||||
|
sock.connect(sockaddr, timeoutMs);
|
||||||
|
} catch (java.net.ConnectException e) {
|
||||||
|
rc.setReturnCode(ERROR_BUT_TRY_AGAIN);
|
||||||
|
rc.stderr = "Could not connect to javac server found in portfile: " + portFile.getFilename() + " " + e;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
if (!sock.isConnected()) {
|
||||||
|
rc.setReturnCode(ERROR_BUT_TRY_AGAIN);
|
||||||
|
rc.stderr = "Could not connect to javac server found in portfile: " + portFile.getFilename();
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send arguments
|
||||||
|
//
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
|
||||||
|
PrintWriter sockout = new PrintWriter(sock.getOutputStream());
|
||||||
|
|
||||||
|
sockout.println(JavacServer.PROTOCOL_COOKIE_VERSION);
|
||||||
|
sockout.println("" + cookie);
|
||||||
|
sockout.println(JavacServer.PROTOCOL_CWD);
|
||||||
|
sockout.println(System.getProperty("user.dir"));
|
||||||
|
sockout.println(JavacServer.PROTOCOL_ID);
|
||||||
|
sockout.println(id);
|
||||||
|
sockout.println(JavacServer.PROTOCOL_ARGS);
|
||||||
|
for (String s : args) {
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
String[] paths = s.split(File.pathSeparator);
|
||||||
|
int c = 0;
|
||||||
|
for (String path : paths) {
|
||||||
|
File f = new File(path);
|
||||||
|
if (f.isFile() || f.isDirectory()) {
|
||||||
|
buf.append(f.getAbsolutePath());
|
||||||
|
c++;
|
||||||
|
if (c < paths.length) {
|
||||||
|
buf.append(File.pathSeparator);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf = new StringBuffer(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sockout.println(buf.toString());
|
||||||
|
}
|
||||||
|
sockout.println(JavacServer.PROTOCOL_SOURCES_TO_COMPILE);
|
||||||
|
for (URI uri : sourcesToCompile) {
|
||||||
|
sockout.println(uri.toString());
|
||||||
|
}
|
||||||
|
sockout.println(JavacServer.PROTOCOL_VISIBLE_SOURCES);
|
||||||
|
for (URI uri : visibleSources) {
|
||||||
|
sockout.println(uri.toString());
|
||||||
|
}
|
||||||
|
sockout.println(JavacServer.PROTOCOL_END);
|
||||||
|
sockout.flush();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Receive result
|
||||||
|
//
|
||||||
|
StringBuffer stdout = new StringBuffer();
|
||||||
|
StringBuffer stderr = new StringBuffer();
|
||||||
|
|
||||||
|
if (!JavacServiceClient.expect(in, JavacServer.PROTOCOL_STDOUT)) {
|
||||||
|
return new CompilationResult(ERROR_FATAL);
|
||||||
|
}
|
||||||
|
// Load stdout
|
||||||
|
for (;;) {
|
||||||
|
String l = in.readLine();
|
||||||
|
if (l == null) {
|
||||||
|
return new CompilationResult(ERROR_FATAL);
|
||||||
|
}
|
||||||
|
if (l.equals(JavacServer.PROTOCOL_STDERR)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stdout.append(l);
|
||||||
|
stdout.append('\n');
|
||||||
|
}
|
||||||
|
// Load stderr
|
||||||
|
for (;;) {
|
||||||
|
String l = in.readLine();
|
||||||
|
if (l == null) {
|
||||||
|
return new CompilationResult(ERROR_FATAL);
|
||||||
|
}
|
||||||
|
if (l.equals(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stderr.append(l);
|
||||||
|
stderr.append('\n');
|
||||||
|
}
|
||||||
|
// Load the package artifacts
|
||||||
|
Set<URI> lastUriSet = null;
|
||||||
|
for (;;) {
|
||||||
|
String l = in.readLine();
|
||||||
|
if (l == null) {
|
||||||
|
return new CompilationResult(ERROR_FATAL);
|
||||||
|
}
|
||||||
|
if (l.equals(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (l.length() > 1 && l.charAt(0) == '+') {
|
||||||
|
String pkg = l.substring(1);
|
||||||
|
lastUriSet = new HashSet<>();
|
||||||
|
rc.packageArtifacts.put(pkg, lastUriSet);
|
||||||
|
} else if (l.length() > 1 && lastUriSet != null) {
|
||||||
|
lastUriSet.add(new URI(l.substring(1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Load package dependencies
|
||||||
|
Set<String> lastPackageSet = null;
|
||||||
|
for (;;) {
|
||||||
|
String l = in.readLine();
|
||||||
|
if (l == null) {
|
||||||
|
return new CompilationResult(ERROR_FATAL);
|
||||||
|
}
|
||||||
|
if (l.equals(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (l.length() > 1 && l.charAt(0) == '+') {
|
||||||
|
String pkg = l.substring(1);
|
||||||
|
lastPackageSet = new HashSet<>();
|
||||||
|
rc.packageDependencies.put(pkg, lastPackageSet);
|
||||||
|
} else if (l.length() > 1 && lastPackageSet != null) {
|
||||||
|
lastPackageSet.add(l.substring(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Load package pubapis
|
||||||
|
Map<String, StringBuffer> tmp = new HashMap<>();
|
||||||
|
StringBuffer lastPublicApi = null;
|
||||||
|
for (;;) {
|
||||||
|
String l = in.readLine();
|
||||||
|
if (l == null) {
|
||||||
|
return new CompilationResult(ERROR_FATAL);
|
||||||
|
}
|
||||||
|
if (l.equals(JavacServer.PROTOCOL_SYSINFO)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (l.length() > 1 && l.charAt(0) == '+') {
|
||||||
|
String pkg = l.substring(1);
|
||||||
|
lastPublicApi = new StringBuffer();
|
||||||
|
tmp.put(pkg, lastPublicApi);
|
||||||
|
} else if (l.length() > 1 && lastPublicApi != null) {
|
||||||
|
lastPublicApi.append(l.substring(1));
|
||||||
|
lastPublicApi.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String p : tmp.keySet()) {
|
||||||
|
//assert (packagePublicApis.get(p) == null);
|
||||||
|
String api = tmp.get(p).toString();
|
||||||
|
rc.packagePubapis.put(p, api);
|
||||||
|
}
|
||||||
|
// Now reading the max memory possible.
|
||||||
|
for (;;) {
|
||||||
|
String l = in.readLine();
|
||||||
|
if (l == null) {
|
||||||
|
return new CompilationResult(ERROR_FATAL);
|
||||||
|
}
|
||||||
|
if (l.equals(JavacServer.PROTOCOL_RETURN_CODE)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (l.startsWith("num_cores=")) {
|
||||||
|
rc.sysinfo.numCores = Integer.parseInt(l.substring(10));
|
||||||
|
}
|
||||||
|
if (l.startsWith("max_memory=")) {
|
||||||
|
rc.sysinfo.maxMemory = Long.parseLong(l.substring(11));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String l = in.readLine();
|
||||||
|
if (l == null) {
|
||||||
|
rc.setReturnCode(ERROR_FATAL);
|
||||||
|
rc.stderr = "No return value from the server!";
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
rc.setReturnCode(Integer.parseInt(l));
|
||||||
|
rc.stdout = stdout.toString();
|
||||||
|
rc.stderr = stderr.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(sw));
|
||||||
|
rc.stderr = sw.toString();
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a compilation request to a javac server.
|
||||||
|
*
|
||||||
|
* @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
|
||||||
|
*
|
||||||
|
* The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
|
||||||
|
*
|
||||||
|
* @param sources_to_compile The sources to compile.
|
||||||
|
*
|
||||||
|
* @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!
|
||||||
|
* (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
|
||||||
|
*
|
||||||
|
* @param visibleClasses If visible classes for a specific root/jar has a non zero size, then visible_classes are the only class files that the javac server
|
||||||
|
* can see, in that root/jar. It maps from a classpath root or a jar file to the set of visible classes for that root/jar.
|
||||||
|
*
|
||||||
|
* The server return meta data about the build in the following parameters.
|
||||||
|
* @param package_artifacts, map from package name to set of created artifacts for that package.
|
||||||
|
* @param package_dependencies, map from package name to set of packages that it depends upon.
|
||||||
|
* @param package_pubapis, map from package name to unique string identifying its pub api.
|
||||||
|
*/
|
||||||
|
public CompilationResult useServer(String[] args,
|
||||||
|
Set<URI> sourcesToCompile,
|
||||||
|
Set<URI> visibleSources,
|
||||||
|
Map<URI, Set<String>> visibleClasses) {
|
||||||
|
try {
|
||||||
|
if (portfile == null) {
|
||||||
|
CompilationResult cr = new CompilationResult(CompilationResult.ERROR_FATAL);
|
||||||
|
cr.stderr = "No portfile was specified!";
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int attempts = 0;
|
||||||
|
CompilationResult rc;
|
||||||
|
do {
|
||||||
|
PortFile port_file = JavacServer.getPortFile(portfile);
|
||||||
|
synchronized (port_file) {
|
||||||
|
port_file.lock();
|
||||||
|
port_file.getValues();
|
||||||
|
port_file.unlock();
|
||||||
|
}
|
||||||
|
if (!port_file.containsPortInfo()) {
|
||||||
|
String cmd = JavacServer.fork(sjavac, port_file.getFilename(), logfile, poolsize, keepalive, System.err, stdouterrfile, background);
|
||||||
|
|
||||||
|
if (background && !port_file.waitForValidValues()) {
|
||||||
|
// Ouch the server did not start! Lets print its stdouterrfile and the command used.
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
JavacServiceClient.printFailedAttempt(cmd, stdouterrfile, new PrintWriter(sw));
|
||||||
|
// And give up.
|
||||||
|
CompilationResult cr = new CompilationResult(ERROR_FATAL);
|
||||||
|
cr.stderr = sw.toString();
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc = compileHelper(id, args, sourcesToCompile, visibleSources);
|
||||||
|
// Try again until we manage to connect. Any error after that
|
||||||
|
// will cause the compilation to fail.
|
||||||
|
if (rc.returnCode == CompilationResult.ERROR_BUT_TRY_AGAIN) {
|
||||||
|
// We could not connect to the server. Try again.
|
||||||
|
attempts++;
|
||||||
|
try {
|
||||||
|
Thread.sleep(JavacServer.WAIT_BETWEEN_CONNECT_ATTEMPTS * 1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (rc.returnCode == ERROR_BUT_TRY_AGAIN && attempts < JavacServer.MAX_NUM_CONNECT_ATTEMPTS);
|
||||||
|
return rc;
|
||||||
|
} catch (Exception e) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(sw));
|
||||||
|
CompilationResult cr = new CompilationResult(ERROR_FATAL);
|
||||||
|
cr.stderr = sw.toString();
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printFailedAttempt(String cmd, String f, PrintWriter err) {
|
||||||
|
err.println("---- Failed to start javac server with this command -----");
|
||||||
|
err.println(cmd);
|
||||||
|
try {
|
||||||
|
BufferedReader in = new BufferedReader(new FileReader(f));
|
||||||
|
err.println("---- stdout/stderr output from attempt to start javac server -----");
|
||||||
|
for (;;) {
|
||||||
|
String l = in.readLine();
|
||||||
|
if (l == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err.println(l);
|
||||||
|
}
|
||||||
|
err.println("------------------------------------------------------------------");
|
||||||
|
} catch (Exception e) {
|
||||||
|
err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect this key on the next line read from the reader.
|
||||||
|
*/
|
||||||
|
public static boolean expect(BufferedReader in, String key) throws IOException {
|
||||||
|
String s = in.readLine();
|
||||||
|
if (s != null && s.equals(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,6 @@
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.*;
|
import java.nio.file.attribute.*;
|
||||||
import java.nio.charset.*;
|
import java.nio.charset.*;
|
||||||
|
@ -43,6 +42,9 @@ class SJavac {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem defaultfs = FileSystems.getDefault();
|
FileSystem defaultfs = FileSystems.getDefault();
|
||||||
|
String serverArg = "--server:"
|
||||||
|
+ "portfile=testportfile,"
|
||||||
|
+ "background=false";
|
||||||
|
|
||||||
// Where to put generated sources that will
|
// Where to put generated sources that will
|
||||||
// test aspects of sjavac, ie JTWork/scratch/gensrc
|
// test aspects of sjavac, ie JTWork/scratch/gensrc
|
||||||
|
@ -136,7 +138,7 @@ class SJavac {
|
||||||
"private int b() { return A.DEFINITION; } native void foo(); }");
|
"private int b() { return A.DEFINITION; } native void foo(); }");
|
||||||
|
|
||||||
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
previous_bin_state = collectState(bin);
|
previous_bin_state = collectState(bin);
|
||||||
previous_headers_state = collectState(headers);
|
previous_headers_state = collectState(headers);
|
||||||
}
|
}
|
||||||
|
@ -145,7 +147,7 @@ class SJavac {
|
||||||
System.out.println("\nTesting that no change in sources implies no change in binaries.");
|
System.out.println("\nTesting that no change in sources implies no change in binaries.");
|
||||||
System.out.println("------------------------------------------------------------------");
|
System.out.println("------------------------------------------------------------------");
|
||||||
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
verifyEqual(new_bin_state, previous_bin_state);
|
verifyEqual(new_bin_state, previous_bin_state);
|
||||||
Map<String,Long> new_headers_state = collectState(headers);
|
Map<String,Long> new_headers_state = collectState(headers);
|
||||||
|
@ -158,7 +160,7 @@ class SJavac {
|
||||||
System.out.println("-----------------------------------------");
|
System.out.println("-----------------------------------------");
|
||||||
removeFrom(gensrc, "alfa/omega/AA.java");
|
removeFrom(gensrc, "alfa/omega/AA.java");
|
||||||
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state,
|
verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state,
|
||||||
"bin/alfa/omega/AA$1.class",
|
"bin/alfa/omega/AA$1.class",
|
||||||
|
@ -185,7 +187,7 @@ class SJavac {
|
||||||
"public final static int DEFINITION = 18; public void aint() { } private void foo() { } }");
|
"public final static int DEFINITION = 18; public void aint() { } private void foo() { } }");
|
||||||
|
|
||||||
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
|
|
||||||
verifyNewerFiles(previous_bin_state, new_bin_state,
|
verifyNewerFiles(previous_bin_state, new_bin_state,
|
||||||
|
@ -211,7 +213,7 @@ class SJavac {
|
||||||
"private int b() { return A.DEFINITION; } }");
|
"private int b() { return A.DEFINITION; } }");
|
||||||
|
|
||||||
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
verifyNewerFiles(previous_bin_state, new_bin_state,
|
verifyNewerFiles(previous_bin_state, new_bin_state,
|
||||||
"bin/beta/B.class",
|
"bin/beta/B.class",
|
||||||
|
@ -236,7 +238,7 @@ class SJavac {
|
||||||
"@java.lang.annotation.Native final static int alfa = 42; }");
|
"@java.lang.annotation.Native final static int alfa = 42; }");
|
||||||
|
|
||||||
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
verifyNewerFiles(previous_bin_state, new_bin_state,
|
verifyNewerFiles(previous_bin_state, new_bin_state,
|
||||||
"bin/beta/B.class",
|
"bin/beta/B.class",
|
||||||
|
@ -262,7 +264,7 @@ class SJavac {
|
||||||
"@java.lang.annotation.Native final static int alfa = 43; }");
|
"@java.lang.annotation.Native final static int alfa = 43; }");
|
||||||
|
|
||||||
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
verifyNewerFiles(previous_bin_state, new_bin_state,
|
verifyNewerFiles(previous_bin_state, new_bin_state,
|
||||||
"bin/beta/B.class",
|
"bin/beta/B.class",
|
||||||
|
@ -299,7 +301,7 @@ class SJavac {
|
||||||
"package beta; public class B { }");
|
"package beta; public class B { }");
|
||||||
|
|
||||||
compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
|
compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false");
|
serverArg);
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
|
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
|
||||||
"bin/alfa/omega/A.class",
|
"bin/alfa/omega/A.class",
|
||||||
|
@ -310,7 +312,7 @@ class SJavac {
|
||||||
System.out.println("----- Compile with exluded beta went well!");
|
System.out.println("----- Compile with exluded beta went well!");
|
||||||
delete(bin);
|
delete(bin);
|
||||||
compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
|
compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false");
|
serverArg);
|
||||||
|
|
||||||
System.out.println("----- Compile without exluded beta failed, as expected! Good!");
|
System.out.println("----- Compile without exluded beta failed, as expected! Good!");
|
||||||
delete(bin);
|
delete(bin);
|
||||||
|
@ -341,7 +343,7 @@ class SJavac {
|
||||||
|
|
||||||
compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2",
|
compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2",
|
||||||
"-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1",
|
"-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false");
|
serverArg);
|
||||||
|
|
||||||
System.out.println("The first compile went well!");
|
System.out.println("The first compile went well!");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
|
@ -353,7 +355,7 @@ class SJavac {
|
||||||
delete(bin);
|
delete(bin);
|
||||||
compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3",
|
compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3",
|
||||||
"-d", "bin", "-h", "headers", "-j", "1",
|
"-d", "bin", "-h", "headers", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false");
|
serverArg);
|
||||||
|
|
||||||
System.out.println("----- Compile without exluded beta failed, as expected! Good!");
|
System.out.println("----- Compile without exluded beta failed, as expected! Good!");
|
||||||
delete(bin);
|
delete(bin);
|
||||||
|
@ -378,7 +380,7 @@ class SJavac {
|
||||||
"package gamma; public class C { alfa.omega.A a; }");
|
"package gamma; public class C { alfa.omega.A a; }");
|
||||||
|
|
||||||
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3",
|
compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3",
|
||||||
"--server:portfile=testserver,background=false","--log=debug");
|
serverArg,"--log=debug");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
|
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
|
||||||
"bin/alfa/omega/A.class",
|
"bin/alfa/omega/A.class",
|
||||||
|
@ -407,7 +409,7 @@ class SJavac {
|
||||||
"package beta; public class B { }");
|
"package beta; public class B { }");
|
||||||
|
|
||||||
compile("-x", "beta", "-src", "gensrc", "-x", "alfa/omega", "-sourcepath", "gensrc",
|
compile("-x", "beta", "-src", "gensrc", "-x", "alfa/omega", "-sourcepath", "gensrc",
|
||||||
"-d", "bin", "--server:portfile=testserver,background=false");
|
"-d", "bin", serverArg);
|
||||||
|
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
|
verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
|
||||||
|
@ -431,7 +433,7 @@ class SJavac {
|
||||||
"}");
|
"}");
|
||||||
|
|
||||||
compile("gensrc", "-d", "bin", "-j", "1",
|
compile("gensrc", "-d", "bin", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
Map<String,Long> previous_bin_state = collectState(bin);
|
Map<String,Long> previous_bin_state = collectState(bin);
|
||||||
|
|
||||||
// Change pubapi of A, this should trigger a recompile of B.
|
// Change pubapi of A, this should trigger a recompile of B.
|
||||||
|
@ -443,7 +445,7 @@ class SJavac {
|
||||||
"}");
|
"}");
|
||||||
|
|
||||||
compile("gensrc", "-d", "bin", "-j", "1",
|
compile("gensrc", "-d", "bin", "-j", "1",
|
||||||
"--server:portfile=testserver,background=false", "--log=debug");
|
serverArg, "--log=debug");
|
||||||
Map<String,Long> new_bin_state = collectState(bin);
|
Map<String,Long> new_bin_state = collectState(bin);
|
||||||
|
|
||||||
verifyNewerFiles(previous_bin_state, new_bin_state,
|
verifyNewerFiles(previous_bin_state, new_bin_state,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue