diff --git a/spring-boot-cli-grape/src/main/java/org/springframework/boot/cli/compiler/AetherGrapeEngine.java b/spring-boot-cli-grape/src/main/java/org/springframework/boot/cli/compiler/AetherGrapeEngine.java index e3aa293c3e1..9b985ec5340 100644 --- a/spring-boot-cli-grape/src/main/java/org/springframework/boot/cli/compiler/AetherGrapeEngine.java +++ b/spring-boot-cli-grape/src/main/java/org/springframework/boot/cli/compiler/AetherGrapeEngine.java @@ -24,6 +24,7 @@ import java.net.MalformedURLException; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -39,6 +40,7 @@ import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.Exclusion; import org.eclipse.aether.impl.ArtifactDescriptorReader; import org.eclipse.aether.impl.DefaultServiceLocator; import org.eclipse.aether.internal.impl.DefaultRepositorySystem; @@ -77,6 +79,9 @@ public class AetherGrapeEngine implements GrapeEngine { private static final String DEPENDENCY_VERSION = "version"; + private static final Collection WILDCARD_EXCLUSION = Arrays + .asList(new Exclusion("*", "*", "*", "*")); + private final Artifact parentArtifact; private final ProgressReporter progressReporter = new ProgressReporter(); @@ -190,15 +195,36 @@ public class AetherGrapeEngine implements GrapeEngine { return dependencies; } + private boolean isTransitive(Map dependencyMap) { + Boolean transitive = (Boolean) dependencyMap.get("transitive"); + if (transitive == null) { + transitive = true; + } + return transitive; + } + private Dependency createDependency(Map dependencyMap) { + Artifact artifact = createArtifact(dependencyMap); + + Dependency dependency; + + if (!isTransitive(dependencyMap)) { + dependency = new Dependency(artifact, JavaScopes.COMPILE, null, + WILDCARD_EXCLUSION); + } + else { + dependency = new Dependency(artifact, JavaScopes.COMPILE); + } + + return dependency; + } + + private Artifact createArtifact(Map dependencyMap) { String group = (String) dependencyMap.get(DEPENDENCY_GROUP); String module = (String) dependencyMap.get(DEPENDENCY_MODULE); String version = (String) dependencyMap.get(DEPENDENCY_VERSION); - // TODO Transitivity - - Artifact artifact = new DefaultArtifact(group, module, "jar", version); - return new Dependency(artifact, JavaScopes.COMPILE); + return new DefaultArtifact(group, module, "jar", version); } private List resolve(List dependencies) diff --git a/spring-boot-cli-grape/src/test/java/org/springframework/boot/cli/compiler/AetherGrapeEngineTests.java b/spring-boot-cli-grape/src/test/java/org/springframework/boot/cli/compiler/AetherGrapeEngineTests.java new file mode 100644 index 00000000000..c27b9486f28 --- /dev/null +++ b/spring-boot-cli-grape/src/test/java/org/springframework/boot/cli/compiler/AetherGrapeEngineTests.java @@ -0,0 +1,88 @@ +/* + * 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.compiler; + +import groovy.lang.GroovyClassLoader; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Andy Wilkinson + */ +public class AetherGrapeEngineTests { + + private final GroovyClassLoader groovyClassLoader = new GroovyClassLoader(); + + private final AetherGrapeEngine grapeEngine = new AetherGrapeEngine( + this.groovyClassLoader, null, null, null); + + @Test + public void dependencyResolution() { + Map args = new HashMap(); + + this.grapeEngine.grab(args, + createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE")); + + assertEquals(6, this.groovyClassLoader.getURLs().length); + } + + @Test + public void nonTransitiveDependencyResolution() { + Map args = new HashMap(); + + this.grapeEngine.grab( + args, + createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE", + false)); + + assertEquals(1, this.groovyClassLoader.getURLs().length); + } + + @Test + public void dependencyResolutionWithCustomClassLoader() { + Map args = new HashMap(); + GroovyClassLoader customClassLoader = new GroovyClassLoader(); + args.put("classLoader", customClassLoader); + + this.grapeEngine.grab(args, + createDependency("org.springframework", "spring-jdbc", "3.2.4.RELEASE")); + + assertEquals(0, this.groovyClassLoader.getURLs().length); + assertEquals(6, customClassLoader.getURLs().length); + } + + private Map createDependency(String group, String module, + String version) { + Map dependency = new HashMap(); + dependency.put("group", group); + dependency.put("module", module); + dependency.put("version", version); + return dependency; + } + + private Map createDependency(String group, String module, + String version, boolean transitive) { + Map dependency = createDependency(group, module, version); + dependency.put("transitive", transitive); + return dependency; + } +} diff --git a/spring-boot-cli/pom.xml b/spring-boot-cli/pom.xml index baef3529935..d1fe46513d0 100644 --- a/spring-boot-cli/pom.xml +++ b/spring-boot-cli/pom.xml @@ -100,11 +100,17 @@ src/main/groovy + + ${project.build.directory}/generated-resources + maven-surefire-plugin + + ${project.build.directory}/generated-resources + org.springframework:spring-core org.springframework:spring-beans @@ -190,7 +196,7 @@ diff --git a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java index 2df6ac6fdc2..bc044682729 100644 --- a/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java +++ b/spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java @@ -353,30 +353,37 @@ public class GroovyCompiler { } private void transformGrabAnnotation(AnnotationNode grabAnnotation) { + grabAnnotation.setMember("initClass", new ConstantExpression(false)); + Expression valueExpression = grabAnnotation.getMember("value"); + String value = null; if (valueExpression instanceof ConstantExpression) { ConstantExpression constantExpression = (ConstantExpression) valueExpression; Object valueObject = constantExpression.getValue(); if (valueObject instanceof String) { - String value = (String) valueObject; - if (!isConvenienceForm(value)) { - applyGroupAndVersion(grabAnnotation, constantExpression); + value = (String) valueObject; + if (isConvenienceForm(value)) { + return; } - grabAnnotation.setMember("initClass", new ConstantExpression(false)); } } + + applyGroupAndVersion(grabAnnotation, value); } private boolean isConvenienceForm(String value) { return value.contains(":") || value.contains("#"); } - private void applyGroupAndVersion(AnnotationNode grabAnnotation, - ConstantExpression moduleExpression) { + private void applyGroupAndVersion(AnnotationNode grabAnnotation, String module) { - grabAnnotation.setMember("module", moduleExpression); - - String module = (String) moduleExpression.getValue(); + if (module != null) { + grabAnnotation.setMember("module", new ConstantExpression(module)); + } + else { + module = (String) ((ConstantExpression) grabAnnotation.getMembers().get( + "module")).getValue(); + } if (grabAnnotation.getMember("group") == null) { ConstantExpression groupIdExpression = new ConstantExpression( @@ -391,10 +398,6 @@ public class GroovyCompiler { .getVersion(module)); grabAnnotation.setMember("version", versionExpression); } - - grabAnnotation.setMember("initClass", new ConstantExpression(false)); - } } - }