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
a70d293c
Commit
a70d293c
authored
Sep 20, 2013
by
Dave Syer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Re-organize the Launcher code a bit
parent
e9fd7c96
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
271 additions
and
180 deletions
+271
-180
AbstractLauncher.java
...ava/org/springframework/boot/loader/AbstractLauncher.java
+104
-0
Archive.java
...rc/main/java/org/springframework/boot/loader/Archive.java
+1
-1
ArchiveFilter.java
...n/java/org/springframework/boot/loader/ArchiveFilter.java
+26
-0
JarLauncher.java
...ain/java/org/springframework/boot/loader/JarLauncher.java
+8
-8
LaunchHelper.java
...in/java/org/springframework/boot/loader/LaunchHelper.java
+35
-91
LaunchedURLClassLoader.java
...g/springframework/boot/loader/LaunchedURLClassLoader.java
+1
-1
MainMethodRunner.java
...ava/org/springframework/boot/loader/MainMethodRunner.java
+1
-1
PropertiesLauncher.java
...a/org/springframework/boot/loader/PropertiesLauncher.java
+83
-66
WarLauncher.java
...ain/java/org/springframework/boot/loader/WarLauncher.java
+9
-9
PropertiesLauncherTests.java
.../springframework/boot/loader/PropertiesLauncherTests.java
+3
-3
No files found.
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/AbstractLauncher.java
0 → 100644
View file @
a70d293c
/*
* Copyright 2013 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
.
loader
;
import
java.io.File
;
import
java.net.URI
;
import
java.security.CodeSource
;
import
java.security.ProtectionDomain
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.logging.Logger
;
/**
* Base class for launchers that can start an application with a fully configured
* classpath.
*
* @author Phillip Webb
* @author Dave Syer
*/
public
abstract
class
AbstractLauncher
implements
ArchiveFilter
{
private
Logger
logger
=
Logger
.
getLogger
(
AbstractLauncher
.
class
.
getName
());
private
LaunchHelper
helper
=
new
LaunchHelper
();
/**
* Launch the application. This method is the initial entry point that should be
* called by a subclass {@code public static void main(String[] args)} method.
* @param args the incoming arguments
*/
public
void
launch
(
String
[]
args
)
{
try
{
launch
(
args
,
getClass
().
getProtectionDomain
());
}
catch
(
Exception
ex
)
{
ex
.
printStackTrace
();
System
.
exit
(
1
);
}
}
/**
* Launch the application given the protection domain.
* @param args the incoming arguments
* @param protectionDomain the protection domain
* @throws Exception
*/
protected
void
launch
(
String
[]
args
,
ProtectionDomain
protectionDomain
)
throws
Exception
{
CodeSource
codeSource
=
protectionDomain
.
getCodeSource
();
URI
location
=
(
codeSource
==
null
?
null
:
codeSource
.
getLocation
().
toURI
());
String
path
=
(
location
==
null
?
null
:
location
.
getPath
());
if
(
path
==
null
)
{
throw
new
IllegalStateException
(
"Unable to determine code source archive"
);
}
File
root
=
new
File
(
path
);
if
(!
root
.
exists
())
{
throw
new
IllegalStateException
(
"Unable to determine code source archive from "
+
root
);
}
Archive
archive
=
(
root
.
isDirectory
()
?
new
ExplodedArchive
(
root
)
:
new
JarFileArchive
(
root
));
launch
(
args
,
archive
);
}
/**
* Launch the application given the archive file
* @param args the incoming arguments
* @param archive the underlying (zip/war/jar) archive
* @throws Exception
*/
protected
void
launch
(
String
[]
args
,
Archive
archive
)
throws
Exception
{
List
<
Archive
>
lib
=
new
ArrayList
<
Archive
>();
lib
.
addAll
(
this
.
helper
.
findNestedArchives
(
archive
,
this
));
this
.
logger
.
fine
(
"Added "
+
lib
.
size
()
+
" entries"
);
postProcessLib
(
archive
,
lib
);
String
mainClass
=
this
.
helper
.
getMainClass
(
archive
);
this
.
helper
.
launch
(
args
,
mainClass
,
lib
);
}
/**
* Called to post-process lib entries before they are used. Implementations can add
* and remove entries.
* @param archive the archive
* @param lib the existing lib
* @throws Exception
*/
protected
void
postProcessLib
(
Archive
archive
,
List
<
Archive
>
lib
)
throws
Exception
{
}
}
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/Archive.java
View file @
a70d293c
...
@@ -22,7 +22,7 @@ import java.net.URL;
...
@@ -22,7 +22,7 @@ import java.net.URL;
import
java.util.jar.Manifest
;
import
java.util.jar.Manifest
;
/**
/**
* An archive that can be launched by the {@link Launcher}.
* An archive that can be launched by the {@link
Abstract
Launcher}.
*
*
* @author Phillip Webb
* @author Phillip Webb
* @see JarFileArchive
* @see JarFileArchive
...
...
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/ArchiveFilter.java
0 → 100644
View file @
a70d293c
/*
* Copyright 2012-2013 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
.
loader
;
/**
* @author Dave Syer
*/
public
interface
ArchiveFilter
{
public
boolean
isArchive
(
Archive
.
Entry
entry
);
}
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/JarLauncher.java
View file @
a70d293c
...
@@ -19,15 +19,19 @@ package org.springframework.boot.loader;
...
@@ -19,15 +19,19 @@ package org.springframework.boot.loader;
import
java.util.List
;
import
java.util.List
;
/**
/**
* {@link
Launcher} for JAR based archives. This launcher assumes that dependency jars are
* {@link
AbstractLauncher} for JAR based archives. This launcher assumes that dependency
* included inside a {@code /lib} directory.
*
jars are
included inside a {@code /lib} directory.
*
*
* @author Phillip Webb
* @author Phillip Webb
*/
*/
public
class
JarLauncher
extends
Launcher
{
public
class
JarLauncher
extends
AbstractLauncher
{
public
static
void
main
(
String
[]
args
)
{
new
JarLauncher
().
launch
(
args
);
}
@Override
@Override
p
rotected
boolean
isNested
Archive
(
Archive
.
Entry
entry
)
{
p
ublic
boolean
is
Archive
(
Archive
.
Entry
entry
)
{
return
!
entry
.
isDirectory
()
&&
entry
.
getName
().
startsWith
(
"lib/"
);
return
!
entry
.
isDirectory
()
&&
entry
.
getName
().
startsWith
(
"lib/"
);
}
}
...
@@ -36,8 +40,4 @@ public class JarLauncher extends Launcher {
...
@@ -36,8 +40,4 @@ public class JarLauncher extends Launcher {
lib
.
add
(
0
,
archive
);
lib
.
add
(
0
,
archive
);
}
}
public
static
void
main
(
String
[]
args
)
{
new
JarLauncher
().
launch
(
args
);
}
}
}
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/Launcher.java
→
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/Launch
Help
er.java
View file @
a70d293c
/*
/*
* Copyright 2013 the original author or authors.
* Copyright 201
2-201
3 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,110 +16,71 @@
...
@@ -16,110 +16,71 @@
package
org
.
springframework
.
boot
.
loader
;
package
org
.
springframework
.
boot
.
loader
;
import
java.io.File
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Constructor
;
import
java.net.URI
;
import
java.net.URL
;
import
java.net.URL
;
import
java.security.CodeSource
;
import
java.security.ProtectionDomain
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
java.util.jar.JarEntry
;
import
java.util.logging.Logger
;
import
java.util.logging.Logger
;
/**
/**
* Base class for launchers that can start an application with a fully configured
* Common convenience methods shared by launcher implementations.
* classpath.
*
*
* @author
Phillip Webb
* @author
Dave Syer
*/
*/
public
abstract
class
Launch
er
{
public
class
LaunchHelp
er
{
private
Logger
logger
=
Logger
.
getLogger
(
Launcher
.
class
.
getName
());
private
Logger
logger
=
Logger
.
getLogger
(
Launch
Help
er
.
class
.
getName
());
/**
/**
* The main runner class. This must be loaded by the created ClassLoader so cannot be
* The main runner class. This must be loaded by the created ClassLoader so cannot be
* directly referenced.
* directly referenced.
*/
*/
private
static
final
String
RUNNER_CLASS
=
Launcher
.
class
.
getPackage
().
getNam
e
()
private
static
final
String
RUNNER_CLASS
=
AbstractLauncher
.
class
.
getPackag
e
()
+
".MainMethodRunner"
;
.
getName
()
+
".MainMethodRunner"
;
/**
/**
* Launch the application. This method is the initial entry point that should be
* called by a subclass {@code public static void main(String[] args)} method.
* @param args the incoming arguments
* @param args the incoming arguments
*/
* @param mainClass the main class
public
void
launch
(
String
[]
args
)
{
* @param lib a collection of archives (zip/jar/war or directory)
try
{
launch
(
args
,
getClass
().
getProtectionDomain
());
}
catch
(
Exception
ex
)
{
ex
.
printStackTrace
();
System
.
exit
(
1
);
}
}
/**
* Launch the application given the protection domain.
* @param args the incoming arguments
* @param protectionDomain the protection domain
* @throws Exception
* @throws Exception
*/
*/
p
rotected
void
launch
(
String
[]
args
,
ProtectionDomain
protectionDomain
)
p
ublic
void
launch
(
String
[]
args
,
String
mainClass
,
List
<
Archive
>
lib
)
throws
Exception
{
throws
Exception
{
CodeSource
codeSource
=
protectionDomain
.
getCodeSource
();
ClassLoader
classLoader
=
createClassLoader
(
lib
);
URI
location
=
(
codeSource
==
null
?
null
:
codeSource
.
getLocation
().
toURI
());
launch
(
args
,
mainClass
,
classLoader
);
String
path
=
(
location
==
null
?
null
:
location
.
getPath
());
if
(
path
==
null
)
{
throw
new
IllegalStateException
(
"Unable to determine code source archive"
);
}
File
root
=
new
File
(
path
);
if
(!
root
.
exists
())
{
throw
new
IllegalStateException
(
"Unable to determine code source archive from "
+
root
);
}
Archive
archive
=
(
root
.
isDirectory
()
?
new
ExplodedArchive
(
root
)
:
new
JarFileArchive
(
root
));
launch
(
args
,
archive
);
}
}
/**
/**
* Launch the application given the archive file
* @param archive the archive to search
* @param args the incoming arguments
* @return an accumulation of nested archives
* @param archive the underlying (zip/war/jar) archive
* @throws Exception
* @throws Exception
*/
*/
protected
void
launch
(
String
[]
args
,
Archive
archive
)
throws
Exception
{
public
List
<
Archive
>
findNestedArchives
(
Archive
archive
,
ArchiveFilter
filter
)
throws
Exception
{
List
<
Archive
>
lib
=
new
ArrayList
<
Archive
>();
List
<
Archive
>
lib
=
new
ArrayList
<
Archive
>();
for
(
Archive
.
Entry
entry
:
archive
.
getEntries
())
{
for
(
Archive
.
Entry
entry
:
archive
.
getEntries
())
{
if
(
isNested
Archive
(
entry
))
{
if
(
filter
.
is
Archive
(
entry
))
{
this
.
logger
.
fine
(
"Adding: "
+
entry
.
getName
());
this
.
logger
.
fine
(
"Adding: "
+
entry
.
getName
());
lib
.
add
(
archive
.
getNestedArchive
(
entry
));
lib
.
add
(
archive
.
getNestedArchive
(
entry
));
}
}
}
}
return
lib
;
this
.
logger
.
fine
(
"Added "
+
lib
.
size
()
+
" entries"
);
postProcessLib
(
archive
,
lib
);
ClassLoader
classLoader
=
createClassLoader
(
lib
);
launch
(
args
,
archive
,
classLoader
);
}
}
/**
/**
* Determine if the specified {@link JarEntry} is a nested item that should be added
* Obtain the main class that should be used to launch the application. By default
* to the classpath. The method is called once for each entry.
* this method uses a {@code Start-Class} manifest entry.
* @param jarEntry the jar entry
* @return {@code true} if the entry is a nested item (jar or folder)
*/
protected
abstract
boolean
isNestedArchive
(
Archive
.
Entry
jarEntry
);
/**
* Called to post-process lib entries before they are used. Implementations can add
* and remove entries.
* @param archive the archive
* @param archive the archive
* @
param lib the existing lib
* @
return the main class
* @throws Exception
* @throws Exception
*/
*/
protected
void
postProcessLib
(
Archive
archive
,
List
<
Archive
>
lib
)
throws
Exception
{
public
String
getMainClass
(
Archive
archive
)
throws
Exception
{
String
mainClass
=
archive
.
getManifest
().
getMainAttributes
()
.
getValue
(
"Start-Class"
);
if
(
mainClass
==
null
)
{
throw
new
IllegalStateException
(
"No 'Start-Class' manifest entry specified"
);
}
return
mainClass
;
}
}
/**
/**
...
@@ -136,26 +97,15 @@ public abstract class Launcher {
...
@@ -136,26 +97,15 @@ public abstract class Launcher {
return
createClassLoader
(
urls
);
return
createClassLoader
(
urls
);
}
}
/**
* Create a classloader for the specified URLs
* @param urls the URLs
* @return the classloader
* @throws Exception
*/
protected
ClassLoader
createClassLoader
(
URL
[]
urls
)
throws
Exception
{
return
new
LaunchedURLClassLoader
(
urls
,
getClass
().
getClassLoader
());
}
/**
/**
* Launch the application given the archive file and a fully configured classloader.
* Launch the application given the archive file and a fully configured classloader.
* @param args the incoming arguments
* @param args the incoming arguments
* @param
archive the archive
* @param
mainClass the main class to run
* @param classLoader the classloader
* @param classLoader the classloader
* @throws Exception
* @throws Exception
*/
*/
protected
void
launch
(
String
[]
args
,
Archive
archive
,
ClassLoader
classLoader
)
protected
void
launch
(
String
[]
args
,
String
mainClass
,
ClassLoader
classLoader
)
throws
Exception
{
throws
Exception
{
String
mainClass
=
getMainClass
(
archive
);
Runnable
runner
=
createMainMethodRunner
(
mainClass
,
args
,
classLoader
);
Runnable
runner
=
createMainMethodRunner
(
mainClass
,
args
,
classLoader
);
Thread
runnerThread
=
new
Thread
(
runner
);
Thread
runnerThread
=
new
Thread
(
runner
);
runnerThread
.
setContextClassLoader
(
classLoader
);
runnerThread
.
setContextClassLoader
(
classLoader
);
...
@@ -164,19 +114,13 @@ public abstract class Launcher {
...
@@ -164,19 +114,13 @@ public abstract class Launcher {
}
}
/**
/**
* Obtain the main class that should be used to launch the application. By default
* Create a classloader for the specified URLs
* this method uses a {@code Start-Class} manifest entry.
* @param urls the URLs
* @param archive the archive
* @return the classloader
* @return the main class
* @throws Exception
* @throws Exception
*/
*/
protected
String
getMainClass
(
Archive
archive
)
throws
Exception
{
protected
ClassLoader
createClassLoader
(
URL
[]
urls
)
throws
Exception
{
String
mainClass
=
archive
.
getManifest
().
getMainAttributes
()
return
new
LaunchedURLClassLoader
(
urls
,
getClass
().
getClassLoader
());
.
getValue
(
"Start-Class"
);
if
(
mainClass
==
null
)
{
throw
new
IllegalStateException
(
"No 'Start-Class' manifest entry specified"
);
}
return
mainClass
;
}
}
/**
/**
...
...
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/LaunchedURLClassLoader.java
View file @
a70d293c
...
@@ -25,7 +25,7 @@ import java.security.PrivilegedExceptionAction;
...
@@ -25,7 +25,7 @@ import java.security.PrivilegedExceptionAction;
import
org.springframework.boot.loader.jar.RandomAccessJarFile
;
import
org.springframework.boot.loader.jar.RandomAccessJarFile
;
/**
/**
* {@link ClassLoader} used by the {@link Launcher}.
* {@link ClassLoader} used by the {@link
Abstract
Launcher}.
*
*
* @author Phillip Webb
* @author Phillip Webb
*/
*/
...
...
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/MainMethodRunner.java
View file @
a70d293c
...
@@ -19,7 +19,7 @@ package org.springframework.boot.loader;
...
@@ -19,7 +19,7 @@ package org.springframework.boot.loader;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
/**
/**
* Utility class that used by {@link Launcher}s to call a main method. This class allows
* Utility class that used by {@link
Abstract
Launcher}s to call a main method. This class allows
* methods to be executed within a thread configured with a specific context classloader.
* methods to be executed within a thread configured with a specific context classloader.
*
*
* @author Phillip Webb
* @author Phillip Webb
...
...
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/PropertiesLauncher.java
View file @
a70d293c
...
@@ -23,7 +23,6 @@ import java.io.InputStream;
...
@@ -23,7 +23,6 @@ import java.io.InputStream;
import
java.net.HttpURLConnection
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.net.URLConnection
;
import
java.security.ProtectionDomain
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
...
@@ -33,8 +32,8 @@ import java.util.logging.Logger;
...
@@ -33,8 +32,8 @@ import java.util.logging.Logger;
import
org.springframework.boot.loader.util.SystemPropertyUtils
;
import
org.springframework.boot.loader.util.SystemPropertyUtils
;
/**
/**
* {@link
Launcher} for archives with user-configured classpath and main class via
a
* {@link
AbstractLauncher} for archives with user-configured classpath and main class vi
a
* properties file. This model is often more flexible and more amenable to creating
*
a
properties file. This model is often more flexible and more amenable to creating
* well-behaved OS-level services than a model based on executable jars.
* well-behaved OS-level services than a model based on executable jars.
*
*
* <p>
* <p>
...
@@ -49,19 +48,20 @@ import org.springframework.boot.loader.util.SystemPropertyUtils;
...
@@ -49,19 +48,20 @@ import org.springframework.boot.loader.util.SystemPropertyUtils;
* System properties in case the file doesn't exist):
* System properties in case the file doesn't exist):
*
*
* <ul>
* <ul>
* <li><code>loader.path</code>: a comma-separated list of
classpath directories
* <li><code>loader.path</code>: a comma-separated list of
directories to append to the
*
(containing file resources and/or archives in *.jar or *.zip). Defaults to
*
classpath (containing file resources and/or nested archives in *.jar or *.zip).
* <code>lib</code> (i.e. a directory in the current working directory)</li>
*
Defaults to
<code>lib</code> (i.e. a directory in the current working directory)</li>
* <li><code>loader.main</code>: the main method to delegate execution to once the class
* <li><code>loader.main</code>: the main method to delegate execution to once the class
* loader is set up. No default, but will fall back to looking in a
* loader is set up. No default, but will fall back to looking for a
* <code>MANIFEST.MF</code> if there is one.</li>
* <code>Start-Class</code> in a <code>MANIFEST.MF</code>, if there is one in
* <code>${loader.home}/META-INF</code>.</li>
* </ul>
* </ul>
*
*
* @author Dave Syer
* @author Dave Syer
*/
*/
public
class
PropertiesLauncher
extends
Launch
er
{
public
class
PropertiesLauncher
implements
ArchiveFilt
er
{
private
Logger
logger
=
Logger
.
getLogger
(
Launcher
.
class
.
getName
());
private
Logger
logger
=
Logger
.
getLogger
(
Abstract
Launcher
.
class
.
getName
());
/**
/**
* Properties key for main class
* Properties key for main class
...
@@ -85,10 +85,32 @@ public class PropertiesLauncher extends Launcher {
...
@@ -85,10 +85,32 @@ public class PropertiesLauncher extends Launcher {
private
Properties
properties
=
new
Properties
();
private
Properties
properties
=
new
Properties
();
private
LaunchHelper
helper
=
new
LaunchHelper
();
public
static
void
main
(
String
[]
args
)
{
new
PropertiesLauncher
().
launch
(
args
);
}
/**
* Launch the application. This method is the initial entry point that should be
* called by a subclass {@code public static void main(String[] args)} method.
* @param args the incoming arguments
*/
public
void
launch
(
String
[]
args
)
{
try
{
File
home
=
getHomeDirectory
();
initialize
(
home
);
this
.
helper
.
launch
(
args
,
getMainClass
(
home
),
getLibrary
(
home
,
this
.
paths
));
}
catch
(
Exception
ex
)
{
ex
.
printStackTrace
();
System
.
exit
(
1
);
}
}
@Override
@Override
protected
void
launch
(
String
[]
args
,
ProtectionDomain
protectionDomain
)
public
boolean
isArchive
(
Archive
.
Entry
entry
)
{
throws
Exception
{
return
entry
.
isDirectory
()
||
isArchive
(
entry
.
getName
());
launch
(
args
,
new
ExplodedArchive
(
getHomeDirectory
()));
}
}
protected
File
getHomeDirectory
()
{
protected
File
getHomeDirectory
()
{
...
@@ -96,28 +118,62 @@ public class PropertiesLauncher extends Launcher {
...
@@ -96,28 +118,62 @@ public class PropertiesLauncher extends Launcher {
"${user.dir}"
)));
"${user.dir}"
)));
}
}
/**
protected
String
getMainClass
(
File
home
)
throws
Exception
{
* Look in various places for a properties file to extract loader settings. Default to
if
(
System
.
getProperty
(
MAIN
)
!=
null
)
{
* <code>application.properties</code> either on the current classpath or in the
return
SystemPropertyUtils
.
resolvePlaceholders
(
System
.
getProperty
(
MAIN
));
* current working directory.
}
* @see org.springframework.boot.loader.Launcher#launch(java.lang.String[],
if
(
this
.
properties
.
containsKey
(
MAIN
))
{
* org.springframework.boot.loader.Archive)
return
SystemPropertyUtils
.
resolvePlaceholders
(
this
.
properties
*/
.
getProperty
(
MAIN
));
@Override
}
protected
void
launch
(
String
[]
args
,
Archive
archive
)
throws
Exception
{
return
this
.
helper
.
getMainClass
(
new
ExplodedArchive
(
home
));
initialize
();
super
.
launch
(
args
,
archive
);
}
}
protected
void
initialize
()
throws
Exception
{
protected
void
initialize
(
File
home
)
throws
Exception
{
initializeProperties
();
initializeProperties
(
home
);
initializePaths
();
initializePaths
();
}
}
private
void
initializeProperties
()
throws
Exception
,
IOException
{
private
boolean
isArchive
(
String
name
)
{
return
name
.
endsWith
(
".jar"
)
||
name
.
endsWith
(
".zip"
);
}
/**
* Search the configured paths and look for nested archives.
*
* @param home the home directory for this launch
* @param paths the directory roots for classpath entries
* @return a library of archives that can be used as a classpath
* @throws Exception
*/
private
List
<
Archive
>
getLibrary
(
File
home
,
List
<
String
>
paths
)
throws
Exception
{
List
<
Archive
>
lib
=
new
ArrayList
<
Archive
>();
for
(
String
path
:
paths
)
{
String
root
=
cleanupPath
(
stripFileUrlPrefix
(
path
));
File
file
=
new
File
(
root
);
if
(!
root
.
startsWith
(
"/"
))
{
file
=
new
File
(
home
,
root
);
}
if
(
file
.
isDirectory
())
{
this
.
logger
.
info
(
"Adding classpath entries from "
+
path
);
Archive
archive
=
new
ExplodedArchive
(
file
);
lib
.
addAll
(
this
.
helper
.
findNestedArchives
(
archive
,
this
));
lib
.
add
(
0
,
archive
);
}
else
{
this
.
logger
.
info
(
"No directory found at "
+
path
);
}
}
return
lib
;
}
private
void
initializeProperties
(
File
home
)
throws
Exception
,
IOException
{
String
config
=
SystemPropertyUtils
.
resolvePlaceholders
(
System
.
getProperty
(
String
config
=
SystemPropertyUtils
.
resolvePlaceholders
(
System
.
getProperty
(
CONFIG_NAME
,
"application"
))
+
".properties"
;
CONFIG_NAME
,
"application"
))
+
".properties"
;
InputStream
resource
=
getClasspathResource
(
config
);
InputStream
resource
=
getClasspathResource
(
config
);
if
(
resource
==
null
)
{
resource
=
getResource
(
new
File
(
home
,
config
).
getAbsolutePath
());
}
if
(
resource
==
null
)
{
if
(
resource
==
null
)
{
config
=
SystemPropertyUtils
.
resolvePlaceholders
(
System
.
getProperty
(
config
=
SystemPropertyUtils
.
resolvePlaceholders
(
System
.
getProperty
(
CONFIG_LOCATION
,
config
));
CONFIG_LOCATION
,
config
));
...
@@ -262,43 +318,4 @@ public class PropertiesLauncher extends Launcher {
...
@@ -262,43 +318,4 @@ public class PropertiesLauncher extends Launcher {
return
path
;
return
path
;
}
}
@Override
protected
boolean
isNestedArchive
(
Archive
.
Entry
entry
)
{
String
name
=
entry
.
getName
();
for
(
String
path
:
this
.
paths
)
{
if
(
path
.
length
()
>
0
)
{
if
((
entry
.
isDirectory
()
&&
name
.
equals
(
path
))
||
(!
entry
.
isDirectory
()
&&
name
.
startsWith
(
path
)
&&
isArchive
(
name
)))
{
return
true
;
}
}
}
return
false
;
}
private
boolean
isArchive
(
String
name
)
{
return
name
.
endsWith
(
".jar"
)
||
name
.
endsWith
(
".zip"
);
}
@Override
protected
void
postProcessLib
(
Archive
archive
,
List
<
Archive
>
lib
)
throws
Exception
{
lib
.
add
(
0
,
archive
);
}
@Override
protected
String
getMainClass
(
Archive
archive
)
throws
Exception
{
if
(
System
.
getProperty
(
MAIN
)
!=
null
)
{
return
SystemPropertyUtils
.
resolvePlaceholders
(
System
.
getProperty
(
MAIN
));
}
if
(
this
.
properties
.
containsKey
(
MAIN
))
{
return
SystemPropertyUtils
.
resolvePlaceholders
(
this
.
properties
.
getProperty
(
MAIN
));
}
return
super
.
getMainClass
(
archive
);
}
public
static
void
main
(
String
[]
args
)
{
new
PropertiesLauncher
().
launch
(
args
);
}
}
}
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/WarLauncher.java
View file @
a70d293c
...
@@ -20,16 +20,20 @@ import java.io.IOException;
...
@@ -20,16 +20,20 @@ import java.io.IOException;
import
java.util.List
;
import
java.util.List
;
/**
/**
* {@link
Launcher} for WAR based archives. This launcher for standard WAR archives.
* {@link
AbstractLauncher} for WAR based archives. This launcher for standard WAR
*
Supports dependencies in {@code WEB-INF/lib} as well as {@code WEB-INF/lib-provided},
*
archives. Supports dependencies in {@code WEB-INF/lib} as well as
* classes are loaded from {@code WEB-INF/classes}.
*
{@code WEB-INF/lib-provided},
classes are loaded from {@code WEB-INF/classes}.
*
*
* @author Phillip Webb
* @author Phillip Webb
*/
*/
public
class
WarLauncher
extends
Launcher
{
public
class
WarLauncher
extends
AbstractLauncher
{
public
static
void
main
(
String
[]
args
)
{
new
WarLauncher
().
launch
(
args
);
}
@Override
@Override
p
rotected
boolean
isNested
Archive
(
Archive
.
Entry
entry
)
{
p
ublic
boolean
is
Archive
(
Archive
.
Entry
entry
)
{
if
(
entry
.
isDirectory
())
{
if
(
entry
.
isDirectory
())
{
return
entry
.
getName
().
equals
(
"WEB-INF/classes/"
);
return
entry
.
getName
().
equals
(
"WEB-INF/classes/"
);
}
}
...
@@ -64,8 +68,4 @@ public class WarLauncher extends Launcher {
...
@@ -64,8 +68,4 @@ public class WarLauncher extends Launcher {
});
});
}
}
public
static
void
main
(
String
[]
args
)
{
new
WarLauncher
().
launch
(
args
);
}
}
}
spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/PropertiesLauncherTests.java
View file @
a70d293c
...
@@ -48,14 +48,14 @@ public class PropertiesLauncherTests {
...
@@ -48,14 +48,14 @@ public class PropertiesLauncherTests {
@Test
@Test
public
void
testUserSpecifiedMain
()
throws
Exception
{
public
void
testUserSpecifiedMain
()
throws
Exception
{
this
.
launcher
.
initialize
();
this
.
launcher
.
initialize
(
new
File
(
"."
)
);
assertEquals
(
"demo.Application"
,
this
.
launcher
.
getMainClass
(
null
));
assertEquals
(
"demo.Application"
,
this
.
launcher
.
getMainClass
(
null
));
}
}
@Test
@Test
public
void
testUserSpecifiedConfigName
()
throws
Exception
{
public
void
testUserSpecifiedConfigName
()
throws
Exception
{
System
.
setProperty
(
"loader.config.name"
,
"foo"
);
System
.
setProperty
(
"loader.config.name"
,
"foo"
);
this
.
launcher
.
initialize
();
this
.
launcher
.
initialize
(
new
File
(
"."
)
);
assertEquals
(
"my.Application"
,
this
.
launcher
.
getMainClass
(
null
));
assertEquals
(
"my.Application"
,
this
.
launcher
.
getMainClass
(
null
));
assertEquals
(
"[etc/]"
,
ReflectionTestUtils
.
getField
(
this
.
launcher
,
"paths"
)
assertEquals
(
"[etc/]"
,
ReflectionTestUtils
.
getField
(
this
.
launcher
,
"paths"
)
.
toString
());
.
toString
());
...
@@ -64,7 +64,7 @@ public class PropertiesLauncherTests {
...
@@ -64,7 +64,7 @@ public class PropertiesLauncherTests {
@Test
@Test
public
void
testSystemPropertySpecifiedMain
()
throws
Exception
{
public
void
testSystemPropertySpecifiedMain
()
throws
Exception
{
System
.
setProperty
(
"loader.main"
,
"foo.Bar"
);
System
.
setProperty
(
"loader.main"
,
"foo.Bar"
);
this
.
launcher
.
initialize
();
this
.
launcher
.
initialize
(
new
File
(
"."
)
);
assertEquals
(
"foo.Bar"
,
this
.
launcher
.
getMainClass
(
null
));
assertEquals
(
"foo.Bar"
,
this
.
launcher
.
getMainClass
(
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