From 65acaf885ba8015705e3e478ec11ec293ad5134c Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Thu, 15 Jan 2015 15:38:24 -0800 Subject: [PATCH 1/2] Remove incorrect assumption that output will be in folder named classes When running in Eclipse, by default Gradle builds its output into a folder named bin. This commit update the annotation processor to remove the failure assumption that the output will always be located beneath a folder named classes. Closes gh-2369 See gh-2361 --- .../ConfigurationMetadataAnnotationProcessor.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java index 304f87fd19..cd8812c02b 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -393,9 +393,11 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor // Gradle keeps things separate String path = file.getPath(); int index = path.lastIndexOf(CLASSES_FOLDER); - path = path.substring(0, index) + RESOURCES_FOLDER - + path.substring(index + CLASSES_FOLDER.length()); - file = new File(path); + if (index >= 0) { + path = path.substring(0, index) + RESOURCES_FOLDER + + path.substring(index + CLASSES_FOLDER.length()); + file = new File(path); + } } return (file.exists() ? new FileInputStream(file) : fileObject.toUri().toURL() .openStream()); From 606ea4979a07f5a081aab2a6c9c9e1d638f76c72 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 21 Jan 2015 11:18:32 +0000 Subject: [PATCH 2/2] Add a test to cover the merging of an additional metadata file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test covers the code path that caused gh-2361 and also checks that, when an additional metadata file is found, it’s correctly merged with the other metadata. Closes gh-2361 --- ...ationMetadataAnnotationProcessorTests.java | 73 ++++++++++++++++++- .../configurationprocessor/TestCompiler.java | 12 ++- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java index a63da50f01..e898ef8ad4 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -16,16 +16,23 @@ package org.springframework.boot.configurationprocessor; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; import java.io.IOException; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; +import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller; import org.springframework.boot.configurationsample.lombok.LombokExplicitProperties; import org.springframework.boot.configurationsample.lombok.LombokSimpleDataProperties; import org.springframework.boot.configurationsample.lombok.LombokSimpleProperties; @@ -59,12 +66,20 @@ import static org.springframework.boot.configurationprocessor.ConfigurationMetad * * @author Stephane Nicoll * @author Phillip Webb + * @author Andy Wilkinson */ public class ConfigurationMetadataAnnotationProcessorTests { @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); + private TestCompiler compiler; + + @Before + public void createCompiler() throws IOException { + this.compiler = new TestCompiler(this.temporaryFolder); + } + @Test public void notAnnotated() throws Exception { ConfigurationMetadata metadata = compile(NotAnnotated.class); @@ -307,6 +322,36 @@ public class ConfigurationMetadataAnnotationProcessorTests { assertSimpleLombokProperties(metadata, LombokExplicitProperties.class, "explicit"); } + @Test + public void mergingOfAdditionalMetadata() throws Exception { + File metaInfFolder = new File(this.compiler.getOutputLocation(), "META-INF"); + metaInfFolder.mkdirs(); + File additionalMetadataFile = new File(metaInfFolder, + "additional-spring-configuration-metadata.json"); + additionalMetadataFile.createNewFile(); + + JSONObject property = new JSONObject(); + property.put("name", "foo"); + property.put("type", "java.lang.String"); + property.put("sourceType", AdditionalMetadata.class.getName()); + JSONArray properties = new JSONArray(); + properties.put(property); + JSONObject additionalMetadata = new JSONObject(); + additionalMetadata.put("properties", properties); + FileWriter writer = new FileWriter(additionalMetadataFile); + additionalMetadata.write(writer); + writer.flush(); + + ConfigurationMetadata metadata = compile(SimpleProperties.class); + + assertThat(metadata, containsProperty("simple.comparator")); + + assertThat(metadata, + containsProperty("foo", String.class) + .fromSource(AdditionalMetadata.class)); + + } + private void assertSimpleLombokProperties(ConfigurationMetadata metadata, Class source, String prefix) { assertThat(metadata, containsGroup(prefix).fromSource(source)); @@ -324,13 +369,13 @@ public class ConfigurationMetadataAnnotationProcessorTests { private ConfigurationMetadata compile(Class... types) throws IOException { TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(); - new TestCompiler(this.temporaryFolder).getTask(types).call(processor); + this.compiler.getTask(types).call(processor); return processor.getMetadata(); } @SupportedAnnotationTypes({ "*" }) @SupportedSourceVersion(SourceVersion.RELEASE_6) - private static class TestConfigurationMetadataAnnotationProcessor extends + private class TestConfigurationMetadataAnnotationProcessor extends ConfigurationMetadataAnnotationProcessor { static final String CONFIGURATION_PROPERTIES_ANNOTATION = "org.springframework.boot.configurationsample.ConfigurationProperties"; @@ -351,7 +396,23 @@ public class ConfigurationMetadataAnnotationProcessorTests { @Override protected void writeMetaData(ConfigurationMetadata metadata) { - this.metadata = metadata; + super.writeMetaData(metadata); + try { + File metadataFile = new File( + ConfigurationMetadataAnnotationProcessorTests.this.compiler + .getOutputLocation(), + "META-INF/spring-configuration-metadata.json"); + if (metadataFile.isFile()) { + this.metadata = new JsonMarshaller().read(new FileInputStream( + metadataFile)); + } + else { + this.metadata = metadata; + } + } + catch (IOException e) { + throw new RuntimeException("Failed to read metadata from disk", e); + } } public ConfigurationMetadata getMetadata() { @@ -360,4 +421,8 @@ public class ConfigurationMetadataAnnotationProcessorTests { } + private static class AdditionalMetadata { + + } + } diff --git a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestCompiler.java b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestCompiler.java index b10d0ece5d..871fd88b87 100644 --- a/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestCompiler.java +++ b/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -35,6 +35,7 @@ import org.junit.rules.TemporaryFolder; * * @author Stephane Nicoll * @author Phillip Webb + * @author Andy Wilkinson */ public class TestCompiler { @@ -42,6 +43,8 @@ public class TestCompiler { private final StandardJavaFileManager fileManager; + private final File outputLocation; + public TestCompiler(TemporaryFolder temporaryFolder) throws IOException { this(ToolProvider.getSystemJavaCompiler(), temporaryFolder); } @@ -50,7 +53,8 @@ public class TestCompiler { throws IOException { this.compiler = compiler; this.fileManager = compiler.getStandardFileManager(null, null, null); - Iterable temp = Arrays.asList(temporaryFolder.newFolder()); + this.outputLocation = temporaryFolder.newFolder(); + Iterable temp = Arrays.asList(this.outputLocation); this.fileManager.setLocation(StandardLocation.CLASS_OUTPUT, temp); this.fileManager.setLocation(StandardLocation.SOURCE_OUTPUT, temp); } @@ -61,6 +65,10 @@ public class TestCompiler { null, null, null, javaFileObjects)); } + public File getOutputLocation() { + return this.outputLocation; + } + private Iterable getJavaFileObjects(Class... types) { File[] files = new File[types.length]; for (int i = 0; i < types.length; i++) {