3535
3636import java .net .*;
3737import java .io .File ;
38+ import java .io .FileFilter ;
3839import java .util .ArrayList ;
3940import java .util .Arrays ;
41+ import java .util .LinkedHashSet ;
4042
4143import edu .rice .cs .util .FileOps ;
4244import edu .rice .cs .util .swing .Utilities ;
@@ -54,32 +56,47 @@ public class ToolsJarClassLoader extends URLClassLoader {
5456
5557 /** Returns an array of possible Files for the tools.jar file. */
5658 public static File [] getToolsJarFiles (File toolsJar ) {
57- String javaHome = System .getProperty ("java.home" );
58- File home = new File (javaHome );
59- ArrayList <File > files = new ArrayList <File >();
59+ File javaHome = FileOps .getCanonicalFile (new File (System .getProperty ("java.home" )));
6060
61- // Check JAVAC_LOCATION
62- if (toolsJar .exists ()) files .add (toolsJar );
63-
64- // Check $JAVA_HOME/lib/tools.jar
65- File libDir = new File (home , "lib" );
66- File jar1 = new File (libDir , "tools.jar" );
67- if (jar1 .exists ()) files .add (jar1 );
68-
69- // Check $JAVA_HOME/../lib/tools.jar
70- File libDir2 = new File (home .getParentFile (), "lib" );
71- File jar2 = new File (libDir2 , "tools.jar" );
72- if (jar2 .exists ()) files .add (jar2 );
73-
74- if (javaHome .toLowerCase ().indexOf ("program files" ) != -1 ) {
75- // Windows: JavaHome is JRE; guess where SDK is
76- File jar3 = new File (getWindowsToolsJar (javaHome ));
77- if (jar3 .exists ()) files .add (jar3 );
61+ // We must maintain insertion order, so that the first entries have priority;
62+ // at the same time, we want to eliminate duplicates so that the same tools.jar file
63+ // doesn't show up multiple times.
64+ LinkedHashSet <File > javaHomeParents = new LinkedHashSet <File >();
65+ javaHomeParents .add (FileOps .getCanonicalFile (new File (javaHome , ".." )));
66+ javaHomeParents .add (FileOps .getCanonicalFile (new File (javaHome , "../.." )));
67+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/C:/Program Files/Java/" )));
68+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/C:/Program Files/" )));
69+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/C:/Java/" )));
70+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/C:/" )));
71+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/usr/" )));
72+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/usr/java/" )));
73+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/usr/j2se/" )));
74+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/usr/local/" )));
75+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/usr/local/java/" )));
76+ javaHomeParents .add (FileOps .getCanonicalFile (new File ("/usr/local/j2se/" )));
77+
78+ LinkedHashSet <File > javaHomes = new LinkedHashSet <File >();
79+ javaHomes .add (javaHome );
80+ String version = System .getProperty ("java.specification.version" );
81+ final String prefix1 = "j2sdk" + version ;
82+ final String prefix2 = "jdk" + version ;
83+ for (File parent : javaHomeParents ) {
84+ javaHomes .addAll (FileOps .getFilesInDir (parent , false , new FileFilter () {
85+ public boolean accept (File f ) {
86+ String name = f .getName ();
87+ return name .startsWith (prefix1 ) || name .startsWith (prefix2 );
88+ }
89+ }));
90+ }
91+
92+ LinkedHashSet <File > result = new LinkedHashSet <File >();
93+ if (toolsJar .exists ()) result .add (FileOps .getCanonicalFile (toolsJar ));
94+ for (File home : javaHomes ) {
95+ File tools = new File (home , "lib/tools.jar" );
96+ if (tools .exists ()) { result .add (FileOps .getCanonicalFile (toolsJar )); }
7897 }
7998
80- File [] fileArray = new File [files .size ()];
81- files .toArray (fileArray );
82- return fileArray ;
99+ return result .toArray (new File [0 ]);
83100 }
84101
85102 /** Returns an array of possible URLs for the tools.jar file. */
@@ -116,33 +133,6 @@ public static String getToolsJarClassPath(File toolsJar) {
116133 return classPath .toString ();
117134 }
118135
119- /** Returns a guess for the location of tools.jar based on the default
120- * installation directory for the Windows Java SDK. In Windows,
121- * JAVA_HOME is set to the JRE directory in "Program Files", but tools.jar
122- * is located in the SDK directory. Guess is simplistic: only looks on C:.
123- *
124- * PRECONDITION: javaHome contains "Program Files"
125- *
126- * @param javaHome The current JAVA_HOME System property
127- */
128- public static String getWindowsToolsJar (String javaHome ) {
129- if (javaHome .indexOf ("Program Files" ) == -1 ) return "" ;
130-
131- String prefix = "C:\\ j2sdk" ;
132- String suffix = "\\ lib\\ tools.jar" ;
133- int versionIndex ;
134-
135- if (javaHome .indexOf ("JavaSoft" ) != -1 ) {
136- prefix = "C:\\ jdk" ;
137- versionIndex = javaHome .indexOf ("JRE\\ " ) + 4 ;
138- }
139- else { versionIndex = javaHome .indexOf ("j2re" ) + 4 ; }
140-
141- String version = javaHome .substring (versionIndex );
142-
143- return prefix + version + suffix ;
144- }
145-
146136 /** Gets the requested resource, bypassing the parent classloader. */
147137 public URL getResource (String name ) { return findResource (name ); }
148138}
0 commit comments