Favor groovy.jar instead of groovy-all.jar
Update CLI application to use groovy.jar rather than groovy-all.jar. This prevents classloading issues when a user project @Grabs groovy-ant.
This commit is contained in:
@@ -26,8 +26,11 @@ import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.codehaus.groovy.ast.ClassNode;
|
||||
import org.codehaus.groovy.control.CompilationUnit;
|
||||
@@ -159,39 +162,39 @@ class ExtendedGroovyClassLoader extends GroovyClassLoader {
|
||||
*/
|
||||
private static class DefaultScopeParentClassLoader extends ClassLoader {
|
||||
|
||||
private static final String[] GROOVY_JARS_PREFIXES = { "groovy", "antlr", "asm" };
|
||||
|
||||
private final URLClassLoader groovyOnlyClassLoader;
|
||||
|
||||
public DefaultScopeParentClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
this.groovyOnlyClassLoader = new URLClassLoader(
|
||||
new URL[] { getGroovyJar(parent) }, null);
|
||||
this.groovyOnlyClassLoader = new URLClassLoader(getGroovyJars(parent), null);
|
||||
}
|
||||
|
||||
private URL getGroovyJar(final ClassLoader parent) {
|
||||
URL result = findGroovyJarDirectly(parent);
|
||||
if (result == null) {
|
||||
result = findGroovyJarFromClassPath(parent);
|
||||
private URL[] getGroovyJars(final ClassLoader parent) {
|
||||
Set<URL> urls = new HashSet<URL>();
|
||||
findGroovyJarsDirectly(parent, urls);
|
||||
if (urls.isEmpty()) {
|
||||
findGroovyJarsFromClassPath(parent, urls);
|
||||
}
|
||||
Assert.state(result != null, "Unable to find groovy JAR");
|
||||
return result;
|
||||
Assert.state(urls.size() > 0, "Unable to find groovy JAR");
|
||||
return new ArrayList<URL>(urls).toArray(new URL[urls.size()]);
|
||||
}
|
||||
|
||||
private URL findGroovyJarDirectly(ClassLoader classLoader) {
|
||||
private void findGroovyJarsDirectly(ClassLoader classLoader, Set<URL> urls) {
|
||||
while (classLoader != null) {
|
||||
if (classLoader instanceof URLClassLoader) {
|
||||
URL[] urls = ((URLClassLoader) classLoader).getURLs();
|
||||
for (URL url : urls) {
|
||||
for (URL url : ((URLClassLoader) classLoader).getURLs()) {
|
||||
if (isGroovyJar(url.toString())) {
|
||||
return url;
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
classLoader = classLoader.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private URL findGroovyJarFromClassPath(ClassLoader parent) {
|
||||
private void findGroovyJarsFromClassPath(ClassLoader parent, Set<URL> urls) {
|
||||
String classpath = System.getProperty("java.class.path");
|
||||
String[] entries = classpath.split(System.getProperty("path.separator"));
|
||||
for (String entry : entries) {
|
||||
@@ -199,7 +202,7 @@ class ExtendedGroovyClassLoader extends GroovyClassLoader {
|
||||
File file = new File(entry);
|
||||
if (file.canRead()) {
|
||||
try {
|
||||
return file.toURI().toURL();
|
||||
urls.add(file.toURI().toURL());
|
||||
}
|
||||
catch (MalformedURLException ex) {
|
||||
// Swallow and continue
|
||||
@@ -207,11 +210,15 @@ class ExtendedGroovyClassLoader extends GroovyClassLoader {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isGroovyJar(String entry) {
|
||||
return entry.contains("/groovy-all");
|
||||
for (String jarPrefix : GROOVY_JARS_PREFIXES) {
|
||||
if (entry.contains("/" + jarPrefix + "-")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.boot.cli;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -86,6 +90,26 @@ public class CliTester implements TestRule {
|
||||
return this.outputCapture.apply(new RunLauncherStatement(base), description);
|
||||
}
|
||||
|
||||
public String getHttpOutput() {
|
||||
return getHttpOutput("http://localhost:8080");
|
||||
}
|
||||
|
||||
public String getHttpOutput(String uri) {
|
||||
try {
|
||||
InputStream stream = URI.create(uri).toURL().openStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||
String line;
|
||||
StringBuilder result = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
result.append(line);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private final class RunLauncherStatement extends Statement {
|
||||
|
||||
private final Statement base;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.cli;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests to exercise reproduce raised issues.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ReproIntegrationTests {
|
||||
|
||||
private static final String SRC = "src/test/resources/repro-samples";
|
||||
|
||||
@Rule
|
||||
public CliTester cli = new CliTester();
|
||||
|
||||
@Test
|
||||
public void grabAntBuilder() throws Exception {
|
||||
this.cli.run(SRC + "/grab-ant-builder.groovy");
|
||||
assertThat(this.cli.getHttpOutput(),
|
||||
containsString("{\"message\":\"Hello World\"}"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,11 +16,7 @@
|
||||
|
||||
package org.springframework.boot.cli;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URI;
|
||||
|
||||
import org.codehaus.plexus.util.FileUtils;
|
||||
import org.junit.BeforeClass;
|
||||
@@ -85,31 +81,29 @@ public class SampleIntegrationTests {
|
||||
"foo=bar");
|
||||
assertTrue("Wrong output: " + output,
|
||||
output.contains("completed with the following parameters"));
|
||||
String result = readEntirely("http://localhost:8080");
|
||||
String result = this.cli.getHttpOutput();
|
||||
assertEquals("World!", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void webSample() throws Exception {
|
||||
this.cli.run("samples/web.groovy");
|
||||
String result = readEntirely("http://localhost:8080");
|
||||
assertEquals("World!", result);
|
||||
assertEquals("World!", this.cli.getHttpOutput());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uiSample() throws Exception {
|
||||
this.cli.run("samples/ui.groovy", "--classpath=.:src/test/resources");
|
||||
String result = readEntirely("http://localhost:8080");
|
||||
String result = this.cli.getHttpOutput();
|
||||
assertTrue("Wrong output: " + result, result.contains("Hello World"));
|
||||
result = readEntirely("http://localhost:8080/css/bootstrap.min.css");
|
||||
result = this.cli.getHttpOutput("http://localhost:8080/css/bootstrap.min.css");
|
||||
assertTrue("Wrong output: " + result, result.contains("container"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actuatorSample() throws Exception {
|
||||
this.cli.run("samples/actuator.groovy");
|
||||
String result = readEntirely("http://localhost:8080");
|
||||
assertEquals("{\"message\":\"Hello World!\"}", result);
|
||||
assertEquals("{\"message\":\"Hello World!\"}", this.cli.getHttpOutput());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -156,24 +150,7 @@ public class SampleIntegrationTests {
|
||||
@Test
|
||||
public void deviceSample() throws Exception {
|
||||
this.cli.run("samples/device.groovy");
|
||||
String result = readEntirely("http://localhost:8080");
|
||||
assertEquals("Hello Normal Device!", result);
|
||||
}
|
||||
|
||||
private static String readEntirely(String uri) {
|
||||
try {
|
||||
InputStream stream = URI.create(uri).toURL().openStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||
String line;
|
||||
StringBuilder result = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
result.append(line);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
assertEquals("Hello Normal Device!", this.cli.getHttpOutput());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
@Grab("org.codehaus.groovy:groovy-ant:2.1.6")
|
||||
|
||||
@RestController
|
||||
class MainController {
|
||||
|
||||
@RequestMapping("/")
|
||||
def home() {
|
||||
new AntBuilder().echo(message:"Hello world")
|
||||
[message: "Hello World"]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user