From 0d78323b600b89ffe8b5f0d55e74f49cd43539c7 Mon Sep 17 00:00:00 2001 From: Liuzh Date: Fri, 20 May 2022 08:37:33 +0800 Subject: [PATCH 1/2] Resolve errors in layers.xsd Update `layer-*.xsd` files with following fixes: - Rename to - Rename to See gh-31126 --- .../spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd | 4 ++-- .../spring-boot-maven-plugin/src/main/xsd/layers-2.5.xsd | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd index 57eac0d6b9..464ef34d31 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd @@ -78,14 +78,14 @@ - + - + - + - + Date: Thu, 19 May 2022 17:34:57 -0700 Subject: [PATCH 2/2] Polish "Resolve errors in layers.xsd" Validate loaded `layer.xml` files against the XSD and additionally update `` sub elements to have a 'minOccurs' of 0. See gh-31126 --- .../spring-boot-maven-plugin/build.gradle | 17 ++++++++-- .../boot/maven/AbstractPackagerMojo.java | 3 +- .../boot/maven/CustomLayersProvider.java | 32 ++++++++++++++++++- .../src/main/xsd/layers-2.3.xsd | 6 ++-- .../src/main/xsd/layers-2.4.xsd | 8 ++--- .../src/main/xsd/layers-2.5.xsd | 8 ++--- .../boot/maven/CustomLayersProviderTests.java | 3 +- 7 files changed, 61 insertions(+), 16 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle index a8e7b881fb..f220f448eb 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle @@ -64,6 +64,11 @@ dependencies { versionProperties(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "effectiveBom")) } +ext { + versionElements = version.split("\\.") + xsdVersion = versionElements[0] + "." + versionElements[1] +} + syncDocumentationSourceForAsciidoctor { from(documentPluginGoals) { into "asciidoc/goals" @@ -71,6 +76,9 @@ syncDocumentationSourceForAsciidoctor { } sourceSets { + main { + output.dir("${buildDir}/generated/resources/xsd", builtBy: "xsdResources") + } intTest { output.dir("${buildDir}/generated-resources", builtBy: "extractVersionProperties") } @@ -78,8 +86,7 @@ sourceSets { tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) { doFirst { - def versionEl = version.split("\\.") - attributes "spring-boot-xsd-version": versionEl[0] + '.' + versionEl[1] + attributes "spring-boot-xsd-version" : project.ext.xsdVersion } } @@ -129,6 +136,12 @@ task zip(type: Zip) { } } +task xsdResources(type: Sync) { + from "src/main/xsd/layers-${project.ext.xsdVersion}.xsd" + into "${buildDir}/generated/resources/xsd/org/springframework/boot/maven" + rename { fileName -> "layers.xsd" } +} + prepareMavenBinaries { versions "3.8.1", "3.6.3", "3.5.4" } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java index 3ce19bf4c1..82ff6455e4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 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. @@ -171,6 +171,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo private Document getDocumentIfAvailable(File xmlFile) throws Exception { InputSource inputSource = new InputSource(new FileInputStream(xmlFile)); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); return builder.parse(inputSource); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java index 5d01b34caa..2889520bd4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 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,24 @@ package org.springframework.boot.maven; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; +import javax.xml.XMLConstants; +import javax.xml.transform.dom.DOMSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; import org.springframework.boot.loader.tools.Layer; import org.springframework.boot.loader.tools.Library; @@ -45,6 +53,7 @@ import org.springframework.boot.loader.tools.layer.LibraryContentFilter; class CustomLayersProvider { CustomLayers getLayers(Document document) { + validate(document); Element root = document.getDocumentElement(); List> applicationSelectors = getApplicationSelectors(root); List> librarySelectors = getLibrarySelectors(root); @@ -52,6 +61,27 @@ class CustomLayersProvider { return new CustomLayers(layers, applicationSelectors, librarySelectors); } + private void validate(Document document) { + Schema schema = loadSchema(); + try { + Validator validator = schema.newValidator(); + validator.validate(new DOMSource(document)); + } + catch (SAXException | IOException ex) { + throw new IllegalStateException("Invalid layers.xml configuration", ex); + } + } + + private Schema loadSchema() { + try { + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + return factory.newSchema(getClass().getResource("layers.xsd")); + } + catch (SAXException ex) { + throw new IllegalStateException("Unable to load layers XSD"); + } + } + private List> getApplicationSelectors(Element root) { return getSelectors(root, "application", (element) -> getSelector(element, ApplicationContentFilter::new)); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.3.xsd b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.3.xsd index 01eca01439..c5c6858651 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.3.xsd +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.3.xsd @@ -6,9 +6,9 @@ - - - + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd index 464ef34d31..20219b9bd8 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd @@ -6,9 +6,9 @@ - - - + + + @@ -92,7 +92,7 @@ ]]> - + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.5.xsd b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.5.xsd index 464ef34d31..20219b9bd8 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.5.xsd +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.5.xsd @@ -6,9 +6,9 @@ - - - + + + @@ -92,7 +92,7 @@ ]]> - + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/CustomLayersProviderTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/CustomLayersProviderTests.java index 5e5bceaea2..e9b9f2bc49 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/CustomLayersProviderTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/CustomLayersProviderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 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. @@ -97,6 +97,7 @@ class CustomLayersProviderTests { ClassPathResource resource = new ClassPathResource(resourceName); InputSource inputSource = new InputSource(resource.getInputStream()); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); DocumentBuilder documentBuilder = factory.newDocumentBuilder(); return documentBuilder.parse(inputSource); }