Commit Graph

277 Commits (67f92bff1eb2500cf6ed647f61f2ab54060c6caa)

Author SHA1 Message Date
Andy Wilkinson 4f200a852b Add missing jar file
It should have been in 68b83a8f but was excluded by gitignore.

See gh-3701
9 years ago
Andy Wilkinson 68b83a8f00 Improve handling of loader.path in PropertiesLauncher
Previously, if loader.path directly specified a jar file that contained
nested archives (.zip or .jar), launching would fail unless those
nested archives were uncompressed. However, if loader.path specified a
directory that contained such a jar file the launch would succeed. This
was because the nested archives within the jar were ignored.

This commit updates PropertiesLauncher so that its behaviour in the
scenarios described above is consistent by not looking for archives
nested with a jar that’s be specified on loader.path. The javadoc for
loader.path has also been updated to make it clear that loader.path
can points to directories or jar files, bringing it into line with
the reference guide.

Closes gh-3701
9 years ago
Andy Wilkinson 313b6f6451 Simplify exception handling and reporting in the launcher
Following changes to LaunchedURLClassLoader made in 87fe0b2a, it is
no longer necessary for the launcher to load MainMethodRunner via
reflection as both the app class loader that the launcher URL class
loader share the same MainMethodRunner class.

This commit takes advantage of this by updating Launcher to instantiate
MainMethodRunner directly rather than via reflection, removing one
source of possible exceptions in the launcher.

As the MainMethodRunner is now loaded directly and its class is shared
between the two class loaders, there’s no longer a need for it to
implement Runnable. This allows it to throw Exception from its run
method, rather than having to wrap any Exception in a RuntimeException.

Lastly, rather than catching any exception thrown from the launch,
Launcher and its subclasses have been updated to allow this exception
to be thrown from the main method. This allows the Exception to reach
the JVM, to be processed by our registered uncaught exception handler,
and to trigger the JVM’s standard processing for exiting due to a
failure. This removes the need for the Launcher itself to call
System.exit(1) and ensures that the exception is only output to the
console if it hasn’t been registered as a logged exception.

Closes gh-5358
9 years ago
Phillip Webb faba7a9514 Rename internal OutputCapture classes
Rename the internal versions of OutputCapture to prevent accidental
import.

See gh-5492
9 years ago
Andy Wilkinson c42f859390 Ensure that ExplodedArchive lists its file in a consistent order
Closes gh-5422
9 years ago
Andy Wilkinson c0b74119e0 Use manifest from class’s jar when defining its package
Previously, when defining a package for a class, LaunchedURLClassLoader
would use the manifest from the first location that contained the
required package. If the package was split across multiple locations,
this could lead to the manifest from a jar other than the one that
contains the class being used.

This commit updates LaunchedURLClassLoader so that it will use the
manifest of the jar file that contains the class which triggered the
definition of the package.

Closes gh-5485
9 years ago
Andy Wilkinson 1d099035b1 Protect against a race condition when defining packages
LaunchedURLClassLoader preemptively defines the package for any
classes that it attempts to load so that the manifest from a nested
jar is correctly associated with the package. This can lead to a race
where the package is defined on two threads in parallel, resulting
in an IllegalArgumentException being thrown.

This problem was manifesting itself as a NoClassDefFoundError.
If the initialization of a class failed due to the above-described
IllegalArgumentException, subsequent attempts to use that class
would then fail with a NoClassDefFoundError.

This commit updates LaunchedURLClassLoader to catch the
IllegalArgumentException and then double-check that the package has
already been defined. This approach, including thrown an
AssertionError when the second check fails, is modelled on the
approach taken by URLClassLoader.

Closes gh-5464
9 years ago
Andy Wilkinson 427d3140b3 Remove unwanted printing of stack trace from the Launcher
Previously, the Launcher would call ex.printStackTrace for any
exception that was thrown when launching the application. This was
unnecessary as the stack trace should already have been logged by
the application when it failed to start.

This commit removes the call to ex.printStackTrace, thereby allowing
an exception to be logged only once or not at all after successful
failure analysis.

Closes gh-5358
9 years ago
Andy Wilkinson 44ddfcc7fa Upgrade copyright headers of all files changed in 2016 9 years ago
Andy Wilkinson d9382244d8 Handle mixture of encoded and unencoded chars in JarURLConnection
Previously, JarURLConnection would corrupt a URL that contained a
mixture of encoded and unencoded double-byte characters. URLs that
only contained unencoded double-byte characters were not affected as
they are passed through as-is.

This commit updates JarURLConnection.JarEntryName to correctly handle
characters with a value that won't fit in a single signed byte (a
value greater than 127). Such characters are now URL encoded and then
written to the output stream as multiple bytes.

Closes gh-5194
9 years ago
Phillip Webb 89b7704977 Extract spring-boot-test.jar
Relocate the `org.springframework.boot.test` package from the
`spring-boot.jar` to `spring-boot-test.jar`.

Fixes gh-5184
9 years ago
Andy Wilkinson 87fe0b2ade Use a conventional delegation model in LaunchedURLClassLoader
When an application is run as an executable archive with nested jars,
the application's own classes need to be able to load classes from
within the nested jars. This means that the application's classes need
to be loaded by the same class loader as is used for the nested jars.
When an application is launched with java -jar the contents of the
jar are on the class path of the app class loader, which is the
parent of the LaunchedURLClassLoader that is used to load classes
from within the nested jars. If the root of the jar includes the
application's classes, they would be loaded by the app class loader
and, therefore, would not be able to load classes from within the
nested jars.

Previously, this problem was resolved by LaunchedURLClassLoader being
created with a copy of all of the app class laoder's URLs and by
using an unconventional delegation model that caused it to skip its
parent (the app class loader) and jump straight to its root class
loader. This ensured that the LaunchedURLClassLoader would load both
the application's own classes and those from within any nested jars.
Unfortunately, this unusual delegation model has proved to be
problematic. We have seen and worked around some problems with Java
Agents (see gh-4911 and gh-863), but there are others (see gh-4868)
that cannot be made to work with the current delegation model.

This commit reworks LaunchedURLClassLoader to use a conventional
delegate model with the app class loader as its parent. With this
change in place, the application's own classes need to be hidden
from the app class loader via some other means. This is now achieved
by packaging application classes in BOOT-INF/classes (and, for
symmetry, nested jars are now packaged in BOOT-INF/lib). Both the
JarLauncher and the PropertiesLauncher (which supports the executable
jar layout) have been updated to look for classes and nested jars in
these new locations.

Closes gh-4897
Fixes gh-4868
9 years ago
Phillip Webb 00cfe1d054 Use AssertJ in spring-boot-tools
See gh-5083
9 years ago
Andy Wilkinson 9dbef5d9b0 Remove use a separate runner thread from the Launcher
Previously, the Launcher was creating a new runner thread that would
call the application's main method. An exception thrown by this thread
is handled differently to one thrown by the JVM's main thread leading
to different exit behaviour. Furthermore, the separate thread isn't
actually necessary.

This commit removew the use of a separate runner thread from the
Launcher. This means that the JVM's exit behaviour will be consistent
and also removes the overhead of createing a starting an extra thread.

Closes gh-5006
9 years ago
Johnny Lim 46540de694 Fix typos
Closes gh-5067
9 years ago
Phillip Webb acbb4e63f2 Clear caches on ApplicationContext load
Ensure that JarFile caches are cleared once the ApplicationContext has
loaded. Caches are cleared manually with the assumption that no
further class loading is likely.

Closes gh-4882
9 years ago
Phillip Webb e2368b909b Reduce memory consumption of fat/exploded jars
Refactor `spring-boot-loader` to reduce the amount of memory required
to load fat & exploded jars. Jar files now no longer store a full list
of entry data records, but instead use an array of entry name hashes.

Since ClassLoaders often ask each JAR if they contain a particular
entry (and mostly they do not), the hash array provides a quick way to
deal with misses. Only when a hash does exist is data actually loaded
from the underlying file.

In addition to the JarFile changes, the Archive abstraction has also
been updated to reduce memory consumption.

See gh-4882
9 years ago
Phillip Webb 858a854ce1 Drop use of loggers in Launchers
Remove the use of JDK loggers in Launcher and PropertiesLauncher to
ensure allow the custom Log4j2 `LogManager` to be used with Spring Boot
applications.

Fixes gh-3815
9 years ago
Phillip Webb fbaf209240 Move master to 1.4.0.BUILD-SNAPSHOT 9 years ago
Spring Buildmaster 504d3e97ba Next development version 9 years ago
Phillip Webb 93c3b22bb4 Merge branch '1.2.x' 9 years ago
Phillip Webb c71aa32fbb Polish 9 years ago
Andy Wilkinson 2dc3660a32 Align launcher exception handling with direct invocation of main method
Previously, if an application’s main method threw an exception,
MainMethodRunner would catch the exception and call System.exit(1).
This meant that the JVM would exit, irrespective of whether or not
any non-daemon threads were running. In contrast, when an application’s
main method was invoked directly (in an IDE, for example) the JVM
would not exit if one or more non-daemon threads were running. This
is standard JVM behaviour that we should be consistent with in the
launcher.

This commit updates MainMethodRunner to wrap any exception thrown by an
application’s main method in a RuntimeException and rethrow it. This
alllows the JVM to handle the exception and use its normal rules for
deciding whether or not it should exit.

Closes gh-4984
9 years ago
Andy Wilkinson 89beef4099 Merge branch '1.2.x' 9 years ago
Andy Wilkinson 681a866cce Exclude Java agents from class loader created by PropertiesLauncher
PropertiesLauncher creates a ClassLoader that is used by the Launcher
to load an application’s classes. During the creation of this
ClassLoader URLs from its ClassLoader. This resulted resulting in Java
agents that are added to the system class loader via the -javaagent
launch option being available on both the system class loader and the
created class loader. Java agents are intended to always be loaded by
the system class loader. Making them available on another class loader
breaks this model.

This is the same problem that was in ExecutableArchiveLauncher and
that was fixed in ee08667e (see gh-863).

This commit updates PropertiesLauncher so that it skips the URLs of
any Java agents (found by examining the JVM’s input arguments) when
copying URLs over to the new ClassLoader, thereby ensuring that Java
agents are only ever loaded by the system class loader.

Closes gh-4911
9 years ago
Andy Wilkinson 27a81e1463 Complete static final logger changes that were started in ec2f33f9
This commit completes the changes to consistently used static final
fields for Log instances that were started in ec2f33f9. Specifically it:

 - Removes this. when accessing logger fields that are now static
 - Renames some fields from log to logger
 - Makes some logger fields static

See gh-4784
9 years ago
Phillip Webb 7397dbaf57 Allow ExitCodeGenerator to be used on Exceptions
Update exit code support to allow the ExitCodeGenerator interface to
be placed on an Exception. Any uncaught exception implementing the
interface and returning a non `0` status will now trigger a System.exit
with the code.

Fixes gh-4803
9 years ago
Andy Wilkinson 2aff82bb64 Merge branch '1.2.x' 9 years ago
Andy Wilkinson 6117b6c5c8 Consistent use of tabs for indentation in pom files 9 years ago
Spring Buildmaster 8db59059a5 Next Development Version 9 years ago
Stephane Nicoll bb736e255b Fix SNAPSHOT version 9 years ago
Kirill Vlasov ec2f33f986 Make loggers private static final
Apply consistency across all static loggers.

Closes gh-4784
9 years ago
Phillip Webb 2694605a4d Polish 9 years ago
Vladimir Tsanev 939b66f4ee Use fast exceptions in findResource(s)
Some libraries like aspectj are using findResource to see the raw
bytecode of a class. It will even call findResource for every method of
every class of beans that are post processed. This can be significant
performance hit on startup when LaunchedURLClassLoader and there are a
lot of nested jars.

See gh-3640
Fixes gh-4557
9 years ago
Vladimir Tsanev 1e2f133892 Use fast exceptions in findResource(s)
Some libraries like aspectj are using findResource to see the raw
bytecode of a class. It will even call findResource for every method of
every class of beans that are post processed. This can be significant
performance hit on startup when LaunchedURLClassLoader and there are a
lot of nested jars.

See gh-3640
Fixes gh-4557
9 years ago
Johnny Lim 8ec00c35bf Polish
Closes gh-4572
9 years ago
Spring Buildmaster 3f6f57a80e Next Development Version 9 years ago
Johnny Lim 0a85281a66 Fix typos
Closes gh-4463
9 years ago
Phillip Webb 6c2ea4648f Polish 9 years ago
Andy Wilkinson 17f61c1dad Update javadoc of LaunchedURLClassLoader to describe delegation model
Closes gh-3864
9 years ago
Phillip Webb 1e4d974ec0 Merge remote-tracking branch 'local12x/1.2.x' 9 years ago
Phillip Webb a79131f8d2 Organize imports with new settings
See gh-4234
9 years ago
Spring Buildmaster 2b38a861e3 Next Development Version 9 years ago
Andy Wilkinson 30f24eac0a Merge branch '1.2.x' 9 years ago
Andy Wilkinson 7e718cda26 Remove redundant hash from path of unpacked nested library
Closes gh-4124
9 years ago
Phillip Webb 04074fece1 Merge branch '1.2.x' 9 years ago
Phillip Webb 94736719f1 Reformat package-info.java files with Eclipse Mars 9 years ago
Andy Wilkinson 2afb641603 Merge branch '1.2.x' 9 years ago
Andy Wilkinson 04c2bd9c89 Update tests to expect additional entry in test jar
Closes gh-4124
9 years ago
Andy Wilkinson 8948322d7a Merge branch '1.2.x' 9 years ago