Skip to content

Commit 101c103

Browse files
author
mgricken
committed
Can specify additional jar files for the compiler now.
This will help multi-jar compilers like Habanero. Doesn't yet check well if all classes are actually found: If a class is not found, may throw a NoClassDefFoundException at the time the compiler is invoked. Also refactored JarJDKToolsLibrary.search to make it a bit easier to understand. git-svn-id: file:///tmp/test-svn/branches/drjava-compilers@5319 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent b7d4cb0 commit 101c103

File tree

9 files changed

+478
-294
lines changed

9 files changed

+478
-294
lines changed

drjava/lib/platform.jar

-350 Bytes
Binary file not shown.

drjava/src/edu/rice/cs/drjava/model/JarJDKToolsLibrary.java

Lines changed: 102 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@
5353
import java.util.jar.Manifest;
5454
import java.util.Enumeration;
5555
import java.io.IOException;
56+
import java.io.FileNotFoundException;
5657

57-
import edu.rice.cs.plt.iter.IterUtil;
5858
import edu.rice.cs.plt.io.IOUtil;
59-
import edu.rice.cs.plt.lambda.Lambda3;
59+
import edu.rice.cs.plt.iter.IterUtil;
60+
import edu.rice.cs.plt.lambda.Lambda;
6061
import edu.rice.cs.plt.lambda.LambdaUtil;
6162
import edu.rice.cs.plt.lambda.Predicate;
6263
import edu.rice.cs.plt.reflect.ReflectUtil;
@@ -153,8 +154,16 @@ public static JarJDKToolsLibrary makeFromFile(File f, GlobalModel model, JDKDesc
153154
JDKToolsLibrary.msg("\tdesc = "+desc);
154155

155156
boolean isSupported = JavaVersion.CURRENT.supports(version.majorVersion());
157+
Iterable<File> additionalCompilerFiles = IterUtil.empty();
156158
if (desc!=null) {
157159
isSupported |= JavaVersion.CURRENT.supports(desc.getMinimumMajorVersion());
160+
try {
161+
additionalCompilerFiles = desc.getAdditionalCompilerFiles(f);
162+
}
163+
catch(FileNotFoundException fnfe) {
164+
// not all additional compiler files were found
165+
isSupported = false;
166+
}
158167
}
159168

160169
// We can't execute code that was possibly compiled for a later Java API version.
@@ -163,7 +172,9 @@ public static JarJDKToolsLibrary makeFromFile(File f, GlobalModel model, JDKDesc
163172
// block tools.jar classes, so that references don't point to a different version of the classes
164173
ClassLoader loader =
165174
new ShadowingClassLoader(JarJDKToolsLibrary.class.getClassLoader(), true, TOOLS_PACKAGES, true);
166-
Iterable<File> path = IterUtil.singleton(IOUtil.attemptAbsoluteFile(f));
175+
Iterable<File> path = IterUtil.map(IterUtil.compose(additionalCompilerFiles, f), new Lambda<File,File>() {
176+
public File value(File arg) { return IOUtil.attemptAbsoluteFile(arg); }
177+
});
167178

168179
String compilerAdapter = adapterForCompiler(version);
169180
if (desc!=null) {
@@ -335,12 +346,13 @@ else if (jf.getJarEntry("com/sun/tools/javac/util/DefaultFileManager.class")!=nu
335346
return result;
336347
}
337348

338-
/** Produce a list of tools libraries discovered on the file system. A variety of locations are searched;
339-
* only those files that can produce a valid library (see {@link #isValid} are returned. The result is
340-
* sorted by version. Where one library of the same version might be preferred over another, the preferred
341-
* library appears earlier in the result list.
342-
*/
343-
public static Iterable<JarJDKToolsLibrary> search(GlobalModel model) {
349+
/** return a collection with the default roots. */
350+
protected static LinkedHashMap<File,Set<JDKDescriptor>> getDefaultSearchRoots() {
351+
/* roots is a list of possible parent directories of Java installations; we want to eliminate duplicates &
352+
* remember insertion order
353+
*/
354+
LinkedHashMap<File,Set<JDKDescriptor>> roots = new LinkedHashMap<File,Set<JDKDescriptor>>();
355+
344356
String javaHome = System.getProperty("java.home");
345357
String envJavaHome = null;
346358
String programFiles = null;
@@ -352,12 +364,7 @@ public static Iterable<JarJDKToolsLibrary> search(GlobalModel model) {
352364
programFiles = System.getenv("ProgramFiles");
353365
systemDrive = System.getenv("SystemDrive");
354366
}
355-
356-
/* roots is a list of possible parent directories of Java installations; we want to eliminate duplicates &
357-
* remember insertion order
358-
*/
359-
LinkedHashMap<File,Set<JDKDescriptor>> roots = new LinkedHashMap<File,Set<JDKDescriptor>>();
360-
367+
361368
if (javaHome != null) {
362369
addIfDir(new File(javaHome), null, roots);
363370
addIfDir(new File(javaHome, ".."), null, roots);
@@ -398,22 +405,13 @@ public static Iterable<JarJDKToolsLibrary> search(GlobalModel model) {
398405
addIfDir(new File("/usr/lib/jvm/java-6-openjdk"), null, roots);
399406

400407
addIfDir(new File("/home/javaplt/java/Linux-i686"), null, roots);
401-
402-
/* jars is a list of possible tools.jar (or classes.jar) files; we want to eliminate duplicates &
403-
* remember insertion order
404-
*/
405-
LinkedHashMap<File,Set<JDKDescriptor>> jars = new LinkedHashMap<File,Set<JDKDescriptor>>();
406-
407-
// Search for all compound JDK descriptors in the drjava.jar file
408-
Iterable<JDKDescriptor> descriptors = searchForJDKDescriptors();
409-
for(JDKDescriptor desc: descriptors) {
410-
// add the specific search directories and files
411-
for(File f: desc.getSearchDirectories()) { addIfDir(f, desc, roots); }
412-
for(File f: desc.getSearchFiles()) { addIfFile(f, desc, jars); }
413-
// add to the set of packages that need to be shadowed
414-
TOOLS_PACKAGES.addAll(desc.getToolsPackages());
415-
}
416408

409+
return roots;
410+
}
411+
412+
/* Search for jar files in roots and, if found, transfer them to the jars collection. */
413+
protected static void searchRootsForJars(LinkedHashMap<File,Set<JDKDescriptor>> roots,
414+
LinkedHashMap<File,Set<JDKDescriptor>> jars) {
417415
// matches: starts with "j2sdk", starts with "jdk", has form "[number].[number].[number]" (OS X), or
418416
// starts with "java-" (Linux)
419417
Predicate<File> subdirFilter = LambdaUtil.or(IOUtil.regexCanonicalCaseFilePredicate("j2sdk.*"),
@@ -426,13 +424,13 @@ public static Iterable<JarJDKToolsLibrary> search(GlobalModel model) {
426424
addIfFile(new File(subdir, "Classes/classes.jar"), root.getValue(), jars);
427425
}
428426
}
429-
430-
// We store everything in reverse order, since that's the natural order of the versions
431-
Map<FullVersion, Iterable<JarJDKToolsLibrary>> results =
432-
new TreeMap<FullVersion, Iterable<JarJDKToolsLibrary>>();
433-
Map<FullVersion, Iterable<JarJDKToolsLibrary>> compoundResults =
434-
new TreeMap<FullVersion, Iterable<JarJDKToolsLibrary>>();
435-
427+
}
428+
429+
/** Check which jars are valid JDKs, and determine if they are compound or full (non-compound) JDKs. */
430+
protected static void collectValidResults(GlobalModel model,
431+
LinkedHashMap<File,Set<JDKDescriptor>> jars,
432+
Map<FullVersion, Iterable<JarJDKToolsLibrary>> results,
433+
Map<FullVersion, Iterable<JarJDKToolsLibrary>> compoundResults) {
436434
for (Map.Entry<File,Set<JDKDescriptor>> jar : jars.entrySet()) {
437435
for (JDKDescriptor desc : jar.getValue()) {
438436
if (desc!=null) {
@@ -456,12 +454,17 @@ public static Iterable<JarJDKToolsLibrary> search(GlobalModel model) {
456454
}
457455
}
458456
}
459-
460-
Iterable<JarJDKToolsLibrary> collapsed = IterUtil.reverse(IterUtil.collapse(results.values()));
461-
Iterable<JarJDKToolsLibrary> compoundCollapsed = IterUtil.reverse(IterUtil.collapse(compoundResults.values()));
462-
463-
Map<FullVersion, Iterable<JarJDKToolsLibrary>> allResults =
457+
}
458+
459+
/** Get completed compound JDKs by going through the list of compound JDKs and finding full JDKs that
460+
* complete them. */
461+
protected static Map<FullVersion, Iterable<JarJDKToolsLibrary>>
462+
getCompletedCompoundResults(GlobalModel model,
463+
Iterable<JarJDKToolsLibrary> collapsed,
464+
Iterable<JarJDKToolsLibrary> compoundCollapsed) {
465+
Map<FullVersion, Iterable<JarJDKToolsLibrary>> completedResults =
464466
new TreeMap<FullVersion, Iterable<JarJDKToolsLibrary>>();
467+
465468
// now we have the JDK libraries in collapsed and the compound libraries in compoundCollapsed
466469
for(JarJDKToolsLibrary compoundLib: compoundCollapsed) {
467470
JDKToolsLibrary.msg("compoundLib: "+compoundLib.version());
@@ -502,17 +505,71 @@ public static Iterable<JarJDKToolsLibrary> search(GlobalModel model) {
502505
if (lib.isValid()) {
503506
JDKToolsLibrary.msg("\t==> "+lib.version());
504507
FullVersion v = lib.version();
505-
if (allResults.containsKey(v)) { allResults.put(v, IterUtil.compose(lib, allResults.get(v))); }
506-
else { allResults.put(v, IterUtil.singleton(lib)); }
508+
if (completedResults.containsKey(v)) {
509+
completedResults.put(v, IterUtil.compose(lib, completedResults.get(v)));
510+
}
511+
else {
512+
completedResults.put(v, IterUtil.singleton(lib));
513+
}
507514
}
508515
}
509516
}
517+
return completedResults;
518+
}
519+
520+
/** Produce a list of tools libraries discovered on the file system. A variety of locations are searched;
521+
* only those files that can produce a valid library (see {@link #isValid} are returned. The result is
522+
* sorted by version. Where one library of the same version might be preferred over another, the preferred
523+
* library appears earlier in the result list.
524+
*/
525+
public static Iterable<JarJDKToolsLibrary> search(GlobalModel model) {
526+
/* roots is a list of possible parent directories of Java installations; we want to eliminate duplicates &
527+
* remember insertion order
528+
*/
529+
LinkedHashMap<File,Set<JDKDescriptor>> roots = getDefaultSearchRoots();
530+
531+
/* jars is a list of possible tools.jar (or classes.jar) files; we want to eliminate duplicates &
532+
* remember insertion order
533+
*/
534+
LinkedHashMap<File,Set<JDKDescriptor>> jars = new LinkedHashMap<File,Set<JDKDescriptor>>();
535+
536+
// Search for all compound JDK descriptors in the drjava.jar file
537+
Iterable<JDKDescriptor> descriptors = searchForJDKDescriptors();
538+
for(JDKDescriptor desc: descriptors) {
539+
// add the specific search directories and files
540+
for(File f: desc.getSearchDirectories()) { addIfDir(f, desc, roots); }
541+
for(File f: desc.getSearchFiles()) { addIfFile(f, desc, jars); }
542+
// add to the set of packages that need to be shadowed
543+
TOOLS_PACKAGES.addAll(desc.getToolsPackages());
544+
}
545+
546+
// search for jar files in roots and, if found, transfer them to the jars collection
547+
searchRootsForJars(roots, jars);
548+
549+
// check which jars are valid JDKs, and determine if they are compound or full (non-compound) JDKs
550+
Map<FullVersion, Iterable<JarJDKToolsLibrary>> results =
551+
new TreeMap<FullVersion, Iterable<JarJDKToolsLibrary>>();
552+
Map<FullVersion, Iterable<JarJDKToolsLibrary>> compoundResults =
553+
new TreeMap<FullVersion, Iterable<JarJDKToolsLibrary>>();
554+
555+
collectValidResults(model, jars, results, compoundResults);
556+
557+
// We store everything in reverse order, since that's the natural order of the versions
558+
Iterable<JarJDKToolsLibrary> collapsed = IterUtil.reverse(IterUtil.collapse(results.values()));
559+
Iterable<JarJDKToolsLibrary> compoundCollapsed = IterUtil.reverse(IterUtil.collapse(compoundResults.values()));
560+
561+
// Get completed compound JDKs by going through the list of compound JDKs and finding full JDKs that
562+
// complete them
563+
Map<FullVersion, Iterable<JarJDKToolsLibrary>> completedResults =
564+
getCompletedCompoundResults(model, collapsed, compoundCollapsed);
565+
510566
JDKToolsLibrary.msg("Result:");
511567
Iterable<JarJDKToolsLibrary> result = IterUtil.
512-
compose(collapsed,IterUtil.reverse(IterUtil.collapse(allResults.values())));
568+
compose(collapsed,IterUtil.reverse(IterUtil.collapse(completedResults.values())));
513569
for(JarJDKToolsLibrary lib: result) {
514570
JDKToolsLibrary.msg("Found library: "+lib);
515571
}
572+
516573
return result;
517574
}
518575

0 commit comments

Comments
 (0)