Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions server/src/main/java/com/defold/extender/Extender.java
Original file line number Diff line number Diff line change
Expand Up @@ -1989,9 +1989,54 @@ private List<String> getAllJars(Map<String,ProGuardContext> extensionJarMap) thr
Map<String, Object> context = createContext(mergedAppContext);
List<String> allJars = ExtenderUtil.pruneItems( (List<String>)context.get("engineJars"), includeJars, excludeJars);
allJars.addAll( ExtenderUtil.pruneItems( extensionJars, includeJars, excludeJars) );
allJars = pruneConflictingAndroidMultidexJars(allJars);
return allJars;
}

private static boolean hasGradleDependency(List<String> jars, String artifactPrefix) {
String escapedPrefix = Pattern.quote(artifactPrefix);
Pattern aarClassesPattern = Pattern.compile(String.format(".*/%s-[^/]+\\.aar/classes\\.jar$", escapedPrefix));
Pattern jarPattern = Pattern.compile(String.format(".*/%s-[^/]+\\.jar$", escapedPrefix));

for (String jarPath : jars) {
String normalizedPath = jarPath.replace('\\', '/');
if (aarClassesPattern.matcher(normalizedPath).matches() || jarPattern.matcher(normalizedPath).matches()) {
return true;
}
}
return false;
}

private static boolean isEngineShareJavaJar(String jarPath, String engineJarName) {
return jarPath.replace('\\', '/').endsWith("/share/java/" + engineJarName);
}

static List<String> pruneConflictingAndroidMultidexJars(List<String> jars) {
List<String> prunedJars = new ArrayList<>(jars);

if (hasGradleDependency(prunedJars, "androidx.multidex-multidex")) {
List<String> removed = prunedJars.stream()
.filter(jarPath -> isEngineShareJavaJar(jarPath, "androidx-multidex.jar"))
.collect(Collectors.toList());
if (!removed.isEmpty()) {
LOGGER.info("Removing engine androidx multidex jar(s) due to Gradle dependency: {}", removed);
prunedJars.removeAll(removed);
}
}

if (hasGradleDependency(prunedJars, "com.android.support-multidex")) {
List<String> removed = prunedJars.stream()
.filter(jarPath -> isEngineShareJavaJar(jarPath, "android-support-multidex.jar"))
.collect(Collectors.toList());
if (!removed.isEmpty()) {
LOGGER.info("Removing engine support multidex jar(s) due to Gradle dependency: {}", removed);
prunedJars.removeAll(removed);
}
}

return prunedJars;
}

// arguments:
// jars - the list of all available jar files gathered from the build
// extensionJarMap - a mapping from a jar file to a list of its corresponding proGuard contexts
Expand Down Expand Up @@ -2136,6 +2181,13 @@ private File buildMainDexList(List<String> jars) throws ExtenderException {

// Find the engine libraries (**/share/java/*.jar)
List<String> mainListJars = ExtenderUtil.filterStrings(jars, ExtenderConst.ENGINE_JAR_RE);
// Keep multidex classes in the main dex even when engine multidex jars are replaced
// by Gradle dependencies.
mainListJars.addAll(ExtenderUtil.filterStrings(jars, "(?:.*)/androidx\\.multidex-multidex-[^/]+\\.aar/classes\\.jar$"));
mainListJars.addAll(ExtenderUtil.filterStrings(jars, "(?:.*)/androidx\\.multidex-multidex-[^/]+\\.jar$"));
mainListJars.addAll(ExtenderUtil.filterStrings(jars, "(?:.*)/com\\.android\\.support-multidex-[^/]+\\.aar/classes\\.jar$"));
mainListJars.addAll(ExtenderUtil.filterStrings(jars, "(?:.*)/com\\.android\\.support-multidex-[^/]+\\.jar$"));
mainListJars = ExtenderUtil.makeUnique(mainListJars);

if (mainListJars.isEmpty()) {
throw new ExtenderException("Regex failed to find any engine jars: " + ExtenderConst.ENGINE_JAR_RE);
Expand Down
42 changes: 42 additions & 0 deletions server/src/test/java/com/defold/extender/ExtenderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,48 @@ public void testExcludeItems() throws IOException, InterruptedException, Extende
}
}

@Test
public void testPruneConflictingAndroidMultidexJarsAndroidX() {
List<String> jars = new ArrayList<>();
jars.add("/var/extender/sdk/hash/defoldsdk/ext/share/java/androidx-multidex.jar");
jars.add("/var/extender/sdk/hash/defoldsdk/share/java/glfw_android.jar");
jars.add("/tmp/.gradle/unpacked/androidx.multidex-multidex-2.0.1.aar/classes.jar");

List<String> result = Extender.pruneConflictingAndroidMultidexJars(jars);

assertFalse(result.contains("/var/extender/sdk/hash/defoldsdk/ext/share/java/androidx-multidex.jar"));
assertTrue(result.contains("/var/extender/sdk/hash/defoldsdk/share/java/glfw_android.jar"));
assertTrue(result.contains("/tmp/.gradle/unpacked/androidx.multidex-multidex-2.0.1.aar/classes.jar"));
}

@Test
public void testPruneConflictingAndroidMultidexJarsSupportLib() {
List<String> jars = new ArrayList<>();
jars.add("/var/extender/sdk/hash/defoldsdk/ext/share/java/android-support-multidex.jar");
jars.add("/var/extender/sdk/hash/defoldsdk/share/java/glfw_android.jar");
jars.add("/tmp/.gradle/unpacked/com.android.support-multidex-1.0.3.aar/classes.jar");

List<String> result = Extender.pruneConflictingAndroidMultidexJars(jars);

assertFalse(result.contains("/var/extender/sdk/hash/defoldsdk/ext/share/java/android-support-multidex.jar"));
assertTrue(result.contains("/var/extender/sdk/hash/defoldsdk/share/java/glfw_android.jar"));
assertTrue(result.contains("/tmp/.gradle/unpacked/com.android.support-multidex-1.0.3.aar/classes.jar"));
}

@Test
public void testPruneConflictingAndroidMultidexJarsNoGradleMultidex() {
List<String> jars = new ArrayList<>();
jars.add("/var/extender/sdk/hash/defoldsdk/ext/share/java/androidx-multidex.jar");
jars.add("/var/extender/sdk/hash/defoldsdk/share/java/glfw_android.jar");
jars.add("/tmp/.gradle/unpacked/com.google.android.gms-play-services-ads-24.0.0.aar/classes.jar");

List<String> result = Extender.pruneConflictingAndroidMultidexJars(jars);

assertTrue(result.contains("/var/extender/sdk/hash/defoldsdk/ext/share/java/androidx-multidex.jar"));
assertTrue(result.contains("/var/extender/sdk/hash/defoldsdk/share/java/glfw_android.jar"));
assertTrue(result.contains("/tmp/.gradle/unpacked/com.google.android.gms-play-services-ads-24.0.0.aar/classes.jar"));
}

@Test
public void testAppManifestContext() throws IOException, ExtenderException {

Expand Down