Commit 77b30424 authored by Ralph Morelli's avatar Ralph Morelli

Modifies Compiler.java to avoid corrupting APKs with missing jars during heavy server load.

The static ConcurrentMap, componentLibraries, was being corrupted by concurrent threads
during periods of high server load.  A similar change was made to concurrentPermissions.

Change-Id: Ibf58c06e5e1dab1b1eaf97466804ad93e95f9158
parent 78ab52c3
...@@ -112,10 +112,10 @@ public final class Compiler { ...@@ -112,10 +112,10 @@ public final class Compiler {
// Logging support // Logging support
private static final Logger LOG = Logger.getLogger(Compiler.class.getName()); private static final Logger LOG = Logger.getLogger(Compiler.class.getName());
private static final ConcurrentMap<String, Set<String>> componentPermissions = private final ConcurrentMap<String, Set<String>> componentPermissions =
new ConcurrentHashMap<String, Set<String>>(); new ConcurrentHashMap<String, Set<String>>();
private static final ConcurrentMap<String, Set<String>> componentLibraries = private final ConcurrentMap<String, Set<String>> componentLibraries =
new ConcurrentHashMap<String, Set<String>>(); new ConcurrentHashMap<String, Set<String>>();
/** /**
...@@ -147,7 +147,7 @@ public final class Compiler { ...@@ -147,7 +147,7 @@ public final class Compiler {
private final boolean isForWireless; private final boolean isForWireless;
// Maximum ram that can be used by a child processes, in MB. // Maximum ram that can be used by a child processes, in MB.
private final int childProcessRamMb; private final int childProcessRamMb;
private static Set<String> librariesNeeded; // Set of component libraries private Set<String> librariesNeeded; // Set of component libraries
/* /*
...@@ -178,10 +178,10 @@ public final class Compiler { ...@@ -178,10 +178,10 @@ public final class Compiler {
} }
/* /*
* Generate the set of Android permissions needed by this project. * Generate the set of Android libraries needed by this project.
*/ */
@VisibleForTesting @VisibleForTesting
Set<String> generateLibraryNames() { void generateLibraryNames() {
// Before we can use componentLibraries, we have to call loadComponentLibraries(). // Before we can use componentLibraries, we have to call loadComponentLibraries().
try { try {
loadComponentLibraryNames(); loadComponentLibraryNames();
...@@ -189,20 +189,17 @@ public final class Compiler { ...@@ -189,20 +189,17 @@ public final class Compiler {
// This is fatal. // This is fatal.
e.printStackTrace(); e.printStackTrace();
userErrors.print(String.format(ERROR_IN_STAGE, "Libraries")); userErrors.print(String.format(ERROR_IN_STAGE, "Libraries"));
return null;
} catch (JSONException e) { } catch (JSONException e) {
// This is fatal, but shouldn't actually ever happen. // This is fatal, but shouldn't actually ever happen.
e.printStackTrace(); e.printStackTrace();
userErrors.print(String.format(ERROR_IN_STAGE, "Libraries")); userErrors.print(String.format(ERROR_IN_STAGE, "Libraries"));
return null;
} }
librariesNeeded = Sets.newHashSet();
Set<String> libraries = Sets.newHashSet();
for (String componentType : componentTypes) { for (String componentType : componentTypes) {
libraries.addAll(componentLibraries.get(componentType)); librariesNeeded.addAll(componentLibraries.get(componentType));
} }
return libraries; System.out.println("Libraries needed, n= " + librariesNeeded.size());
} }
...@@ -372,8 +369,7 @@ public final class Compiler { ...@@ -372,8 +369,7 @@ public final class Compiler {
Compiler compiler = new Compiler(project, componentTypes, out, err, userErrors, isForRepl, isForWireless, Compiler compiler = new Compiler(project, componentTypes, out, err, userErrors, isForRepl, isForWireless,
childProcessRam); childProcessRam);
// Get the names of component libraries for classpath and dx command line compiler.generateLibraryNames();
librariesNeeded = compiler.generateLibraryNames();
// Create build directory. // Create build directory.
File buildDir = createDirectory(project.getBuildDirectory()); File buildDir = createDirectory(project.getBuildDirectory());
...@@ -622,12 +618,15 @@ public final class Compiler { ...@@ -622,12 +618,15 @@ public final class Compiler {
getResource(SIMPLE_ANDROID_RUNTIME_JAR) + File.pathSeparator; getResource(SIMPLE_ANDROID_RUNTIME_JAR) + File.pathSeparator;
// Add component library names to classpath // Add component library names to classpath
System.out.println("Libraries Classpath, n " + librariesNeeded.size());
for (String library : librariesNeeded) { for (String library : librariesNeeded) {
classpath += getResource(RUNTIME_FILES_DIR + library) + File.pathSeparator; classpath += getResource(RUNTIME_FILES_DIR + library) + File.pathSeparator;
} }
classpath += classpath +=
getResource(ANDROID_RUNTIME); getResource(ANDROID_RUNTIME);
System.out.println("Libraries Classpath = " + classpath);
String yailRuntime = getResource(YAIL_RUNTIME); String yailRuntime = getResource(YAIL_RUNTIME);
List<String> kawaCommandArgs = Lists.newArrayList(); List<String> kawaCommandArgs = Lists.newArrayList();
...@@ -831,10 +830,13 @@ public final class Compiler { ...@@ -831,10 +830,13 @@ public final class Compiler {
commandLineList.add(getResource(BUGSENSE_RUNTIME)); commandLineList.add(getResource(BUGSENSE_RUNTIME));
// Add libraries to command line arguments // Add libraries to command line arguments
System.out.println("Libraries needed command line n = " + librariesNeeded.size());
for (String library : librariesNeeded) { for (String library : librariesNeeded) {
commandLineList.add(getResource(RUNTIME_FILES_DIR + library)); commandLineList.add(getResource(RUNTIME_FILES_DIR + library));
} }
System.out.println("Libraries command line = " + commandLineList);
// Convert command line to an array // Convert command line to an array
String[] dxCommandLine = new String[commandLineList.size()]; String[] dxCommandLine = new String[commandLineList.size()];
commandLineList.toArray(dxCommandLine); commandLineList.toArray(dxCommandLine);
...@@ -945,7 +947,7 @@ public final class Compiler { ...@@ -945,7 +947,7 @@ public final class Compiler {
} }
} }
private static void loadComponentPermissions() throws IOException, JSONException { private void loadComponentPermissions() throws IOException, JSONException {
synchronized (componentPermissions) { synchronized (componentPermissions) {
if (componentPermissions.isEmpty()) { if (componentPermissions.isEmpty()) {
String permissionsJson = Resources.toString( String permissionsJson = Resources.toString(
...@@ -979,7 +981,7 @@ public final class Compiler { ...@@ -979,7 +981,7 @@ public final class Compiler {
* @throws IOException * @throws IOException
* @throws JSONException * @throws JSONException
*/ */
private static void loadComponentLibraryNames() throws IOException, JSONException { private void loadComponentLibraryNames() throws IOException, JSONException {
synchronized (componentLibraries) { synchronized (componentLibraries) {
if (componentLibraries.isEmpty()) { if (componentLibraries.isEmpty()) {
String librariesJson = Resources.toString( String librariesJson = Resources.toString(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment