GT-2941: Generic support for moving "fat jar" to the end of the

classpath.
This commit is contained in:
Ryan Kurtz 2019-06-18 12:07:56 -04:00
parent ba37c1bae4
commit d8da078251
3 changed files with 39 additions and 10 deletions

View file

@ -17,6 +17,7 @@ package ghidra;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import ghidra.framework.GModule; import ghidra.framework.GModule;
@ -59,7 +60,7 @@ public class GhidraLauncher {
addPatchPaths(classpathList, layout.getApplicationInstallationDir()); addPatchPaths(classpathList, layout.getApplicationInstallationDir());
addModuleJarPaths(classpathList, layout.getModules()); addModuleJarPaths(classpathList, layout.getModules());
} }
classpathList = orderClasspath(classpathList); classpathList = orderClasspath(classpathList, layout.getModules());
// Add the classpath to the class loader // Add the classpath to the class loader
GhidraClassLoader loader = (GhidraClassLoader) ClassLoader.getSystemClassLoader(); GhidraClassLoader loader = (GhidraClassLoader) ClassLoader.getSystemClassLoader();
@ -79,11 +80,11 @@ public class GhidraLauncher {
} }
/** /**
* Add patch jars to the given path list. This should be done * Add patch jars to the given path list. This should be done first so they take precedence in
* first so they take precedence in the classpath. * the classpath.
* *
* @param pathList The list of paths to add to. * @param pathList The list of paths to add to.
* @param appRootDirs The application root directories to search. * @param installDir The application installation directory.
*/ */
private static void addPatchPaths(List<String> pathList, ResourceFile installDir) { private static void addPatchPaths(List<String> pathList, ResourceFile installDir) {
ResourceFile patchDir = new ResourceFile(installDir, "Ghidra/patch"); ResourceFile patchDir = new ResourceFile(installDir, "Ghidra/patch");
@ -186,17 +187,26 @@ public class GhidraLauncher {
* Updates the list of paths to make sure the order is correct for any class-loading dependencies. * Updates the list of paths to make sure the order is correct for any class-loading dependencies.
* *
* @param pathList The list of paths to order. * @param pathList The list of paths to order.
* @param modules The modules on the classpath.
* @return A new list with the elements of the original list re-ordered as needed. * @return A new list with the elements of the original list re-ordered as needed.
*/ */
private static List<String> orderClasspath(List<String> pathList) { private static List<String> orderClasspath(List<String> pathList,
Map<String, GModule> modules) {
//@formatter:off
Set<String> flatJars = modules
.values()
.stream()
.flatMap(m -> m.getFatJars().stream())
.collect(Collectors.toSet());
//@formatter:on
List<String> orderedList = new ArrayList<String>(pathList); List<String> orderedList = new ArrayList<String>(pathList);
for (String path : pathList) { for (String path : pathList) {
if (path.endsWith("Renoir.jar")) { // Renoir.jar must be after all other jars if (flatJars.contains(new File(path).getName())) {
orderedList.remove(path); orderedList.remove(path);
orderedList.add(path); orderedList.add(path);
break;
} }
} }

View file

@ -43,6 +43,7 @@ public class GModule {
private ResourceFile moduleRoot; private ResourceFile moduleRoot;
private List<ResourceFile> searchRootsByPriority = new ArrayList<>(); private List<ResourceFile> searchRootsByPriority = new ArrayList<>();
private Set<String> dataSearchIgnoreDirs = new HashSet<>(); private Set<String> dataSearchIgnoreDirs = new HashSet<>();
private Set<String> fatJars = new HashSet<>();
public GModule(Collection<ResourceFile> appRoots, ResourceFile moduleRoot) { public GModule(Collection<ResourceFile> appRoots, ResourceFile moduleRoot) {
@ -67,6 +68,7 @@ public class GModule {
try { try {
ModuleManifestFile manifestFile = new ModuleManifestFile(moduleRoot); ModuleManifestFile manifestFile = new ModuleManifestFile(moduleRoot);
dataSearchIgnoreDirs = manifestFile.getDataSearchIgnoreDirs(); dataSearchIgnoreDirs = manifestFile.getDataSearchIgnoreDirs();
fatJars = manifestFile.getFatJars();
} }
catch (IOException e) { catch (IOException e) {
// don't care - if not using moduleManifest to find modules, then we don't // don't care - if not using moduleManifest to find modules, then we don't
@ -145,6 +147,10 @@ public class GModule {
return null; return null;
} }
public Set<String> getFatJars() {
return fatJars;
}
private void accumulateFilesByExtension(String extension, ResourceFile dir, private void accumulateFilesByExtension(String extension, ResourceFile dir,
List<ResourceFile> accumulator) { List<ResourceFile> accumulator) {
ResourceFile[] children = dir.listFiles(); ResourceFile[] children = dir.listFiles();

View file

@ -15,12 +15,11 @@
*/ */
package utility.module; package utility.module;
import generic.jar.ResourceFile;
import ghidra.util.Msg;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import generic.jar.ResourceFile;
import ghidra.util.Msg;
import utilities.util.FileUtilities; import utilities.util.FileUtilities;
public class ModuleManifestFile { public class ModuleManifestFile {
@ -32,6 +31,7 @@ public class ModuleManifestFile {
private static final String EXCLUDE_FROM_GHIDRA_JAR = "EXCLUDE FROM GHIDRA JAR"; private static final String EXCLUDE_FROM_GHIDRA_JAR = "EXCLUDE FROM GHIDRA JAR";
private static final String DATA_SEARCH_IGNORE_DIR = "DATA SEARCH IGNORE DIR:"; private static final String DATA_SEARCH_IGNORE_DIR = "DATA SEARCH IGNORE DIR:";
private static final String MODULE_DIR_IDENTIFIER = "MODULE DIR:"; private static final String MODULE_DIR_IDENTIFIER = "MODULE DIR:";
private static final String FAT_JAR = "FAT JAR:";
// private static final String EXTENSION_SUFFIX = "EXTENSION SUFFIX:"; // private static final String EXTENSION_SUFFIX = "EXTENSION SUFFIX:";
// private static final String REQUIRES_CLASS_SEARCH = "REQUIRES CLASS SEARCH:"; // private static final String REQUIRES_CLASS_SEARCH = "REQUIRES CLASS SEARCH:";
// private static final String OWNER_IDENTIFIER = "MODULE DIR:"; // private static final String OWNER_IDENTIFIER = "MODULE DIR:";
@ -46,6 +46,7 @@ public class ModuleManifestFile {
private Map<String, String> fileIPMap = new HashMap<String, String>(); private Map<String, String> fileIPMap = new HashMap<String, String>();
private Set<String> dataSearchIgnoreDirs = new HashSet<String>(); private Set<String> dataSearchIgnoreDirs = new HashSet<String>();
private Set<String> fatJars = new HashSet<>();
public ModuleManifestFile(File moduleRootDir) throws IOException { public ModuleManifestFile(File moduleRootDir) throws IOException {
this(new ResourceFile(moduleRootDir)); this(new ResourceFile(moduleRootDir));
@ -108,6 +109,9 @@ public class ModuleManifestFile {
else if (trimmedLine.startsWith(MODULE_DIR_IDENTIFIER)) { else if (trimmedLine.startsWith(MODULE_DIR_IDENTIFIER)) {
// do nothing for now // do nothing for now
} }
else if (trimmedLine.startsWith(FAT_JAR)) {
processFatJar(trimmedLine);
}
else { else {
String message = String message =
"Module manifest file error on line " + (lineNumber + 1) + " of file: " + file + "Module manifest file error on line " + (lineNumber + 1) + " of file: " + file +
@ -144,6 +148,11 @@ public class ModuleManifestFile {
moduleName = line.substring(NAME_IDENTIFIER.length()).trim(); moduleName = line.substring(NAME_IDENTIFIER.length()).trim();
} }
private void processFatJar(String line) {
String fatJar = line.substring(FAT_JAR.length()).trim();
fatJars.add(fatJar);
}
public String getModuleName() { public String getModuleName() {
return moduleName; return moduleName;
} }
@ -151,4 +160,8 @@ public class ModuleManifestFile {
public Set<String> getDataSearchIgnoreDirs() { public Set<String> getDataSearchIgnoreDirs() {
return dataSearchIgnoreDirs; return dataSearchIgnoreDirs;
} }
public Set<String> getFatJars() {
return fatJars;
}
} }