From a2d328ae3aa5dbc651c1fc82f47febf8e9873bc3 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 25 Apr 2013 16:02:44 +0100 Subject: [PATCH] [bs-73] Anonymous classes cannot be used in @Bean definitions in .groovy scripts * Added a test for each of the classes loaded by the SpringApplication * If it's an anonymous class or looks like a Groovy closure we ignore it * The CLI sample job.groovy also modified to take advantage [Fixes #48718891] --- pom.xml | 2 +- spring-bootstrap-cli/samples/job.groovy | 14 ++-- .../bootstrap/cli/CleanCommand.java | 74 ++++++++++++++----- spring-bootstrap-cli/src/main/scripts/spring | 2 +- .../bootstrap/BeanDefinitionLoader.java | 17 ++++- .../bootstrap/SpringApplication.java | 4 +- 6 files changed, 81 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index e62b82e8ec..b2bb687a96 100644 --- a/pom.xml +++ b/pom.xml @@ -252,7 +252,7 @@ org.codehaus.groovy groovy - 2.1.2 + 2.1.3 org.eclipse.jetty diff --git a/spring-bootstrap-cli/samples/job.groovy b/spring-bootstrap-cli/samples/job.groovy index 6c917d764b..b3b7a47f9c 100644 --- a/spring-bootstrap-cli/samples/job.groovy +++ b/spring-bootstrap-cli/samples/job.groovy @@ -14,7 +14,12 @@ class JobConfig { @Bean protected Tasklet tasklet() { - return new SampleTasklet() + return new Tasklet() { + @Override + RepeatStatus execute(StepContribution contribution, ChunkContext context) { + return RepeatStatus.FINISHED + } + } } @Bean @@ -28,13 +33,6 @@ class JobConfig { } } -class SampleTasklet implements Tasklet { - @Override - RepeatStatus execute(StepContribution contribution, ChunkContext context) { - return RepeatStatus.FINISHED - } -} - import org.springframework.util.StringUtils import groovy.util.logging.Log diff --git a/spring-bootstrap-cli/src/main/java/org/springframework/bootstrap/cli/CleanCommand.java b/spring-bootstrap-cli/src/main/java/org/springframework/bootstrap/cli/CleanCommand.java index fdb4ba857f..4204043be1 100644 --- a/spring-bootstrap-cli/src/main/java/org/springframework/bootstrap/cli/CleanCommand.java +++ b/spring-bootstrap-cli/src/main/java/org/springframework/bootstrap/cli/CleanCommand.java @@ -34,6 +34,10 @@ import org.apache.ivy.util.FileUtil; */ public class CleanCommand extends OptionParsingCommand { + private static enum Layout { + IVY, MAVEN; + } + private OptionSpec allOption; public CleanCommand() { @@ -55,28 +59,18 @@ public class CleanCommand extends OptionParsingCommand { @Override protected void run(OptionSet options) throws Exception { + clean(options, getGrapesHome(options), Layout.IVY); + clean(options, getMavenHome(options), Layout.MAVEN); + } - String dir = System.getenv("GROOVY_HOME"); - String userdir = System.getProperty("user.home"); - - File home; - if (dir == null || !new File(dir).exists()) { - dir = userdir; - home = new File(dir, ".groovy"); - } else { - home = new File(dir); - } - if (dir == null || !new File(dir).exists()) { - return; - } + private void clean(OptionSet options, File root, Layout layout) { - if (!home.exists()) { + if (root == null || !root.exists()) { return; } - File grapes = new File(home, "grapes"); ArrayList specs = new ArrayList(options.nonOptionArguments()); - if (!specs.contains("org.springframework.bootstrap")) { + if (!specs.contains("org.springframework.bootstrap") && layout == Layout.IVY) { specs.add(0, "org.springframework.bootstrap"); } for (String spec : specs) { @@ -86,8 +80,7 @@ public class CleanCommand extends OptionParsingCommand { group = spec.substring(0, spec.indexOf(":")); module = spec.substring(spec.indexOf(":") + 1); } - File file = module == null ? new File(grapes, group) : new File(new File( - grapes, group), module); + File file = getModulePath(root, group, module, layout); if (file.exists()) { if (options.has(this.allOption) || group.equals("org.springframework.bootstrap")) { @@ -102,7 +95,52 @@ public class CleanCommand extends OptionParsingCommand { } } } + } + + private File getModulePath(File root, String group, String module, Layout layout) { + File parent = root; + if (layout == Layout.IVY) { + parent = new File(parent, group); + } else { + for (String path : group.split("\\.")) { + parent = new File(parent, path); + } + } + if (module == null) { + return parent; + } + return new File(parent, module); + } + + private File getGrapesHome(OptionSet options) { + + String dir = System.getenv("GROOVY_HOME"); + String userdir = System.getProperty("user.home"); + + File home; + if (dir == null || !new File(dir).exists()) { + dir = userdir; + home = new File(dir, ".groovy"); + } else { + home = new File(dir); + } + if (dir == null || !new File(dir).exists()) { + return null; + } + + File grapes = new File(home, "grapes"); + return grapes; } + private File getMavenHome(OptionSet options) { + String dir = System.getProperty("user.home"); + + if (dir == null || !new File(dir).exists()) { + return null; + } + File home = new File(dir); + File grapes = new File(new File(home, ".m2"), "repository"); + return grapes; + } } diff --git a/spring-bootstrap-cli/src/main/scripts/spring b/spring-bootstrap-cli/src/main/scripts/spring index 4efa9a19fa..65300773be 100755 --- a/spring-bootstrap-cli/src/main/scripts/spring +++ b/spring-bootstrap-cli/src/main/scripts/spring @@ -71,4 +71,4 @@ if $cygwin; then CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` fi -${JAVA_HOME}/bin/java -cp "$CLASSPATH" org.springframework.bootstrap.cli.SpringBootstrapCli $* \ No newline at end of file +${JAVA_HOME}/bin/java ${JAVA_OPTS} -cp "$CLASSPATH" org.springframework.bootstrap.cli.SpringBootstrapCli $* \ No newline at end of file diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/BeanDefinitionLoader.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/BeanDefinitionLoader.java index 611e7fb9d2..0305c1763d 100644 --- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/BeanDefinitionLoader.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/BeanDefinitionLoader.java @@ -116,8 +116,12 @@ class BeanDefinitionLoader { private int load(Object source) { Assert.notNull(source, "Source must not be null"); if (source instanceof Class) { - this.annotatedReader.register((Class) source); - return 1; + Class type = (Class) source; + if (isComponent(type)) { + this.annotatedReader.register(type); + return 1; + } + return 0; } if (source instanceof Resource) { @@ -149,6 +153,15 @@ class BeanDefinitionLoader { throw new IllegalArgumentException("Invalid source '" + source + "'"); } + private boolean isComponent(Class type) { + // Nested anonymous classes are not eligible for registration, nor are groovy + // closures + if (type.isAnonymousClass() || type.getName().contains("$_closure")) { + return false; + } + return true; + } + /** * Simple {@link TypeFilter} used to ensure that specified {@link Class} sources are * not accidentally re-added during scanning. diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/SpringApplication.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/SpringApplication.java index e1344f4933..7572bfff2b 100644 --- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/SpringApplication.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/SpringApplication.java @@ -297,11 +297,11 @@ public class SpringApplication { } } - if (context instanceof AbstractApplicationContext) { + if (context instanceof AbstractApplicationContext && this.environment != null) { ((AbstractApplicationContext) context).setEnvironment(this.environment); } - if (context instanceof GenericApplicationContext) { + if (context instanceof GenericApplicationContext && this.resourceLoader != null) { ((GenericApplicationContext) context).setResourceLoader(this.resourceLoader); } }