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
1395f38e
Commit
1395f38e
authored
Mar 09, 2017
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '1.4.x' into 1.5.x
parents
7da70a52
a2cf0455
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
603 additions
and
45 deletions
+603
-45
AbstractApplicationLauncher.java
...rk/boot/context/embedded/AbstractApplicationLauncher.java
+16
-8
AbstractEmbeddedServletContainerIntegrationTests.java
...ded/AbstractEmbeddedServletContainerIntegrationTests.java
+25
-14
BootRunApplicationLauncher.java
...ork/boot/context/embedded/BootRunApplicationLauncher.java
+141
-0
EmbeddedServletContainerJarDevelopmentIntegrationTests.java
...beddedServletContainerJarDevelopmentIntegrationTests.java
+67
-0
EmbeddedServletContainerJarPackagingIntegrationTests.java
...EmbeddedServletContainerJarPackagingIntegrationTests.java
+5
-1
EmbeddedServletContainerWarDevelopmentIntegrationTests.java
...beddedServletContainerWarDevelopmentIntegrationTests.java
+74
-0
EmbeddedServletContainerWarPackagingIntegrationTests.java
...EmbeddedServletContainerWarPackagingIntegrationTests.java
+5
-1
ExplodedApplicationLauncher.java
...rk/boot/context/embedded/ExplodedApplicationLauncher.java
+12
-2
IdeApplicationLauncher.java
...amework/boot/context/embedded/IdeApplicationLauncher.java
+152
-0
PackagedApplicationLauncher.java
...rk/boot/context/embedded/PackagedApplicationLauncher.java
+10
-0
AbstractEmbeddedServletContainerFactory.java
...ext/embedded/AbstractEmbeddedServletContainerFactory.java
+43
-7
JettyEmbeddedServletContainerFactory.java
.../embedded/jetty/JettyEmbeddedServletContainerFactory.java
+11
-2
TomcatResources.java
...amework/boot/context/embedded/tomcat/TomcatResources.java
+4
-2
UndertowEmbeddedServletContainerFactory.java
...ded/undertow/UndertowEmbeddedServletContainerFactory.java
+38
-8
No files found.
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/AbstractApplicationLauncher.java
View file @
1395f38e
...
...
@@ -34,8 +34,6 @@ import org.springframework.util.FileCopyUtils;
*/
abstract
class
AbstractApplicationLauncher
extends
ExternalResource
{
private
final
File
serverPortFile
=
new
File
(
"target/server.port"
);
private
final
ApplicationBuilder
applicationBuilder
;
private
Process
process
;
...
...
@@ -62,8 +60,15 @@ abstract class AbstractApplicationLauncher extends ExternalResource {
protected
abstract
List
<
String
>
getArguments
(
File
archive
);
protected
abstract
File
getWorkingDirectory
();
protected
abstract
String
getDescription
(
String
packaging
);
private
Process
startApplication
()
throws
Exception
{
this
.
serverPortFile
.
delete
();
File
workingDirectory
=
getWorkingDirectory
();
File
serverPortFile
=
workingDirectory
==
null
?
new
File
(
"target/server.port"
)
:
new
File
(
workingDirectory
,
"target/server.port"
);
serverPortFile
.
delete
();
File
archive
=
this
.
applicationBuilder
.
buildApplication
();
List
<
String
>
arguments
=
new
ArrayList
<
String
>();
arguments
.
add
(
System
.
getProperty
(
"java.home"
)
+
"/bin/java"
);
...
...
@@ -72,14 +77,17 @@ abstract class AbstractApplicationLauncher extends ExternalResource {
arguments
.
toArray
(
new
String
[
arguments
.
size
()]));
processBuilder
.
redirectOutput
(
Redirect
.
INHERIT
);
processBuilder
.
redirectError
(
Redirect
.
INHERIT
);
if
(
workingDirectory
!=
null
)
{
processBuilder
.
directory
(
workingDirectory
);
}
Process
process
=
processBuilder
.
start
();
this
.
httpPort
=
awaitServerPort
(
process
);
this
.
httpPort
=
awaitServerPort
(
process
,
serverPortFile
);
return
process
;
}
private
int
awaitServerPort
(
Process
process
)
throws
Exception
{
private
int
awaitServerPort
(
Process
process
,
File
serverPortFile
)
throws
Exception
{
long
end
=
System
.
currentTimeMillis
()
+
30000
;
while
(
this
.
serverPortFile
.
length
()
==
0
)
{
while
(
serverPortFile
.
length
()
==
0
)
{
if
(
System
.
currentTimeMillis
()
>
end
)
{
throw
new
IllegalStateException
(
"server.port file was not written within 30 seconds"
);
...
...
@@ -89,8 +97,8 @@ abstract class AbstractApplicationLauncher extends ExternalResource {
}
Thread
.
sleep
(
100
);
}
return
Integer
.
parseInt
(
FileCopyUtils
.
copyToString
(
new
FileReader
(
this
.
serverPortFile
)));
return
Integer
.
parseInt
(
FileCopyUtils
.
copyToString
(
new
FileReader
(
serverPortFile
)));
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerIntegrationTests.java
View file @
1395f38e
...
...
@@ -19,6 +19,8 @@ package org.springframework.boot.context.embedded;
import
java.io.IOException
;
import
java.net.URI
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -47,29 +49,38 @@ public abstract class AbstractEmbeddedServletContainerIntegrationTests {
protected
final
RestTemplate
rest
=
new
RestTemplate
();
public
static
Object
[]
parameters
(
String
packaging
)
{
public
static
Object
[]
parameters
(
String
packaging
,
List
<
Class
<?
extends
AbstractApplicationLauncher
>>
applicationLaunchers
)
{
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"
));
parameters
.
addAll
(
createParameters
(
packaging
,
"jetty"
,
Arrays
.
asList
(
"current"
,
"9.3.16.v20170120"
),
applicationLaunchers
));
parameters
.
addAll
(
createParameters
(
packaging
,
"tomcat"
,
Arrays
.
asList
(
"current"
,
"8.0.41"
,
"7.0.75"
),
applicationLaunchers
));
parameters
.
addAll
(
createParameters
(
packaging
,
"undertow"
,
Collections
.
singletonList
(
"current"
),
applicationLaunchers
));
return
parameters
.
toArray
(
new
Object
[
parameters
.
size
()]);
}
private
static
List
<
Object
>
createParameters
(
String
packaging
,
String
container
,
String
...
versions
)
{
List
<
String
>
versions
,
List
<
Class
<?
extends
AbstractApplicationLauncher
>>
applicationLaunchers
)
{
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
)
});
for
(
Class
<?
extends
AbstractApplicationLauncher
>
launcherClass
:
applicationLaunchers
)
{
try
{
AbstractApplicationLauncher
launcher
=
launcherClass
.
getDeclaredConstructor
(
ApplicationBuilder
.
class
)
.
newInstance
(
applicationBuilder
);
String
name
=
StringUtils
.
capitalise
(
container
)
+
" "
+
version
+
": "
+
launcher
.
getDescription
(
packaging
);
parameters
.
add
(
new
Object
[]
{
name
,
launcher
});
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
}
return
parameters
;
}
...
...
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/BootRunApplicationLauncher.java
0 → 100644
View file @
1395f38e
/*
* 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.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
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
;
import
org.springframework.util.StringUtils
;
/**
* {@link AbstractApplicationLauncher} that launches a Spring Boot application with a
* classpath similar to that used when run with Maven or Gradle.
*
* @author Andy Wilkinson
*/
class
BootRunApplicationLauncher
extends
AbstractApplicationLauncher
{
private
final
File
exploded
=
new
File
(
"target/run"
);
BootRunApplicationLauncher
(
ApplicationBuilder
applicationBuilder
)
{
super
(
applicationBuilder
);
}
@Override
protected
List
<
String
>
getArguments
(
File
archive
)
{
try
{
explodeArchive
(
archive
);
deleteLauncherClasses
();
File
targetClasses
=
populateTargetClasses
(
archive
);
File
dependencies
=
populateDependencies
(
archive
);
populateSrcMainWebapp
();
List
<
String
>
classpath
=
new
ArrayList
<
String
>();
classpath
.
add
(
targetClasses
.
getAbsolutePath
());
for
(
File
dependency
:
dependencies
.
listFiles
())
{
classpath
.
add
(
dependency
.
getAbsolutePath
());
}
return
Arrays
.
asList
(
"-cp"
,
StringUtils
.
collectionToDelimitedString
(
classpath
,
File
.
pathSeparator
),
"com.example.ResourceHandlingApplication"
);
}
catch
(
IOException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
void
deleteLauncherClasses
()
{
FileSystemUtils
.
deleteRecursively
(
new
File
(
this
.
exploded
,
"org"
));
}
private
File
populateTargetClasses
(
File
archive
)
{
File
targetClasses
=
new
File
(
this
.
exploded
,
"target/classes"
);
targetClasses
.
mkdirs
();
new
File
(
this
.
exploded
,
getClassesPath
(
archive
)).
renameTo
(
targetClasses
);
return
targetClasses
;
}
private
File
populateDependencies
(
File
archive
)
{
File
dependencies
=
new
File
(
this
.
exploded
,
"dependencies"
);
dependencies
.
mkdirs
();
List
<
String
>
libPaths
=
getLibPaths
(
archive
);
for
(
String
libPath
:
libPaths
)
{
for
(
File
jar
:
new
File
(
this
.
exploded
,
libPath
).
listFiles
())
{
jar
.
renameTo
(
new
File
(
dependencies
,
jar
.
getName
()));
}
}
return
dependencies
;
}
private
void
populateSrcMainWebapp
()
{
File
srcMainWebapp
=
new
File
(
this
.
exploded
,
"src/main/webapp"
);
srcMainWebapp
.
mkdirs
();
new
File
(
this
.
exploded
,
"webapp-resource.txt"
)
.
renameTo
(
new
File
(
srcMainWebapp
,
"webapp-resource.txt"
));
}
private
String
getClassesPath
(
File
archive
)
{
return
archive
.
getName
().
endsWith
(
".jar"
)
?
"BOOT-INF/classes"
:
"WEB-INF/classes"
;
}
private
List
<
String
>
getLibPaths
(
File
archive
)
{
return
archive
.
getName
().
endsWith
(
".jar"
)
?
Collections
.
singletonList
(
"BOOT-INF/lib"
)
:
Arrays
.
asList
(
"WEB-INF/lib"
,
"WEB-INF/lib-provided"
);
}
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
();
}
@Override
protected
File
getWorkingDirectory
()
{
return
this
.
exploded
;
}
@Override
protected
String
getDescription
(
String
packaging
)
{
return
"build system run "
+
packaging
+
" project"
;
}
}
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/EmbeddedServletContainerJarDevelopmentIntegrationTests.java
0 → 100644
View file @
1395f38e
/*
* 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.util.Arrays
;
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 when developing
* a jar application.
*
* @author Andy Wilkinson
*/
@RunWith
(
Parameterized
.
class
)
public
class
EmbeddedServletContainerJarDevelopmentIntegrationTests
extends
AbstractEmbeddedServletContainerIntegrationTests
{
@Parameters
(
name
=
"{0}"
)
public
static
Object
[]
parameters
()
{
return
AbstractEmbeddedServletContainerIntegrationTests
.
parameters
(
"jar"
,
Arrays
.
asList
(
BootRunApplicationLauncher
.
class
,
IdeApplicationLauncher
.
class
));
}
public
EmbeddedServletContainerJarDevelopmentIntegrationTests
(
String
name
,
AbstractApplicationLauncher
launcher
)
{
super
(
name
,
launcher
);
}
@Test
public
void
metaInfResourceFromDependencyIsAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/nested-meta-inf-resource.txt"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
@Test
public
void
metaInfResourceFromDependencyIsAvailableViaServletContext
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/nested-meta-inf-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/EmbeddedServletContainerJarPackagingIntegrationTests.java
View file @
1395f38e
...
...
@@ -16,6 +16,8 @@
package
org
.
springframework
.
boot
.
context
.
embedded
;
import
java.util.Arrays
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Parameterized
;
...
...
@@ -38,7 +40,9 @@ public class EmbeddedServletContainerJarPackagingIntegrationTests
@Parameters
(
name
=
"{0}"
)
public
static
Object
[]
parameters
()
{
return
AbstractEmbeddedServletContainerIntegrationTests
.
parameters
(
"jar"
);
return
AbstractEmbeddedServletContainerIntegrationTests
.
parameters
(
"jar"
,
Arrays
.
asList
(
PackagedApplicationLauncher
.
class
,
ExplodedApplicationLauncher
.
class
));
}
public
EmbeddedServletContainerJarPackagingIntegrationTests
(
String
name
,
...
...
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/EmbeddedServletContainerWarDevelopmentIntegrationTests.java
0 → 100644
View file @
1395f38e
/*
* 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.util.Arrays
;
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 when developing
* a war application.
*
* @author Andy Wilkinson
*/
@RunWith
(
Parameterized
.
class
)
public
class
EmbeddedServletContainerWarDevelopmentIntegrationTests
extends
AbstractEmbeddedServletContainerIntegrationTests
{
@Parameters
(
name
=
"{0}"
)
public
static
Object
[]
parameters
()
{
return
AbstractEmbeddedServletContainerIntegrationTests
.
parameters
(
"war"
,
Arrays
.
asList
(
BootRunApplicationLauncher
.
class
,
IdeApplicationLauncher
.
class
));
}
public
EmbeddedServletContainerWarDevelopmentIntegrationTests
(
String
name
,
AbstractApplicationLauncher
launcher
)
{
super
(
name
,
launcher
);
}
@Test
public
void
metaInfResourceFromDependencyIsAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/nested-meta-inf-resource.txt"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
@Test
public
void
metaInfResourceFromDependencyIsAvailableViaServletContext
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/nested-meta-inf-resource.txt"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
@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/EmbeddedServletContainerWarPackagingIntegrationTests.java
View file @
1395f38e
...
...
@@ -16,6 +16,8 @@
package
org
.
springframework
.
boot
.
context
.
embedded
;
import
java.util.Arrays
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Parameterized
;
...
...
@@ -38,7 +40,9 @@ public class EmbeddedServletContainerWarPackagingIntegrationTests
@Parameters
(
name
=
"{0}"
)
public
static
Object
[]
parameters
()
{
return
AbstractEmbeddedServletContainerIntegrationTests
.
parameters
(
"war"
);
return
AbstractEmbeddedServletContainerIntegrationTests
.
parameters
(
"war"
,
Arrays
.
asList
(
PackagedApplicationLauncher
.
class
,
ExplodedApplicationLauncher
.
class
));
}
public
EmbeddedServletContainerWarPackagingIntegrationTests
(
String
name
,
...
...
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/ExplodedApplicationLauncher.java
View file @
1395f38e
...
...
@@ -29,8 +29,8 @@ import org.springframework.util.FileSystemUtils;
import
org.springframework.util.StreamUtils
;
/**
* {@link AbstractApplicationLauncher} that launches a
n exploded Spring Boot application
*
using Spring Boot's Jar or War launcher
.
* {@link AbstractApplicationLauncher} that launches a
Spring Boot application using
*
{@code JarLauncher} or {@code WarLauncher} and an exploded archive
.
*
* @author Andy Wilkinson
*/
...
...
@@ -42,6 +42,16 @@ class ExplodedApplicationLauncher extends AbstractApplicationLauncher {
super
(
applicationBuilder
);
}
@Override
protected
File
getWorkingDirectory
()
{
return
this
.
exploded
;
}
@Override
protected
String
getDescription
(
String
packaging
)
{
return
"exploded "
+
packaging
;
}
@Override
protected
List
<
String
>
getArguments
(
File
archive
)
{
String
mainClass
=
archive
.
getName
().
endsWith
(
".war"
)
...
...
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/IdeApplicationLauncher.java
0 → 100644
View file @
1395f38e
/*
* 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.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
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
;
import
org.springframework.util.StringUtils
;
/**
* {@link AbstractApplicationLauncher} that launches a Spring Boot application with a
* classpath similar to that used when run in an IDE.
*
* @author Andy Wilkinson
*/
class
IdeApplicationLauncher
extends
AbstractApplicationLauncher
{
private
final
File
exploded
=
new
File
(
"target/ide"
);
IdeApplicationLauncher
(
ApplicationBuilder
applicationBuilder
)
{
super
(
applicationBuilder
);
}
@Override
protected
File
getWorkingDirectory
()
{
return
this
.
exploded
;
}
@Override
protected
String
getDescription
(
String
packaging
)
{
return
"IDE run "
+
packaging
+
" project"
;
}
@Override
protected
List
<
String
>
getArguments
(
File
archive
)
{
try
{
explodeArchive
(
archive
,
this
.
exploded
);
deleteLauncherClasses
();
File
targetClasses
=
populateTargetClasses
(
archive
);
File
dependencies
=
populateDependencies
(
archive
);
File
resourcesProject
=
explodedResourcesProject
(
dependencies
);
populateSrcMainWebapp
();
List
<
String
>
classpath
=
new
ArrayList
<
String
>();
classpath
.
add
(
targetClasses
.
getAbsolutePath
());
for
(
File
dependency
:
dependencies
.
listFiles
())
{
classpath
.
add
(
dependency
.
getAbsolutePath
());
}
classpath
.
add
(
resourcesProject
.
getAbsolutePath
());
return
Arrays
.
asList
(
"-cp"
,
StringUtils
.
collectionToDelimitedString
(
classpath
,
File
.
pathSeparator
),
"com.example.ResourceHandlingApplication"
);
}
catch
(
IOException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
private
File
populateTargetClasses
(
File
archive
)
{
File
targetClasses
=
new
File
(
this
.
exploded
,
"target/classes"
);
targetClasses
.
mkdirs
();
new
File
(
this
.
exploded
,
getClassesPath
(
archive
)).
renameTo
(
targetClasses
);
return
targetClasses
;
}
private
File
populateDependencies
(
File
archive
)
{
File
dependencies
=
new
File
(
this
.
exploded
,
"dependencies"
);
dependencies
.
mkdirs
();
List
<
String
>
libPaths
=
getLibPaths
(
archive
);
for
(
String
libPath
:
libPaths
)
{
for
(
File
jar
:
new
File
(
this
.
exploded
,
libPath
).
listFiles
())
{
jar
.
renameTo
(
new
File
(
dependencies
,
jar
.
getName
()));
}
}
return
dependencies
;
}
private
File
explodedResourcesProject
(
File
dependencies
)
throws
IOException
{
File
resourcesProject
=
new
File
(
this
.
exploded
,
"resources-project/target/classes"
);
File
resourcesJar
=
new
File
(
dependencies
,
"resources-1.0.jar"
);
explodeArchive
(
resourcesJar
,
resourcesProject
);
resourcesJar
.
delete
();
return
resourcesProject
;
}
private
void
populateSrcMainWebapp
()
{
File
srcMainWebapp
=
new
File
(
this
.
exploded
,
"src/main/webapp"
);
srcMainWebapp
.
mkdirs
();
new
File
(
this
.
exploded
,
"webapp-resource.txt"
)
.
renameTo
(
new
File
(
srcMainWebapp
,
"webapp-resource.txt"
));
}
private
void
deleteLauncherClasses
()
{
FileSystemUtils
.
deleteRecursively
(
new
File
(
this
.
exploded
,
"org"
));
}
private
String
getClassesPath
(
File
archive
)
{
return
archive
.
getName
().
endsWith
(
".jar"
)
?
"BOOT-INF/classes"
:
"WEB-INF/classes"
;
}
private
List
<
String
>
getLibPaths
(
File
archive
)
{
return
archive
.
getName
().
endsWith
(
".jar"
)
?
Collections
.
singletonList
(
"BOOT-INF/lib"
)
:
Arrays
.
asList
(
"WEB-INF/lib"
,
"WEB-INF/lib-provided"
);
}
private
void
explodeArchive
(
File
archive
,
File
destination
)
throws
IOException
{
FileSystemUtils
.
deleteRecursively
(
destination
);
JarFile
jarFile
=
new
JarFile
(
archive
);
Enumeration
<
JarEntry
>
entries
=
jarFile
.
entries
();
while
(
entries
.
hasMoreElements
())
{
JarEntry
jarEntry
=
entries
.
nextElement
();
File
extracted
=
new
File
(
destination
,
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
View file @
1395f38e
...
...
@@ -32,6 +32,16 @@ class PackagedApplicationLauncher extends AbstractApplicationLauncher {
super
(
applicationBuilder
);
}
@Override
protected
File
getWorkingDirectory
()
{
return
null
;
}
@Override
protected
String
getDescription
(
String
packaging
)
{
return
"packaged "
+
packaging
;
}
@Override
protected
List
<
String
>
getArguments
(
File
archive
)
{
return
Arrays
.
asList
(
"-jar"
,
archive
.
getAbsolutePath
());
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractEmbeddedServletContainerFactory.java
View file @
1395f38e
...
...
@@ -96,15 +96,23 @@ public abstract class AbstractEmbeddedServletContainerFactory
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
)
{
if
(
"file"
.
equals
(
url
.
getProtocol
()))
{
File
file
=
new
File
(
url
.
getFile
());
if
(
file
.
isDirectory
()
&&
new
File
(
file
,
"META-INF/resources"
).
isDirectory
())
{
staticResourceUrls
.
add
(
url
);
}
jar
.
close
();
else
if
(
isResourcesJar
(
file
))
{
staticResourceUrls
.
add
(
url
);
}
}
else
{
URLConnection
connection
=
url
.
openConnection
();
if
(
connection
instanceof
JarURLConnection
)
{
if
(
isResourcesJar
((
JarURLConnection
)
connection
))
{
staticResourceUrls
.
add
(
url
);
}
}
}
}
catch
(
IOException
ex
)
{
...
...
@@ -115,6 +123,34 @@ public abstract class AbstractEmbeddedServletContainerFactory
return
staticResourceUrls
;
}
private
boolean
isResourcesJar
(
JarURLConnection
connection
)
{
try
{
return
isResourcesJar
(
connection
.
getJarFile
());
}
catch
(
IOException
ex
)
{
return
false
;
}
}
private
boolean
isResourcesJar
(
File
file
)
{
try
{
return
isResourcesJar
(
new
JarFile
(
file
));
}
catch
(
IOException
ex
)
{
return
false
;
}
}
private
boolean
isResourcesJar
(
JarFile
jar
)
throws
IOException
{
try
{
return
jar
.
getName
().
endsWith
(
".jar"
)
&&
(
jar
.
getJarEntry
(
"META-INF/resources"
)
!=
null
);
}
finally
{
jar
.
close
();
}
}
File
getExplodedWarFileDocumentRoot
(
File
codeSourceFile
)
{
if
(
this
.
logger
.
isDebugEnabled
())
{
this
.
logger
.
debug
(
"Code archive: "
+
codeSourceFile
);
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java
View file @
1395f38e
...
...
@@ -414,8 +414,7 @@ public class JettyEmbeddedServletContainerFactory
root
.
isDirectory
()
?
Resource
.
newResource
(
root
.
getCanonicalFile
())
:
JarResource
.
newJarResource
(
Resource
.
newResource
(
root
)));
for
(
URL
resourceJarUrl
:
this
.
getUrlsOfJarsWithMetaInfResources
())
{
Resource
resource
=
Resource
.
newResource
(
resourceJarUrl
+
"META-INF/resources"
);
Resource
resource
=
createResource
(
resourceJarUrl
);
// Jetty 9.2 and earlier do not support nested jars. See
// https://github.com/eclipse/jetty.project/issues/518
if
(
resource
.
exists
()
&&
resource
.
isDirectory
())
{
...
...
@@ -430,6 +429,16 @@ public class JettyEmbeddedServletContainerFactory
}
}
private
Resource
createResource
(
URL
url
)
throws
IOException
{
if
(
"file"
.
equals
(
url
.
getProtocol
()))
{
File
file
=
new
File
(
url
.
getFile
());
if
(
file
.
isFile
())
{
return
Resource
.
newResource
(
"jar:"
+
url
+
"!/META-INF/resources"
);
}
}
return
Resource
.
newResource
(
url
+
"META-INF/resources"
);
}
/**
* Add Jetty's {@code DefaultServlet} to the given {@link WebAppContext}.
* @param context the jetty {@link WebAppContext}
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatResources.java
View file @
1395f38e
...
...
@@ -22,7 +22,6 @@ import java.net.URL;
import
java.util.List
;
import
javax.naming.directory.DirContext
;
import
javax.servlet.ServletContext
;
import
org.apache.catalina.Context
;
import
org.apache.catalina.WebResourceRoot.ResourceSetType
;
...
...
@@ -57,6 +56,9 @@ abstract class TomcatResources {
}
addJar
(
jar
);
}
else
{
addDir
(
file
,
url
);
}
}
}
...
...
@@ -127,7 +129,7 @@ abstract class TomcatResources {
@Override
protected
void
addDir
(
String
dir
,
URL
url
)
{
if
(
getContext
()
instanceof
S
ervlet
Context
)
{
if
(
getContext
()
instanceof
S
tandard
Context
)
{
try
{
Class
<?>
fileDirContextClass
=
Class
.
forName
(
"org.apache.naming.resources.FileDirContext"
);
...
...
spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java
View file @
1395f38e
...
...
@@ -18,6 +18,7 @@ package org.springframework.boot.context.embedded.undertow;
import
java.io.File
;
import
java.io.IOException
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.nio.charset.Charset
;
...
...
@@ -465,11 +466,35 @@ public class UndertowEmbeddedServletContainerFactory
private
ResourceManager
getDocumentRootResourceManager
()
{
File
root
=
getCanonicalDocumentRoot
();
List
<
URL
>
metaInfResourceJarUrls
=
getUrlsOfJarsWithMetaInfResources
();
List
<
URL
>
metaInfResourceUrls
=
getUrlsOfJarsWithMetaInfResources
();
List
<
URL
>
resourceJarUrls
=
new
ArrayList
<
URL
>();
List
<
ResourceManager
>
resourceManagers
=
new
ArrayList
<
ResourceManager
>();
ResourceManager
rootResourceManager
=
root
.
isDirectory
()
?
new
FileResourceManager
(
root
,
0
)
:
new
JarResourceManager
(
root
);
return
new
CompositeResourceManager
(
rootResourceManager
,
new
MetaInfResourcesResourceManager
(
metaInfResourceJarUrls
));
resourceManagers
.
add
(
rootResourceManager
);
for
(
URL
url
:
metaInfResourceUrls
)
{
if
(
"file"
.
equals
(
url
.
getProtocol
()))
{
File
file
=
new
File
(
url
.
getFile
());
if
(
file
.
isFile
())
{
try
{
resourceJarUrls
.
add
(
new
URL
(
"jar:"
+
url
+
"!/"
));
}
catch
(
MalformedURLException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
else
{
resourceManagers
.
add
(
new
FileResourceManager
(
new
File
(
file
,
"META-INF/resources"
),
0
));
}
}
else
{
resourceJarUrls
.
add
(
url
);
}
}
resourceManagers
.
add
(
new
MetaInfResourcesResourceManager
(
resourceJarUrls
));
return
new
CompositeResourceManager
(
resourceManagers
.
toArray
(
new
ResourceManager
[
resourceManagers
.
size
()]));
}
/**
...
...
@@ -619,12 +644,17 @@ public class UndertowEmbeddedServletContainerFactory
}
@Override
public
Resource
getResource
(
String
path
)
throws
IOException
{
public
Resource
getResource
(
String
path
)
{
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
);
try
{
URL
resourceUrl
=
new
URL
(
url
+
"META-INF/resources"
+
path
);
URLConnection
connection
=
resourceUrl
.
openConnection
();
if
(
connection
.
getContentLength
()
>=
0
)
{
return
new
URLResource
(
resourceUrl
,
connection
,
path
);
}
}
catch
(
IOException
ex
)
{
// Continue
}
}
return
null
;
...
...
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