Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
68af8310
Commit
68af8310
authored
Mar 01, 2017
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '1.4.x' into 1.5.x
parents
e36a60dc
b443b745
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1112 additions
and
42 deletions
+1112
-42
pom.xml
spring-boot-integration-tests/pom.xml
+1
-0
pom.xml
...boot-integration-tests-embedded-servlet-container/pom.xml
+66
-0
ResourceHandlingApplication.java
...rc/test/java/com/example/ResourceHandlingApplication.java
+72
-0
AbstractApplicationLauncher.java
...rk/boot/context/embedded/AbstractApplicationLauncher.java
+96
-0
AbstractEmbeddedServletContainerIntegrationTests.java
...ded/AbstractEmbeddedServletContainerIntegrationTests.java
+110
-0
ApplicationBuilder.java
...ngframework/boot/context/embedded/ApplicationBuilder.java
+159
-0
EmbeddedServletContainerJarPackagingIntegrationTests.java
...EmbeddedServletContainerJarPackagingIntegrationTests.java
+85
-0
EmbeddedServletContainerWarPackagingIntegrationTests.java
...EmbeddedServletContainerWarPackagingIntegrationTests.java
+85
-0
ExplodedApplicationLauncher.java
...rk/boot/context/embedded/ExplodedApplicationLauncher.java
+78
-0
PackagedApplicationLauncher.java
...rk/boot/context/embedded/PackagedApplicationLauncher.java
+40
-0
Versions.java
...a/org/springframework/boot/context/embedded/Versions.java
+56
-0
pom-template.xml
...ded-servlet-container/src/test/resources/pom-template.xml
+68
-0
AbstractEmbeddedServletContainerFactory.java
...ext/embedded/AbstractEmbeddedServletContainerFactory.java
+29
-0
JettyEmbeddedServletContainerFactory.java
.../embedded/jetty/JettyEmbeddedServletContainerFactory.java
+16
-8
TomcatEmbeddedServletContainerFactory.java
...mbedded/tomcat/TomcatEmbeddedServletContainerFactory.java
+13
-3
TomcatResources.java
...amework/boot/context/embedded/tomcat/TomcatResources.java
+12
-24
CompositeResourceManager.java
...t/context/embedded/undertow/CompositeResourceManager.java
+74
-0
UndertowEmbeddedServletContainerFactory.java
...ded/undertow/UndertowEmbeddedServletContainerFactory.java
+52
-7
No files found.
spring-boot-integration-tests/pom.xml
View file @
68af8310
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
</properties>
</properties>
<modules>
<modules>
<module>
spring-boot-devtools-tests
</module>
<module>
spring-boot-devtools-tests
</module>
<module>
spring-boot-integration-tests-embedded-servlet-container
</module>
<module>
spring-boot-gradle-tests
</module>
<module>
spring-boot-gradle-tests
</module>
<module>
spring-boot-launch-script-tests
</module>
<module>
spring-boot-launch-script-tests
</module>
<module>
spring-boot-security-tests
</module>
<module>
spring-boot-security-tests
</module>
...
...
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/pom.xml
0 → 100644
View file @
68af8310
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-integration-tests
</artifactId>
<version>
1.5.2.BUILD-SNAPSHOT
</version>
</parent>
<artifactId>
spring-boot-integration-tests-embedded-servlet-container
</artifactId>
<packaging>
jar
</packaging>
<name>
Spring Boot Embedded Servlet Container Integration Tests
</name>
<url>
http://projects.spring.io/spring-boot/
</url>
<organization>
<name>
Pivotal Software, Inc.
</name>
<url>
http://www.spring.io
</url>
</organization>
<properties>
<main.basedir>
${basedir}/../..
</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-logging
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
com.samskivert
</groupId>
<artifactId>
jmustache
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
javax.servlet
</groupId>
<artifactId>
javax.servlet-api
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.apache.maven.shared
</groupId>
<artifactId>
maven-invoker
</artifactId>
<version>
3.0.0
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-web
</artifactId>
<scope>
test
</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-surefire-plugin
</artifactId>
<configuration>
<systemPropertyVariables>
<maven.home>
${maven.home}
</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/com/example/ResourceHandlingApplication.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
com
.
example
;
import
java.io.IOException
;
import
java.net.URL
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServlet
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.builder.SpringApplicationBuilder
;
import
org.springframework.boot.system.EmbeddedServerPortFileWriter
;
import
org.springframework.boot.web.servlet.ServletRegistrationBean
;
import
org.springframework.context.annotation.Bean
;
/**
* Test application for verifying an embedded container's static resource handling.
*
* @author Andy Wilkinson
*/
@SpringBootApplication
public
class
ResourceHandlingApplication
{
public
static
void
main
(
String
[]
args
)
{
new
SpringApplicationBuilder
(
ResourceHandlingApplication
.
class
)
.
properties
(
"server.port:0"
)
.
listeners
(
new
EmbeddedServerPortFileWriter
(
"target/server.port"
))
.
run
(
args
);
}
@Bean
public
ServletRegistrationBean
resourceServletRegistration
()
{
ServletRegistrationBean
registration
=
new
ServletRegistrationBean
(
new
HttpServlet
()
{
@Override
protected
void
doGet
(
HttpServletRequest
req
,
HttpServletResponse
resp
)
throws
ServletException
,
IOException
{
URL
resource
=
getServletContext
()
.
getResource
(
req
.
getQueryString
());
if
(
resource
==
null
)
{
resp
.
sendError
(
404
);
}
else
{
resp
.
getWriter
().
println
(
resource
);
resp
.
getWriter
().
flush
();
}
}
});
registration
.
addUrlMappings
(
"/servletContext"
);
return
registration
;
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/AbstractApplicationLauncher.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
.
context
.
embedded
;
import
java.io.File
;
import
java.io.FileReader
;
import
java.lang.ProcessBuilder.Redirect
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.junit.rules.ExternalResource
;
import
org.springframework.util.FileCopyUtils
;
/**
* Base {@link ExternalResource} for launching a Spring Boot application as part of a
* JUnit test.
*
* @author Andy Wilkinson
*/
abstract
class
AbstractApplicationLauncher
extends
ExternalResource
{
private
final
File
serverPortFile
=
new
File
(
"target/server.port"
);
private
final
ApplicationBuilder
applicationBuilder
;
private
Process
process
;
private
int
httpPort
;
protected
AbstractApplicationLauncher
(
ApplicationBuilder
applicationBuilder
)
{
this
.
applicationBuilder
=
applicationBuilder
;
}
@Override
protected
final
void
before
()
throws
Throwable
{
this
.
process
=
startApplication
();
}
@Override
protected
final
void
after
()
{
this
.
process
.
destroy
();
}
public
final
int
getHttpPort
()
{
return
this
.
httpPort
;
}
protected
abstract
List
<
String
>
getArguments
(
File
archive
);
private
Process
startApplication
()
throws
Exception
{
this
.
serverPortFile
.
delete
();
File
archive
=
this
.
applicationBuilder
.
buildApplication
();
List
<
String
>
arguments
=
new
ArrayList
<
String
>();
arguments
.
add
(
System
.
getProperty
(
"java.home"
)
+
"/bin/java"
);
arguments
.
addAll
(
getArguments
(
archive
));
ProcessBuilder
processBuilder
=
new
ProcessBuilder
(
arguments
.
toArray
(
new
String
[
arguments
.
size
()]));
processBuilder
.
redirectOutput
(
Redirect
.
INHERIT
);
processBuilder
.
redirectError
(
Redirect
.
INHERIT
);
Process
process
=
processBuilder
.
start
();
this
.
httpPort
=
awaitServerPort
(
process
);
return
process
;
}
private
int
awaitServerPort
(
Process
process
)
throws
Exception
{
long
end
=
System
.
currentTimeMillis
()
+
30000
;
while
(
this
.
serverPortFile
.
length
()
==
0
)
{
if
(
System
.
currentTimeMillis
()
>
end
)
{
throw
new
IllegalStateException
(
"server.port file was not written within 30 seconds"
);
}
if
(!
process
.
isAlive
())
{
throw
new
IllegalStateException
(
"Application failed to launch"
);
}
Thread
.
sleep
(
100
);
}
return
Integer
.
parseInt
(
FileCopyUtils
.
copyToString
(
new
FileReader
(
this
.
serverPortFile
)));
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerIntegrationTests.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
.
context
.
embedded
;
import
java.io.IOException
;
import
java.net.URI
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
org.codehaus.plexus.util.StringUtils
;
import
org.junit.ClassRule
;
import
org.junit.Rule
;
import
org.junit.rules.TemporaryFolder
;
import
org.springframework.http.client.ClientHttpResponse
;
import
org.springframework.web.client.ResponseErrorHandler
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.util.UriTemplateHandler
;
/**
* Base class for embedded servlet container integration tests.
*
* @author Andy Wilkinson
*/
public
abstract
class
AbstractEmbeddedServletContainerIntegrationTests
{
@ClassRule
public
static
final
TemporaryFolder
temporaryFolder
=
new
TemporaryFolder
();
@Rule
public
final
AbstractApplicationLauncher
launcher
;
protected
final
RestTemplate
rest
=
new
RestTemplate
();
public
static
Object
[]
parameters
(
String
packaging
)
{
List
<
Object
>
parameters
=
new
ArrayList
<
Object
>();
parameters
.
addAll
(
createParameters
(
packaging
,
"jetty"
,
"current"
));
parameters
.
addAll
(
createParameters
(
packaging
,
"tomcat"
,
"current"
,
"8.0.41"
,
"7.0.75"
));
parameters
.
addAll
(
createParameters
(
packaging
,
"undertow"
,
"current"
));
return
parameters
.
toArray
(
new
Object
[
parameters
.
size
()]);
}
private
static
List
<
Object
>
createParameters
(
String
packaging
,
String
container
,
String
...
versions
)
{
List
<
Object
>
parameters
=
new
ArrayList
<
Object
>();
for
(
String
version
:
versions
)
{
ApplicationBuilder
applicationBuilder
=
new
ApplicationBuilder
(
temporaryFolder
,
packaging
,
container
,
version
);
parameters
.
add
(
new
Object
[]
{
StringUtils
.
capitalise
(
container
)
+
" "
+
version
+
" packaged "
+
packaging
,
new
PackagedApplicationLauncher
(
applicationBuilder
)
});
parameters
.
add
(
new
Object
[]
{
StringUtils
.
capitalise
(
container
)
+
" "
+
version
+
" exploded "
+
packaging
,
new
ExplodedApplicationLauncher
(
applicationBuilder
)
});
}
return
parameters
;
}
protected
AbstractEmbeddedServletContainerIntegrationTests
(
String
name
,
AbstractApplicationLauncher
launcher
)
{
this
.
launcher
=
launcher
;
this
.
rest
.
setErrorHandler
(
new
ResponseErrorHandler
()
{
@Override
public
boolean
hasError
(
ClientHttpResponse
response
)
throws
IOException
{
return
false
;
}
@Override
public
void
handleError
(
ClientHttpResponse
response
)
throws
IOException
{
}
});
this
.
rest
.
setUriTemplateHandler
(
new
UriTemplateHandler
()
{
@Override
public
URI
expand
(
String
uriTemplate
,
Object
...
uriVariables
)
{
return
URI
.
create
(
"http://localhost:"
+
launcher
.
getHttpPort
()
+
uriTemplate
);
}
@Override
public
URI
expand
(
String
uriTemplate
,
Map
<
String
,
?>
uriVariables
)
{
return
URI
.
create
(
"http://localhost:"
+
launcher
.
getHttpPort
()
+
uriTemplate
);
}
});
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/ApplicationBuilder.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2016 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
.
context
.
embedded
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileOutputStream
;
import
java.io.FileReader
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.jar.JarOutputStream
;
import
java.util.zip.ZipEntry
;
import
com.samskivert.mustache.Mustache
;
import
org.apache.maven.shared.invoker.DefaultInvocationRequest
;
import
org.apache.maven.shared.invoker.DefaultInvoker
;
import
org.apache.maven.shared.invoker.InvocationRequest
;
import
org.apache.maven.shared.invoker.InvocationResult
;
import
org.apache.maven.shared.invoker.MavenInvocationException
;
import
org.junit.rules.TemporaryFolder
;
import
org.springframework.util.FileCopyUtils
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Builds a Spring Boot application using Maven. To use this class, the {@code maven.home}
* system property must be set.
*
* @author Andy Wilkinson
*/
class
ApplicationBuilder
{
private
final
TemporaryFolder
temp
;
private
final
String
packaging
;
private
final
String
container
;
private
final
String
containerVersion
;
ApplicationBuilder
(
TemporaryFolder
temp
,
String
packaging
,
String
container
,
String
containerVersion
)
{
this
.
temp
=
temp
;
this
.
packaging
=
packaging
;
this
.
container
=
container
;
this
.
containerVersion
=
containerVersion
;
}
File
buildApplication
()
throws
Exception
{
File
containerFolder
=
new
File
(
this
.
temp
.
getRoot
(),
this
.
container
+
"-"
+
this
.
containerVersion
);
if
(
containerFolder
.
exists
())
{
return
new
File
(
containerFolder
,
"app/target/app-0.0.1."
+
this
.
packaging
);
}
return
doBuildApplication
(
containerFolder
);
}
private
File
doBuildApplication
(
File
containerFolder
)
throws
IOException
,
FileNotFoundException
,
MavenInvocationException
{
File
resourcesJar
=
createResourcesJar
();
File
appFolder
=
new
File
(
containerFolder
,
"app"
);
appFolder
.
mkdirs
();
writePom
(
appFolder
,
resourcesJar
);
copyApplicationSource
(
appFolder
);
packageApplication
(
appFolder
);
return
new
File
(
appFolder
,
"target/app-0.0.1."
+
this
.
packaging
);
}
private
File
createResourcesJar
()
throws
IOException
,
FileNotFoundException
{
File
resourcesJar
=
new
File
(
this
.
temp
.
getRoot
(),
"resources.jar"
);
if
(
resourcesJar
.
exists
())
{
return
resourcesJar
;
}
JarOutputStream
resourcesJarStream
=
new
JarOutputStream
(
new
FileOutputStream
(
resourcesJar
));
resourcesJarStream
.
putNextEntry
(
new
ZipEntry
(
"META-INF/resources/"
));
resourcesJarStream
.
closeEntry
();
resourcesJarStream
.
putNextEntry
(
new
ZipEntry
(
"META-INF/resources/nested-meta-inf-resource.txt"
));
resourcesJarStream
.
write
(
"nested"
.
getBytes
());
resourcesJarStream
.
closeEntry
();
resourcesJarStream
.
close
();
return
resourcesJar
;
}
private
void
writePom
(
File
appFolder
,
File
resourcesJar
)
throws
FileNotFoundException
,
IOException
{
Map
<
String
,
Object
>
context
=
new
HashMap
<
String
,
Object
>();
context
.
put
(
"packaging"
,
this
.
packaging
);
context
.
put
(
"container"
,
this
.
container
);
context
.
put
(
"bootVersion"
,
Versions
.
getBootVersion
());
context
.
put
(
"resourcesJarPath"
,
resourcesJar
.
getAbsolutePath
());
context
.
put
(
"containerVersion"
,
"current"
.
equals
(
this
.
containerVersion
)
?
""
:
String
.
format
(
"<%s.version>%s</%s.version>"
,
this
.
container
,
this
.
containerVersion
,
this
.
container
));
context
.
put
(
"additionalDependencies"
,
getAdditionalDependencies
());
FileWriter
out
=
new
FileWriter
(
new
File
(
appFolder
,
"pom.xml"
));
Mustache
.
compiler
().
escapeHTML
(
false
)
.
compile
(
new
FileReader
(
"src/test/resources/pom-template.xml"
))
.
execute
(
context
,
out
);
out
.
close
();
}
private
List
<
Map
<
String
,
String
>>
getAdditionalDependencies
()
{
List
<
Map
<
String
,
String
>>
additionalDependencies
=
new
ArrayList
<
Map
<
String
,
String
>>();
if
(
"tomcat"
.
equals
(
this
.
container
)
&&
!
"current"
.
equals
(
this
.
containerVersion
))
{
Map
<
String
,
String
>
juli
=
new
HashMap
<
String
,
String
>();
juli
.
put
(
"groupId"
,
"org.apache.tomcat"
);
juli
.
put
(
"artifactId"
,
"tomcat-juli"
);
juli
.
put
(
"version"
,
"${tomcat.version}"
);
additionalDependencies
.
add
(
juli
);
}
return
additionalDependencies
;
}
private
void
copyApplicationSource
(
File
appFolder
)
throws
IOException
{
File
examplePackage
=
new
File
(
appFolder
,
"src/main/java/com/example"
);
examplePackage
.
mkdirs
();
FileCopyUtils
.
copy
(
new
File
(
"src/test/java/com/example/ResourceHandlingApplication.java"
),
new
File
(
examplePackage
,
"ResourceHandlingApplication.java"
));
if
(
"war"
.
equals
(
this
.
packaging
))
{
File
srcMainWebapp
=
new
File
(
appFolder
,
"src/main/webapp"
);
srcMainWebapp
.
mkdirs
();
FileCopyUtils
.
copy
(
"webapp resource"
,
new
FileWriter
(
new
File
(
srcMainWebapp
,
"webapp-resource.txt"
)));
}
}
private
void
packageApplication
(
File
appFolder
)
throws
MavenInvocationException
{
InvocationRequest
invocation
=
new
DefaultInvocationRequest
();
invocation
.
setBaseDirectory
(
appFolder
);
invocation
.
setGoals
(
Collections
.
singletonList
(
"package"
));
InvocationResult
execute
=
new
DefaultInvoker
().
execute
(
invocation
);
assertThat
(
execute
.
getExitCode
()).
isEqualTo
(
0
);
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/EmbeddedServletContainerJarPackagingIntegrationTests.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
.
context
.
embedded
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Parameterized
;
import
org.junit.runners.Parameterized.Parameters
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Integration tests for Spring Boot's embedded servlet container support using jar
* packaging.
*
* @author Andy Wilkinson
*/
@RunWith
(
Parameterized
.
class
)
public
class
EmbeddedServletContainerJarPackagingIntegrationTests
extends
AbstractEmbeddedServletContainerIntegrationTests
{
@Parameters
(
name
=
"{0}"
)
public
static
Object
[]
parameters
()
{
return
AbstractEmbeddedServletContainerIntegrationTests
.
parameters
(
"jar"
);
}
public
EmbeddedServletContainerJarPackagingIntegrationTests
(
String
name
,
AbstractApplicationLauncher
launcher
)
{
super
(
name
,
launcher
);
}
@Test
public
void
nestedMetaInfResourceIsAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/nested-meta-inf-resource.txt"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
@Test
public
void
nestedMetaInfResourceIsAvailableViaServletContext
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/nested-meta-inf-resource.txt"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
@Test
public
void
nestedJarIsNotAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/BOOT-INF/lib/resources-1.0.jar"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
NOT_FOUND
);
}
@Test
public
void
applicationClassesAreNotAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/BOOT-INF/classes/com/example/ResourceHandlingApplication.class"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
NOT_FOUND
);
}
@Test
public
void
launcherIsNotAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/org/springframework/boot/loader/Launcher.class"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
NOT_FOUND
);
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/EmbeddedServletContainerWarPackagingIntegrationTests.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
.
context
.
embedded
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Parameterized
;
import
org.junit.runners.Parameterized.Parameters
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Integration tests for Spring Boot's embedded servlet container support using war
* packaging.
*
* @author Andy Wilkinson
*/
@RunWith
(
Parameterized
.
class
)
public
class
EmbeddedServletContainerWarPackagingIntegrationTests
extends
AbstractEmbeddedServletContainerIntegrationTests
{
@Parameters
(
name
=
"{0}"
)
public
static
Object
[]
parameters
()
{
return
AbstractEmbeddedServletContainerIntegrationTests
.
parameters
(
"war"
);
}
public
EmbeddedServletContainerWarPackagingIntegrationTests
(
String
name
,
AbstractApplicationLauncher
launcher
)
{
super
(
name
,
launcher
);
}
@Test
public
void
nestedMetaInfResourceIsAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/nested-meta-inf-resource.txt"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
@Test
public
void
nestedMetaInfResourceIsAvailableViaServletContext
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/nested-meta-inf-resource.txt"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
@Test
public
void
nestedJarIsNotAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/WEB-INF/lib/resources-1.0.jar"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
NOT_FOUND
);
}
@Test
public
void
applicationClassesAreNotAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/WEB-INF/classes/com/example/ResourceHandlingApplication.class"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
NOT_FOUND
);
}
@Test
public
void
webappResourcesAreAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/webapp-resource.txt"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/ExplodedApplicationLauncher.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
.
context
.
embedded
;
import
java.io.File
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.Enumeration
;
import
java.util.List
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarFile
;
import
org.springframework.util.FileSystemUtils
;
import
org.springframework.util.StreamUtils
;
/**
* {@link AbstractApplicationLauncher} that launches an exploded Spring Boot application
* using Spring Boot's Jar or War launcher.
*
* @author Andy Wilkinson
*/
class
ExplodedApplicationLauncher
extends
AbstractApplicationLauncher
{
private
final
File
exploded
=
new
File
(
"target/exploded"
);
ExplodedApplicationLauncher
(
ApplicationBuilder
applicationBuilder
)
{
super
(
applicationBuilder
);
}
@Override
protected
List
<
String
>
getArguments
(
File
archive
)
{
String
mainClass
=
archive
.
getName
().
endsWith
(
".war"
)
?
"org.springframework.boot.loader.WarLauncher"
:
"org.springframework.boot.loader.JarLauncher"
;
try
{
explodeArchive
(
archive
);
return
Arrays
.
asList
(
"-cp"
,
this
.
exploded
.
getAbsolutePath
(),
mainClass
);
}
catch
(
IOException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
void
explodeArchive
(
File
archive
)
throws
IOException
{
FileSystemUtils
.
deleteRecursively
(
this
.
exploded
);
JarFile
jarFile
=
new
JarFile
(
archive
);
Enumeration
<
JarEntry
>
entries
=
jarFile
.
entries
();
while
(
entries
.
hasMoreElements
())
{
JarEntry
jarEntry
=
entries
.
nextElement
();
File
extracted
=
new
File
(
this
.
exploded
,
jarEntry
.
getName
());
if
(
jarEntry
.
isDirectory
())
{
extracted
.
mkdirs
();
}
else
{
FileOutputStream
extractedOutputStream
=
new
FileOutputStream
(
extracted
);
StreamUtils
.
copy
(
jarFile
.
getInputStream
(
jarEntry
),
extractedOutputStream
);
extractedOutputStream
.
close
();
}
}
jarFile
.
close
();
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/PackagedApplicationLauncher.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
.
context
.
embedded
;
import
java.io.File
;
import
java.util.Arrays
;
import
java.util.List
;
/**
* {@link AbstractApplicationLauncher} that launches a packaged Spring Boot application
* using {@code java -jar}.
*
* @author Andy Wilkinson
*/
class
PackagedApplicationLauncher
extends
AbstractApplicationLauncher
{
PackagedApplicationLauncher
(
ApplicationBuilder
applicationBuilder
)
{
super
(
applicationBuilder
);
}
@Override
protected
List
<
String
>
getArguments
(
File
archive
)
{
return
Arrays
.
asList
(
"-jar"
,
archive
.
getAbsolutePath
());
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/Versions.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
.
context
.
embedded
;
import
java.io.FileReader
;
import
javax.xml.xpath.XPath
;
import
javax.xml.xpath.XPathExpression
;
import
javax.xml.xpath.XPathFactory
;
import
org.xml.sax.InputSource
;
/**
* Provides access to dependency versions by querying the project's pom.
*
* @author Andy Wilkinson
*/
final
class
Versions
{
private
Versions
()
{
}
public
static
String
getBootVersion
()
{
return
evaluateExpression
(
"/*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']"
+
"/text()"
);
}
private
static
String
evaluateExpression
(
String
expression
)
{
try
{
XPathFactory
xPathFactory
=
XPathFactory
.
newInstance
();
XPath
xpath
=
xPathFactory
.
newXPath
();
XPathExpression
expr
=
xpath
.
compile
(
expression
);
String
version
=
expr
.
evaluate
(
new
InputSource
(
new
FileReader
(
"pom.xml"
)));
return
version
;
}
catch
(
Exception
ex
)
{
throw
new
IllegalStateException
(
"Failed to evaluate expression"
,
ex
);
}
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/resources/pom-template.xml
0 → 100644
View file @
68af8310
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-parent
</artifactId>
<version>
{{bootVersion}}
</version>
<relativePath/>
</parent>
<groupId>
com.example
</groupId>
<artifactId>
app
</artifactId>
<version>
0.0.1
</version>
<packaging>
{{packaging}}
</packaging>
<properties>
<resourcesJarPath>
{{resourcesJarPath}}
</resourcesJarPath>
{{containerVersion}}
</properties>
<dependencies>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-{{container}}
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-web
</artifactId>
</dependency>
<dependency>
<groupId>
javax.servlet
</groupId>
<artifactId>
javax.servlet-api
</artifactId>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
com.example
</groupId>
<artifactId>
resources
</artifactId>
<version>
1.0
</version>
<scope>
system
</scope>
<systemPath>
${resourcesJarPath}
</systemPath>
</dependency>
{{#additionalDependencies}}
<dependency>
<groupId>
{{groupId}}
</groupId>
<artifactId>
{{artifactId}}
</artifactId>
<version>
{{version}}
</version>
</dependency>
{{/additionalDependencies}}
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-maven-plugin
</artifactId>
<configuration>
<includeSystemScope>
true
</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>
spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java
View file @
68af8310
...
@@ -20,9 +20,13 @@ import java.io.File;
...
@@ -20,9 +20,13 @@ import java.io.File;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.JarURLConnection
;
import
java.net.JarURLConnection
;
import
java.net.URL
;
import
java.net.URL
;
import
java.net.URLClassLoader
;
import
java.net.URLConnection
;
import
java.net.URLConnection
;
import
java.security.CodeSource
;
import
java.security.CodeSource
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.jar.JarFile
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.apache.commons.logging.LogFactory
;
...
@@ -86,6 +90,31 @@ public abstract class AbstractEmbeddedServletContainerFactory
...
@@ -86,6 +90,31 @@ public abstract class AbstractEmbeddedServletContainerFactory
return
getExplodedWarFileDocumentRoot
(
getCodeSourceArchive
());
return
getExplodedWarFileDocumentRoot
(
getCodeSourceArchive
());
}
}
protected
List
<
URL
>
getUrlsOfJarsWithMetaInfResources
()
{
ClassLoader
classLoader
=
getClass
().
getClassLoader
();
List
<
URL
>
staticResourceUrls
=
new
ArrayList
<
URL
>();
if
(
classLoader
instanceof
URLClassLoader
)
{
for
(
URL
url
:
((
URLClassLoader
)
classLoader
).
getURLs
())
{
try
{
URLConnection
connection
=
url
.
openConnection
();
if
(
connection
instanceof
JarURLConnection
)
{
JarURLConnection
jarConnection
=
(
JarURLConnection
)
connection
;
JarFile
jar
=
jarConnection
.
getJarFile
();
if
(
jar
.
getName
().
endsWith
(
".jar"
)
&&
jar
.
getJarEntry
(
"META-INF/resources"
)
!=
null
)
{
staticResourceUrls
.
add
(
url
);
}
jar
.
close
();
}
}
catch
(
IOException
ex
)
{
throw
new
IllegalStateException
(
ex
);
}
}
}
return
staticResourceUrls
;
}
File
getExplodedWarFileDocumentRoot
(
File
codeSourceFile
)
{
File
getExplodedWarFileDocumentRoot
(
File
codeSourceFile
)
{
if
(
this
.
logger
.
isDebugEnabled
())
{
if
(
this
.
logger
.
isDebugEnabled
())
{
this
.
logger
.
debug
(
"Code archive: "
+
codeSourceFile
);
this
.
logger
.
debug
(
"Code archive: "
+
codeSourceFile
);
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java
View file @
68af8310
/*
/*
* Copyright 2012-201
6
the original author or authors.
* Copyright 2012-201
7
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -60,6 +60,7 @@ import org.eclipse.jetty.servlet.ServletHolder;
...
@@ -60,6 +60,7 @@ import org.eclipse.jetty.servlet.ServletHolder;
import
org.eclipse.jetty.servlet.ServletMapping
;
import
org.eclipse.jetty.servlet.ServletMapping
;
import
org.eclipse.jetty.util.resource.JarResource
;
import
org.eclipse.jetty.util.resource.JarResource
;
import
org.eclipse.jetty.util.resource.Resource
;
import
org.eclipse.jetty.util.resource.Resource
;
import
org.eclipse.jetty.util.resource.ResourceCollection
;
import
org.eclipse.jetty.util.ssl.SslContextFactory
;
import
org.eclipse.jetty.util.ssl.SslContextFactory
;
import
org.eclipse.jetty.util.thread.ThreadPool
;
import
org.eclipse.jetty.util.thread.ThreadPool
;
import
org.eclipse.jetty.webapp.AbstractConfiguration
;
import
org.eclipse.jetty.webapp.AbstractConfiguration
;
...
@@ -408,14 +409,21 @@ public class JettyEmbeddedServletContainerFactory
...
@@ -408,14 +409,21 @@ public class JettyEmbeddedServletContainerFactory
File
root
=
getValidDocumentRoot
();
File
root
=
getValidDocumentRoot
();
root
=
(
root
!=
null
?
root
:
createTempDir
(
"jetty-docbase"
));
root
=
(
root
!=
null
?
root
:
createTempDir
(
"jetty-docbase"
));
try
{
try
{
if
(!
root
.
isDirectory
())
{
List
<
Resource
>
resources
=
new
ArrayList
<
Resource
>();
Resource
resource
=
JarResource
resources
.
add
(
.
newJarResource
(
Resource
.
newResource
(
root
));
root
.
isDirectory
()
?
Resource
.
newResource
(
root
.
getCanonicalFile
())
handler
.
setBaseResource
(
resource
);
:
JarResource
.
newJarResource
(
Resource
.
newResource
(
root
)));
}
for
(
URL
resourceJarUrl
:
this
.
getUrlsOfJarsWithMetaInfResources
())
{
else
{
Resource
resource
=
Resource
handler
.
setBaseResource
(
Resource
.
newResource
(
root
.
getCanonicalFile
()));
.
newResource
(
resourceJarUrl
+
"META-INF/resources"
);
// Jetty 9.2 and earlier do not support nested jars. See
// https://github.com/eclipse/jetty.project/issues/518
if
(
resource
.
exists
()
&&
resource
.
isDirectory
())
{
resources
.
add
(
resource
);
}
}
}
handler
.
setBaseResource
(
new
ResourceCollection
(
resources
.
toArray
(
new
Resource
[
resources
.
size
()])));
}
}
catch
(
Exception
ex
)
{
catch
(
Exception
ex
)
{
throw
new
IllegalStateException
(
ex
);
throw
new
IllegalStateException
(
ex
);
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java
View file @
68af8310
/*
/*
* Copyright 2012-201
6
the original author or authors.
* Copyright 2012-201
7
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -189,7 +189,7 @@ public class TomcatEmbeddedServletContainerFactory
...
@@ -189,7 +189,7 @@ public class TomcatEmbeddedServletContainerFactory
protected
void
prepareContext
(
Host
host
,
ServletContextInitializer
[]
initializers
)
{
protected
void
prepareContext
(
Host
host
,
ServletContextInitializer
[]
initializers
)
{
File
docBase
=
getValidDocumentRoot
();
File
docBase
=
getValidDocumentRoot
();
docBase
=
(
docBase
!=
null
?
docBase
:
createTempDir
(
"tomcat-docbase"
));
docBase
=
(
docBase
!=
null
?
docBase
:
createTempDir
(
"tomcat-docbase"
));
TomcatEmbeddedContext
context
=
new
TomcatEmbeddedContext
();
final
TomcatEmbeddedContext
context
=
new
TomcatEmbeddedContext
();
context
.
setName
(
getContextPath
());
context
.
setName
(
getContextPath
());
context
.
setDisplayName
(
getDisplayName
());
context
.
setDisplayName
(
getDisplayName
());
context
.
setPath
(
getContextPath
());
context
.
setPath
(
getContextPath
());
...
@@ -219,6 +219,17 @@ public class TomcatEmbeddedServletContainerFactory
...
@@ -219,6 +219,17 @@ public class TomcatEmbeddedServletContainerFactory
addJasperInitializer
(
context
);
addJasperInitializer
(
context
);
context
.
addLifecycleListener
(
new
StoreMergedWebXmlListener
());
context
.
addLifecycleListener
(
new
StoreMergedWebXmlListener
());
}
}
context
.
addLifecycleListener
(
new
LifecycleListener
()
{
@Override
public
void
lifecycleEvent
(
LifecycleEvent
event
)
{
if
(
event
.
getType
().
equals
(
Lifecycle
.
CONFIGURE_START_EVENT
))
{
TomcatResources
.
get
(
context
)
.
addResourceJars
(
getUrlsOfJarsWithMetaInfResources
());
}
}
});
ServletContextInitializer
[]
initializersToUse
=
mergeInitializers
(
initializers
);
ServletContextInitializer
[]
initializersToUse
=
mergeInitializers
(
initializers
);
configureContext
(
context
,
initializersToUse
);
configureContext
(
context
,
initializersToUse
);
host
.
addChild
(
context
);
host
.
addChild
(
context
);
...
@@ -823,7 +834,6 @@ public class TomcatEmbeddedServletContainerFactory
...
@@ -823,7 +834,6 @@ public class TomcatEmbeddedServletContainerFactory
if
(
servletContext
.
getAttribute
(
MERGED_WEB_XML
)
==
null
)
{
if
(
servletContext
.
getAttribute
(
MERGED_WEB_XML
)
==
null
)
{
servletContext
.
setAttribute
(
MERGED_WEB_XML
,
getEmptyWebXml
());
servletContext
.
setAttribute
(
MERGED_WEB_XML
,
getEmptyWebXml
());
}
}
TomcatResources
.
get
(
context
).
addClasspathResources
();
}
}
private
String
getEmptyWebXml
()
{
private
String
getEmptyWebXml
()
{
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatResources.java
View file @
68af8310
/*
/*
* Copyright 2012-201
6
the original author or authors.
* Copyright 2012-201
7
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -16,11 +16,10 @@
...
@@ -16,11 +16,10 @@
package
org
.
springframework
.
boot
.
context
.
embedded
.
tomcat
;
package
org
.
springframework
.
boot
.
context
.
embedded
.
tomcat
;
import
java.io.File
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.net.MalformedURLException
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.net.URL
;
import
java.
net.URLClassLoader
;
import
java.
util.List
;
import
javax.naming.directory.DirContext
;
import
javax.naming.directory.DirContext
;
import
javax.servlet.ServletContext
;
import
javax.servlet.ServletContext
;
...
@@ -37,6 +36,7 @@ import org.springframework.util.ReflectionUtils;
...
@@ -37,6 +36,7 @@ import org.springframework.util.ReflectionUtils;
*
*
* @author Dave Syer
* @author Dave Syer
* @author Phillip Webb
* @author Phillip Webb
* @author Andy Wilkinson
*/
*/
abstract
class
TomcatResources
{
abstract
class
TomcatResources
{
...
@@ -46,28 +46,16 @@ abstract class TomcatResources {
...
@@ -46,28 +46,16 @@ abstract class TomcatResources {
this
.
context
=
context
;
this
.
context
=
context
;
}
}
/**
void
addResourceJars
(
List
<
URL
>
resourceJarUrls
)
{
* Add resources from the classpath.
for
(
URL
url
:
resourceJarUrls
)
{
*/
String
file
=
url
.
getFile
();
public
void
addClasspathResources
()
{
if
(
file
.
endsWith
(
".jar"
)
||
file
.
endsWith
(
".jar!/"
))
{
ClassLoader
loader
=
getClass
().
getClassLoader
();
String
jar
=
url
.
toString
();
if
(
loader
instanceof
URLClassLoader
)
{
if
(!
jar
.
startsWith
(
"jar:"
))
{
for
(
URL
url
:
((
URLClassLoader
)
loader
).
getURLs
())
{
// A jar file in the file system. Convert to Jar URL.
String
file
=
url
.
getFile
();
jar
=
"jar:"
+
jar
+
"!/"
;
if
(
file
.
endsWith
(
".jar"
)
||
file
.
endsWith
(
".jar!/"
))
{
String
jar
=
url
.
toString
();
if
(!
jar
.
startsWith
(
"jar:"
))
{
// A jar file in the file system. Convert to Jar URL.
jar
=
"jar:"
+
jar
+
"!/"
;
}
addJar
(
jar
);
}
else
if
(
url
.
toString
().
startsWith
(
"file:"
))
{
String
dir
=
url
.
toString
().
substring
(
"file:"
.
length
());
if
(
new
File
(
dir
).
isDirectory
())
{
addDir
(
dir
,
url
);
}
}
}
addJar
(
jar
);
}
}
}
}
}
}
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/CompositeResourceManager.java
0 → 100644
View file @
68af8310
/*
* Copyright 2012-2017 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
.
context
.
embedded
.
undertow
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.List
;
import
io.undertow.UndertowMessages
;
import
io.undertow.server.handlers.resource.Resource
;
import
io.undertow.server.handlers.resource.ResourceChangeListener
;
import
io.undertow.server.handlers.resource.ResourceManager
;
/**
* A {@ResourceManager} that delegates to multiple {@code ResourceManager} instances.
*
* @author Andy Wilkinson
*/
class
CompositeResourceManager
implements
ResourceManager
{
private
final
List
<
ResourceManager
>
resourceManagers
;
CompositeResourceManager
(
ResourceManager
...
resourceManagers
)
{
this
.
resourceManagers
=
Arrays
.
asList
(
resourceManagers
);
}
@Override
public
void
close
()
throws
IOException
{
for
(
ResourceManager
resourceManager
:
this
.
resourceManagers
)
{
resourceManager
.
close
();
}
}
@Override
public
Resource
getResource
(
String
path
)
throws
IOException
{
for
(
ResourceManager
resourceManager
:
this
.
resourceManagers
)
{
Resource
resource
=
resourceManager
.
getResource
(
path
);
if
(
resource
!=
null
)
{
return
resource
;
}
}
return
null
;
}
@Override
public
boolean
isResourceChangeListenerSupported
()
{
return
false
;
}
@Override
public
void
registerResourceChangeListener
(
ResourceChangeListener
listener
)
{
throw
UndertowMessages
.
MESSAGES
.
resourceChangeListenerNotSupported
();
}
@Override
public
void
removeResourceChangeListener
(
ResourceChangeListener
listener
)
{
throw
UndertowMessages
.
MESSAGES
.
resourceChangeListenerNotSupported
();
}
}
spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java
View file @
68af8310
...
@@ -19,6 +19,7 @@ package org.springframework.boot.context.embedded.undertow;
...
@@ -19,6 +19,7 @@ package org.springframework.boot.context.embedded.undertow;
import
java.io.File
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.URL
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.nio.charset.Charset
;
import
java.nio.charset.Charset
;
import
java.security.KeyManagementException
;
import
java.security.KeyManagementException
;
import
java.security.KeyStore
;
import
java.security.KeyStore
;
...
@@ -49,7 +50,10 @@ import io.undertow.server.handlers.accesslog.AccessLogHandler;
...
@@ -49,7 +50,10 @@ import io.undertow.server.handlers.accesslog.AccessLogHandler;
import
io.undertow.server.handlers.accesslog.AccessLogReceiver
;
import
io.undertow.server.handlers.accesslog.AccessLogReceiver
;
import
io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver
;
import
io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver
;
import
io.undertow.server.handlers.resource.FileResourceManager
;
import
io.undertow.server.handlers.resource.FileResourceManager
;
import
io.undertow.server.handlers.resource.Resource
;
import
io.undertow.server.handlers.resource.ResourceChangeListener
;
import
io.undertow.server.handlers.resource.ResourceManager
;
import
io.undertow.server.handlers.resource.ResourceManager
;
import
io.undertow.server.handlers.resource.URLResource
;
import
io.undertow.server.session.SessionManager
;
import
io.undertow.server.session.SessionManager
;
import
io.undertow.servlet.Servlets
;
import
io.undertow.servlet.Servlets
;
import
io.undertow.servlet.api.DeploymentInfo
;
import
io.undertow.servlet.api.DeploymentInfo
;
...
@@ -461,13 +465,11 @@ public class UndertowEmbeddedServletContainerFactory
...
@@ -461,13 +465,11 @@ public class UndertowEmbeddedServletContainerFactory
private
ResourceManager
getDocumentRootResourceManager
()
{
private
ResourceManager
getDocumentRootResourceManager
()
{
File
root
=
getCanonicalDocumentRoot
();
File
root
=
getCanonicalDocumentRoot
();
if
(
root
.
isDirectory
())
{
List
<
URL
>
metaInfResourceJarUrls
=
getUrlsOfJarsWithMetaInfResources
();
return
new
FileResourceManager
(
root
,
0
);
ResourceManager
rootResourceManager
=
root
.
isDirectory
()
}
?
new
FileResourceManager
(
root
,
0
)
:
new
JarResourceManager
(
root
);
if
(
root
.
isFile
())
{
return
new
CompositeResourceManager
(
rootResourceManager
,
return
new
JarResourceManager
(
root
);
new
MetaInfResourcesResourceManager
(
metaInfResourceJarUrls
));
}
return
ResourceManager
.
EMPTY_RESOURCE_MANAGER
;
}
}
/**
/**
...
@@ -599,6 +601,49 @@ public class UndertowEmbeddedServletContainerFactory
...
@@ -599,6 +601,49 @@ public class UndertowEmbeddedServletContainerFactory
this
.
useForwardHeaders
=
useForwardHeaders
;
this
.
useForwardHeaders
=
useForwardHeaders
;
}
}
/**
* {@link ResourceManager} that exposes resource in {@code META-INF/resources}
* directory of nested (in {@code BOOT-INF/lib} or {@code WEB-INF/lib}) jars.
*/
private
static
final
class
MetaInfResourcesResourceManager
implements
ResourceManager
{
private
final
List
<
URL
>
metaInfResourceJarUrls
;
private
MetaInfResourcesResourceManager
(
List
<
URL
>
metaInfResourceJarUrls
)
{
this
.
metaInfResourceJarUrls
=
metaInfResourceJarUrls
;
}
@Override
public
void
close
()
throws
IOException
{
}
@Override
public
Resource
getResource
(
String
path
)
throws
IOException
{
for
(
URL
url
:
this
.
metaInfResourceJarUrls
)
{
URL
resourceUrl
=
new
URL
(
url
+
"META-INF/resources"
+
path
);
URLConnection
connection
=
resourceUrl
.
openConnection
();
if
(
connection
.
getContentLength
()
>=
0
)
{
return
new
URLResource
(
resourceUrl
,
connection
,
path
);
}
}
return
null
;
}
@Override
public
boolean
isResourceChangeListenerSupported
()
{
return
false
;
}
@Override
public
void
registerResourceChangeListener
(
ResourceChangeListener
listener
)
{
}
@Override
public
void
removeResourceChangeListener
(
ResourceChangeListener
listener
)
{
}
}
/**
/**
* {@link ServletContainerInitializer} to initialize {@link ServletContextInitializer
* {@link ServletContainerInitializer} to initialize {@link ServletContextInitializer
* ServletContextInitializers}.
* ServletContextInitializers}.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment