diff --git a/spring-boot-integration-tests/src/test/java/org/springframework/boot/gradle/WarPackagingTests.java b/spring-boot-integration-tests/src/test/java/org/springframework/boot/gradle/WarPackagingTests.java new file mode 100644 index 00000000000..2900f1a6295 --- /dev/null +++ b/spring-boot-integration-tests/src/test/java/org/springframework/boot/gradle/WarPackagingTests.java @@ -0,0 +1,145 @@ +/* + * Copyright 2012-2014 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.gradle; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.gradle.tooling.ProjectConnection; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.boot.dependency.tools.ManagedDependencies; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Tests for war packaging with Gradle to ensure that only the Servlet container and its + * dependencies are packaged in WEB-INF/lib-provided + * + * @author Andy Wilkinson + */ +public class WarPackagingTests { + + private static final String WEB_INF_LIB_PROVIDED_PREFIX = "WEB-INF/lib-provided/"; + + private static final Set TOMCAT_EXPECTED_IN_WEB_INF_LIB_PROVIDED = new HashSet( + Arrays.asList(WEB_INF_LIB_PROVIDED_PREFIX + "spring-boot-starter-tomcat-", + WEB_INF_LIB_PROVIDED_PREFIX + "tomcat-embed-core-", + WEB_INF_LIB_PROVIDED_PREFIX + "tomcat-embed-el-", + WEB_INF_LIB_PROVIDED_PREFIX + "tomcat-embed-logging-juli-")); + + private static final Set JETTY_EXPECTED_IN_WEB_INF_LIB_PROVIDED = new HashSet( + Arrays.asList(WEB_INF_LIB_PROVIDED_PREFIX + "spring-boot-starter-jetty-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-util-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-xml-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-continuation-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-io-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-http-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-server-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-security-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-servlet-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-webapp-", + WEB_INF_LIB_PROVIDED_PREFIX + "javax.servlet.jsp-", + WEB_INF_LIB_PROVIDED_PREFIX + "org.apache.jasper.glassfish-", + WEB_INF_LIB_PROVIDED_PREFIX + "javax.servlet.jsp.jstl-", + WEB_INF_LIB_PROVIDED_PREFIX + + "org.apache.taglibs.standard.glassfish-", + WEB_INF_LIB_PROVIDED_PREFIX + "javax.el-", + WEB_INF_LIB_PROVIDED_PREFIX + "com.sun.el-", + WEB_INF_LIB_PROVIDED_PREFIX + "org.eclipse.jdt.core-", + WEB_INF_LIB_PROVIDED_PREFIX + "jetty-jsp-")); + + private static final String BOOT_VERSION = ManagedDependencies.get() + .find("spring-boot").getVersion(); + + private static ProjectConnection project; + + @BeforeClass + public static void createProject() throws IOException { + project = new ProjectCreator().createProject("war-packaging"); + } + + @Test + public void onlyTomcatIsPackackedInWebInfLibProvided() throws IOException { + checkWebInfLibProvidedEntriesForServletContainer("tomcat", + TOMCAT_EXPECTED_IN_WEB_INF_LIB_PROVIDED); + } + + @Test + public void onlyJettyIsPackackedInWebInfLibProvided() throws IOException { + checkWebInfLibProvidedEntriesForServletContainer("jetty", + JETTY_EXPECTED_IN_WEB_INF_LIB_PROVIDED); + } + + private void checkWebInfLibProvidedEntriesForServletContainer( + String servletContainer, Set expectedEntries) throws IOException { + project.newBuild() + .forTasks("clean", "build") + .withArguments("-PbootVersion=" + BOOT_VERSION, + "-PservletContainer=" + servletContainer).run(); + + JarFile war = new JarFile("target/war-packaging/build/libs/war-packaging.war"); + Set entries = getWebInfLibProvidedEntries(war); + + assertEquals( + "Expected " + expectedEntries.size() + " but found " + entries.size() + + ": " + entries, expectedEntries.size(), entries.size()); + + List unexpectedLibProvidedEntries = new ArrayList(); + for (String entry : entries) { + if (!isExpectedInWebInfLibProvided(entry, expectedEntries)) { + unexpectedLibProvidedEntries.add(entry); + } + } + assertTrue("Found unexpected entries in WEB-INF/lib-provided: " + + unexpectedLibProvidedEntries, unexpectedLibProvidedEntries.isEmpty()); + } + + private Set getWebInfLibProvidedEntries(JarFile war) throws IOException { + Set webInfLibProvidedEntries = new HashSet(); + Enumeration entries = war.entries(); + while (entries.hasMoreElements()) { + String name = entries.nextElement().getName(); + if (isWebInfLibProvidedEntry(name)) { + webInfLibProvidedEntries.add(name); + } + } + return webInfLibProvidedEntries; + } + + private boolean isWebInfLibProvidedEntry(String name) { + return name.startsWith(WEB_INF_LIB_PROVIDED_PREFIX) + && !name.equals(WEB_INF_LIB_PROVIDED_PREFIX); + } + + private boolean isExpectedInWebInfLibProvided(String name, Set expectedEntries) { + for (String expected : expectedEntries) { + if (name.startsWith(expected)) { + return true; + } + } + return false; + } +} diff --git a/spring-boot-integration-tests/src/test/resources/war-packaging.gradle b/spring-boot-integration-tests/src/test/resources/war-packaging.gradle new file mode 100644 index 00000000000..9ff8591d007 --- /dev/null +++ b/spring-boot-integration-tests/src/test/resources/war-packaging.gradle @@ -0,0 +1,27 @@ +import org.gradle.api.artifacts.result.UnresolvedDependencyResult; + +buildscript { + repositories { + mavenLocal() + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}" + } +} + +repositories { + mavenLocal() + mavenCentral() +} + +apply plugin: 'spring-boot' +apply plugin: 'war' + +dependencies { + compile 'org.springframework.boot:spring-boot-starter-freemarker' + providedRuntime "org.springframework.boot:spring-boot-starter-$servletContainer" +} + +springBoot { + mainClass = 'foo.bar.Baz' +} \ No newline at end of file