Skip to content

Commit 57662d1

Browse files
committed
GROOVY-11978: RootLoader duplicates the core jar already on the bootstrap classpath
1 parent 42b9d17 commit 57662d1

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

src/main/java/org/codehaus/groovy/tools/RootLoader.java

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@
1919
package org.codehaus.groovy.tools;
2020

2121
import java.io.File;
22+
import java.io.IOException;
2223
import java.net.MalformedURLException;
24+
import java.net.URISyntaxException;
2325
import java.net.URL;
2426
import java.net.URLClassLoader;
2527
import java.util.HashMap;
28+
import java.util.HashSet;
2629
import java.util.Map;
2730
import java.util.Optional;
31+
import java.util.Set;
2832

2933
/**
3034
* This ClassLoader should be used as root of class loaders. Any
@@ -109,8 +113,16 @@ public RootLoader(final LoaderConfiguration lc) {
109113

110114
Thread.currentThread().setContextClassLoader(this);
111115

116+
// Skip URLs already on the JVM startup (system) classpath: the launcher
117+
// puts the core groovy jar on -classpath to start GroovyStarter, and
118+
// groovy-starter.conf's "load lib/*.jar" then re-globs it. Adding the
119+
// same jar to both loaders lets each define its own copy of every core
120+
// class, and trips duplicate-resource detection.
121+
Set<File> startup = startupClasspathFiles();
112122
for (URL url : lc.getClassPathUrls()) {
113-
addURL(url);
123+
if (!startup.contains(canonicalFile(url))) {
124+
addURL(url);
125+
}
114126
}
115127
// TODO M12N eventually defer this until later when we have a full Groovy
116128
// environment and use normal Grape.grab()
@@ -179,4 +191,33 @@ public void addURL(final URL url) {
179191
protected Class<?> findClass(final String name) throws ClassNotFoundException {
180192
throw new ClassNotFoundException(name);
181193
}
194+
195+
private static Set<File> startupClasspathFiles() {
196+
Set<File> files = new HashSet<>();
197+
String cp = System.getProperty("java.class.path");
198+
if (cp == null || cp.isEmpty()) return files;
199+
for (String entry : cp.split(File.pathSeparator)) {
200+
if (entry.isEmpty()) continue;
201+
File f = canonicalFile(new File(entry));
202+
if (f != null) files.add(f);
203+
}
204+
return files;
205+
}
206+
207+
private static File canonicalFile(URL url) {
208+
if (!"file".equals(url.getProtocol())) return null;
209+
try {
210+
return canonicalFile(new File(url.toURI()));
211+
} catch (URISyntaxException | IllegalArgumentException e) {
212+
return null;
213+
}
214+
}
215+
216+
private static File canonicalFile(File f) {
217+
try {
218+
return f.getCanonicalFile();
219+
} catch (IOException e) {
220+
return f.getAbsoluteFile();
221+
}
222+
}
182223
}

0 commit comments

Comments
 (0)