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
2c2b9622
Commit
2c2b9622
authored
Jun 17, 2019
by
Phillip Webb
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.1.x'
Closes gh-17232
parents
f4d9e1c6
d82ccf14
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
214 additions
and
131 deletions
+214
-131
BootZipCopyAction.java
...amework/boot/gradle/tasks/bundling/BootZipCopyAction.java
+90
-130
LoaderZipEntries.java
...ramework/boot/gradle/tasks/bundling/LoaderZipEntries.java
+116
-0
AbstractBootArchiveTests.java
.../boot/gradle/tasks/bundling/AbstractBootArchiveTests.java
+8
-1
No files found.
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java
View file @
2c2b9622
...
@@ -22,11 +22,9 @@ import java.io.IOException;
...
@@ -22,11 +22,9 @@ import java.io.IOException;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
java.util.GregorianCalendar
;
import
java.util.HashSet
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.function.Function
;
import
java.util.function.Function
;
import
java.util.zip.CRC32
;
import
java.util.zip.CRC32
;
import
java.util.zip.ZipInputStream
;
import
org.apache.commons.compress.archivers.zip.UnixStat
;
import
org.apache.commons.compress.archivers.zip.UnixStat
;
import
org.apache.commons.compress.archivers.zip.ZipArchiveEntry
;
import
org.apache.commons.compress.archivers.zip.ZipArchiveEntry
;
...
@@ -34,12 +32,9 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
...
@@ -34,12 +32,9 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import
org.gradle.api.GradleException
;
import
org.gradle.api.GradleException
;
import
org.gradle.api.file.FileCopyDetails
;
import
org.gradle.api.file.FileCopyDetails
;
import
org.gradle.api.file.FileTreeElement
;
import
org.gradle.api.file.FileTreeElement
;
import
org.gradle.api.internal.file.CopyActionProcessingStreamAction
;
import
org.gradle.api.internal.file.copy.CopyAction
;
import
org.gradle.api.internal.file.copy.CopyAction
;
import
org.gradle.api.internal.file.copy.CopyActionProcessingStream
;
import
org.gradle.api.internal.file.copy.CopyActionProcessingStream
;
import
org.gradle.api.internal.file.copy.FileCopyDetailsInternal
;
import
org.gradle.api.specs.Spec
;
import
org.gradle.api.specs.Spec
;
import
org.gradle.api.specs.Specs
;
import
org.gradle.api.tasks.WorkResult
;
import
org.gradle.api.tasks.WorkResult
;
import
org.springframework.boot.loader.tools.DefaultLaunchScript
;
import
org.springframework.boot.loader.tools.DefaultLaunchScript
;
...
@@ -50,6 +45,7 @@ import org.springframework.boot.loader.tools.FileUtils;
...
@@ -50,6 +45,7 @@ import org.springframework.boot.loader.tools.FileUtils;
* Stores jar files without compression as required by Spring Boot's loader.
* Stores jar files without compression as required by Spring Boot's loader.
*
*
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author Phillip Webb
*/
*/
class
BootZipCopyAction
implements
CopyAction
{
class
BootZipCopyAction
implements
CopyAction
{
...
@@ -88,191 +84,155 @@ class BootZipCopyAction implements CopyAction {
...
@@ -88,191 +84,155 @@ class BootZipCopyAction implements CopyAction {
@Override
@Override
public
WorkResult
execute
(
CopyActionProcessingStream
stream
)
{
public
WorkResult
execute
(
CopyActionProcessingStream
stream
)
{
ZipArchiveOutputStream
zipStream
;
Spec
<
FileTreeElement
>
loaderEntries
;
try
{
try
{
FileOutputStream
fileStream
=
new
FileOutputStream
(
this
.
output
);
writeArchive
(
stream
);
writeLaunchScriptIfNecessary
(
fileStream
);
return
()
->
true
;
zipStream
=
new
ZipArchiveOutputStream
(
fileStream
);
if
(
this
.
encoding
!=
null
)
{
zipStream
.
setEncoding
(
this
.
encoding
);
}
loaderEntries
=
writeLoaderClassesIfNecessary
(
zipStream
);
}
}
catch
(
IOException
ex
)
{
catch
(
IOException
ex
)
{
throw
new
GradleException
(
"Failed to create "
+
this
.
output
,
ex
);
throw
new
GradleException
(
"Failed to create "
+
this
.
output
,
ex
);
}
}
}
private
void
writeArchive
(
CopyActionProcessingStream
stream
)
throws
IOException
{
OutputStream
outputStream
=
new
FileOutputStream
(
this
.
output
);
try
{
try
{
stream
.
process
(
new
ZipStreamAction
(
zipStream
,
this
.
output
,
this
.
preserveFileTimestamps
,
this
.
requiresUnpack
,
writeLaunchScriptIfNecessary
(
outputStream
);
createExclusionSpec
(
loaderEntries
),
this
.
compressionResolver
));
ZipArchiveOutputStream
zipOutputStream
=
new
ZipArchiveOutputStream
(
outputStream
);
}
finally
{
try
{
try
{
zipStream
.
close
();
if
(
this
.
encoding
!=
null
)
{
zipOutputStream
.
setEncoding
(
this
.
encoding
);
}
Processor
processor
=
new
Processor
(
zipOutputStream
);
stream
.
process
(
processor:
:
process
);
processor
.
finish
();
}
}
catch
(
IOException
ex
)
{
finally
{
// Continue
closeQuietly
(
zipOutputStream
);
}
}
}
}
return
()
->
true
;
finally
{
}
closeQuietly
(
outputStream
);
private
Spec
<
FileTreeElement
>
createExclusionSpec
(
Spec
<
FileTreeElement
>
loaderEntries
)
{
return
Specs
.
union
(
loaderEntries
,
this
.
exclusions
);
}
private
Spec
<
FileTreeElement
>
writeLoaderClassesIfNecessary
(
ZipArchiveOutputStream
out
)
{
if
(!
this
.
includeDefaultLoader
)
{
return
Specs
.
satisfyNone
();
}
}
return
writeLoaderClasses
(
out
);
}
}
private
Spec
<
FileTreeElement
>
writeLoaderClasses
(
ZipArchiveOutputStream
out
)
{
private
void
writeLaunchScriptIfNecessary
(
OutputStream
outputStream
)
{
try
(
ZipInputStream
in
=
new
ZipInputStream
(
if
(
this
.
launchScript
==
null
)
{
getClass
().
getResourceAsStream
(
"/META-INF/loader/spring-boot-loader.jar"
)))
{
return
;
Set
<
String
>
entries
=
new
HashSet
<>();
java
.
util
.
zip
.
ZipEntry
entry
;
while
((
entry
=
in
.
getNextEntry
())
!=
null
)
{
if
(
entry
.
isDirectory
()
&&
!
entry
.
getName
().
startsWith
(
"META-INF/"
))
{
writeDirectory
(
new
ZipArchiveEntry
(
entry
),
out
);
entries
.
add
(
entry
.
getName
());
}
else
if
(
entry
.
getName
().
endsWith
(
".class"
))
{
writeClass
(
new
ZipArchiveEntry
(
entry
),
in
,
out
);
}
}
return
(
element
)
->
{
String
path
=
element
.
getRelativePath
().
getPathString
();
if
(
element
.
isDirectory
()
&&
!
path
.
endsWith
((
"/"
)))
{
path
+=
"/"
;
}
return
entries
.
contains
(
path
);
};
}
catch
(
IOException
ex
)
{
throw
new
GradleException
(
"Failed to write loader classes"
,
ex
);
}
}
}
try
{
File
file
=
this
.
launchScript
.
getScript
();
private
void
writeDirectory
(
ZipArchiveEntry
entry
,
ZipArchiveOutputStream
out
)
throws
IOException
{
Map
<
String
,
String
>
properties
=
this
.
launchScript
.
getProperties
();
prepareEntry
(
entry
,
UnixStat
.
DIR_FLAG
|
UnixStat
.
DEFAULT_DIR_PERM
);
outputStream
.
write
(
new
DefaultLaunchScript
(
file
,
properties
).
toByteArray
());
out
.
putArchiveEntry
(
entry
);
outputStream
.
flush
();
out
.
closeArchiveEntry
();
this
.
output
.
setExecutable
(
true
);
}
private
void
writeClass
(
ZipArchiveEntry
entry
,
ZipInputStream
in
,
ZipArchiveOutputStream
out
)
throws
IOException
{
prepareEntry
(
entry
,
UnixStat
.
FILE_FLAG
|
UnixStat
.
DEFAULT_FILE_PERM
);
out
.
putArchiveEntry
(
entry
);
byte
[]
buffer
=
new
byte
[
4096
];
int
read
;
while
((
read
=
in
.
read
(
buffer
))
>
0
)
{
out
.
write
(
buffer
,
0
,
read
);
}
}
out
.
closeArchiveEntry
();
catch
(
IOException
ex
)
{
}
throw
new
GradleException
(
"Failed to write launch script to "
+
this
.
output
,
ex
);
private
void
prepareEntry
(
ZipArchiveEntry
entry
,
int
unixMode
)
{
if
(!
this
.
preserveFileTimestamps
)
{
entry
.
setTime
(
CONSTANT_TIME_FOR_ZIP_ENTRIES
);
}
}
entry
.
setUnixMode
(
unixMode
);
}
}
private
void
writeLaunchScriptIfNecessary
(
FileOutputStream
file
Stream
)
{
private
void
closeQuietly
(
OutputStream
output
Stream
)
{
try
{
try
{
if
(
this
.
launchScript
!=
null
)
{
outputStream
.
close
();
fileStream
.
write
(
new
DefaultLaunchScript
(
this
.
launchScript
.
getScript
(),
this
.
launchScript
.
getProperties
())
.
toByteArray
());
this
.
output
.
setExecutable
(
true
);
}
}
}
catch
(
IOException
ex
)
{
catch
(
IOException
ex
)
{
throw
new
GradleException
(
"Failed to write launch script to "
+
this
.
output
,
ex
);
}
}
}
}
private
static
final
class
ZipStreamAction
implements
CopyActionProcessingStreamAction
{
/**
* Internal process used to copy {@link FileCopyDetails file details} to the zip file.
private
final
ZipArchiveOutputStream
zipStream
;
*/
private
class
Processor
{
private
final
File
output
;
private
final
boolean
preserveFileTimestamps
;
private
final
Spec
<
FileTreeElement
>
requiresUnpack
;
private
final
Spec
<
FileTreeElement
>
exclusions
;
private
ZipArchiveOutputStream
outputStream
;
private
final
Function
<
FileCopyDetails
,
ZipCompression
>
compressionType
;
private
Spec
<
FileTreeElement
>
writtenLoaderEntries
;
private
ZipStreamAction
(
ZipArchiveOutputStream
zipStream
,
File
output
,
boolean
preserveFileTimestamps
,
Processor
(
ZipArchiveOutputStream
outputStream
)
{
Spec
<
FileTreeElement
>
requiresUnpack
,
Spec
<
FileTreeElement
>
exclusions
,
this
.
outputStream
=
outputStream
;
Function
<
FileCopyDetails
,
ZipCompression
>
compressionType
)
{
this
.
zipStream
=
zipStream
;
this
.
output
=
output
;
this
.
preserveFileTimestamps
=
preserveFileTimestamps
;
this
.
requiresUnpack
=
requiresUnpack
;
this
.
exclusions
=
exclusions
;
this
.
compressionType
=
compressionType
;
}
}
@Override
public
void
process
(
FileCopyDetails
details
)
{
public
void
processFile
(
FileCopyDetailsInternal
details
)
{
if
(
BootZipCopyAction
.
this
.
exclusions
.
isSatisfiedBy
(
details
)
if
(
this
.
exclusions
.
isSatisfiedBy
(
details
))
{
||
(
this
.
writtenLoaderEntries
!=
null
&&
this
.
writtenLoaderEntries
.
isSatisfiedBy
(
details
)
))
{
return
;
return
;
}
}
try
{
try
{
writeLoaderEntriesIfNecessary
(
details
);
if
(
details
.
isDirectory
())
{
if
(
details
.
isDirectory
())
{
create
Directory
(
details
);
process
Directory
(
details
);
}
}
else
{
else
{
create
File
(
details
);
process
File
(
details
);
}
}
}
}
catch
(
IOException
ex
)
{
catch
(
IOException
ex
)
{
throw
new
GradleException
(
"Failed to add "
+
details
+
" to "
+
this
.
output
,
ex
);
throw
new
GradleException
(
"Failed to add "
+
details
+
" to "
+
BootZipCopyAction
.
this
.
output
,
ex
);
}
}
public
void
finish
()
throws
IOException
{
writeLoaderEntriesIfNecessary
(
null
);
}
private
void
writeLoaderEntriesIfNecessary
(
FileCopyDetails
details
)
throws
IOException
{
if
(!
BootZipCopyAction
.
this
.
includeDefaultLoader
||
this
.
writtenLoaderEntries
!=
null
)
{
return
;
}
if
(
isInMetaInf
(
details
))
{
// Don't write loader entries until after META-INF folder (see gh-16698)
return
;
}
LoaderZipEntries
loaderEntries
=
new
LoaderZipEntries
(
BootZipCopyAction
.
this
.
preserveFileTimestamps
?
null
:
CONSTANT_TIME_FOR_ZIP_ENTRIES
);
this
.
writtenLoaderEntries
=
loaderEntries
.
writeTo
(
this
.
outputStream
);
}
private
boolean
isInMetaInf
(
FileCopyDetails
details
)
{
if
(
details
==
null
)
{
return
false
;
}
}
String
[]
segments
=
details
.
getRelativePath
().
getSegments
();
return
segments
.
length
>
0
&&
"META-INF"
.
equals
(
segments
[
0
]);
}
}
private
void
createDirectory
(
FileCopyDetailsInternal
details
)
throws
IOException
{
private
void
processDirectory
(
FileCopyDetails
details
)
throws
IOException
{
ZipArchiveEntry
archiveEntry
=
new
ZipArchiveEntry
(
details
.
getRelativePath
().
getPathString
()
+
'/'
);
ZipArchiveEntry
archiveEntry
=
new
ZipArchiveEntry
(
details
.
getRelativePath
().
getPathString
()
+
'/'
);
archiveEntry
.
setUnixMode
(
UnixStat
.
DIR_FLAG
|
details
.
getMode
());
archiveEntry
.
setUnixMode
(
UnixStat
.
DIR_FLAG
|
details
.
getMode
());
archiveEntry
.
setTime
(
getTime
(
details
));
archiveEntry
.
setTime
(
getTime
(
details
));
this
.
zip
Stream
.
putArchiveEntry
(
archiveEntry
);
this
.
output
Stream
.
putArchiveEntry
(
archiveEntry
);
this
.
zip
Stream
.
closeArchiveEntry
();
this
.
output
Stream
.
closeArchiveEntry
();
}
}
private
void
createFile
(
FileCopyDetailsInternal
details
)
throws
IOException
{
private
void
processFile
(
FileCopyDetails
details
)
throws
IOException
{
String
relativePath
=
details
.
getRelativePath
().
getPathString
();
String
relativePath
=
details
.
getRelativePath
().
getPathString
();
ZipArchiveEntry
archiveEntry
=
new
ZipArchiveEntry
(
relativePath
);
ZipArchiveEntry
archiveEntry
=
new
ZipArchiveEntry
(
relativePath
);
archiveEntry
.
setUnixMode
(
UnixStat
.
FILE_FLAG
|
details
.
getMode
());
archiveEntry
.
setUnixMode
(
UnixStat
.
FILE_FLAG
|
details
.
getMode
());
archiveEntry
.
setTime
(
getTime
(
details
));
archiveEntry
.
setTime
(
getTime
(
details
));
ZipCompression
compression
=
this
.
compressionType
.
apply
(
details
);
ZipCompression
compression
=
BootZipCopyAction
.
this
.
compressionResolver
.
apply
(
details
);
if
(
compression
==
ZipCompression
.
STORED
)
{
if
(
compression
==
ZipCompression
.
STORED
)
{
prepareStoredEntry
(
details
,
archiveEntry
);
prepareStoredEntry
(
details
,
archiveEntry
);
}
}
this
.
zip
Stream
.
putArchiveEntry
(
archiveEntry
);
this
.
output
Stream
.
putArchiveEntry
(
archiveEntry
);
details
.
copyTo
(
this
.
zip
Stream
);
details
.
copyTo
(
this
.
output
Stream
);
this
.
zip
Stream
.
closeArchiveEntry
();
this
.
output
Stream
.
closeArchiveEntry
();
}
}
private
void
prepareStoredEntry
(
FileCopyDetailsInternal
details
,
ZipArchiveEntry
archiveEntry
)
private
void
prepareStoredEntry
(
FileCopyDetails
details
,
ZipArchiveEntry
archiveEntry
)
throws
IOException
{
throws
IOException
{
archiveEntry
.
setMethod
(
java
.
util
.
zip
.
ZipEntry
.
STORED
);
archiveEntry
.
setMethod
(
java
.
util
.
zip
.
ZipEntry
.
STORED
);
archiveEntry
.
setSize
(
details
.
getSize
());
archiveEntry
.
setSize
(
details
.
getSize
());
archiveEntry
.
setCompressedSize
(
details
.
getSize
());
archiveEntry
.
setCompressedSize
(
details
.
getSize
());
Crc32OutputStream
crcStream
=
new
Crc32OutputStream
();
Crc32OutputStream
crcStream
=
new
Crc32OutputStream
();
details
.
copyTo
(
crcStream
);
details
.
copyTo
(
crcStream
);
archiveEntry
.
setCrc
(
crcStream
.
getCrc
());
archiveEntry
.
setCrc
(
crcStream
.
getCrc
());
if
(
this
.
requiresUnpack
.
isSatisfiedBy
(
details
))
{
if
(
BootZipCopyAction
.
this
.
requiresUnpack
.
isSatisfiedBy
(
details
))
{
archiveEntry
.
setComment
(
"UNPACK:"
+
FileUtils
.
sha1Hash
(
details
.
getFile
()));
archiveEntry
.
setComment
(
"UNPACK:"
+
FileUtils
.
sha1Hash
(
details
.
getFile
()));
}
}
}
}
private
long
getTime
(
FileCopyDetails
details
)
{
private
long
getTime
(
FileCopyDetails
details
)
{
return
this
.
preserveFileTimestamps
?
details
.
getLastModified
()
:
CONSTANT_TIME_FOR_ZIP_ENTRIES
;
return
BootZipCopyAction
.
this
.
preserveFileTimestamps
?
details
.
getLastModified
()
:
CONSTANT_TIME_FOR_ZIP_ENTRIES
;
}
}
}
}
...
@@ -282,25 +242,25 @@ class BootZipCopyAction implements CopyAction {
...
@@ -282,25 +242,25 @@ class BootZipCopyAction implements CopyAction {
*/
*/
private
static
final
class
Crc32OutputStream
extends
OutputStream
{
private
static
final
class
Crc32OutputStream
extends
OutputStream
{
private
final
CRC32
crc
32
=
new
CRC32
();
private
final
CRC32
crc
=
new
CRC32
();
@Override
@Override
public
void
write
(
int
b
)
throws
IOException
{
public
void
write
(
int
b
)
throws
IOException
{
this
.
crc
32
.
update
(
b
);
this
.
crc
.
update
(
b
);
}
}
@Override
@Override
public
void
write
(
byte
[]
b
)
throws
IOException
{
public
void
write
(
byte
[]
b
)
throws
IOException
{
this
.
crc
32
.
update
(
b
);
this
.
crc
.
update
(
b
);
}
}
@Override
@Override
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
public
void
write
(
byte
[]
b
,
int
off
,
int
len
)
throws
IOException
{
this
.
crc
32
.
update
(
b
,
off
,
len
);
this
.
crc
.
update
(
b
,
off
,
len
);
}
}
private
long
getCrc
()
{
private
long
getCrc
()
{
return
this
.
crc
32
.
getValue
();
return
this
.
crc
.
getValue
();
}
}
}
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LoaderZipEntries.java
0 → 100644
View file @
2c2b9622
/*
* Copyright 2012-2018 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
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
springframework
.
boot
.
gradle
.
tasks
.
bundling
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.HashSet
;
import
java.util.Set
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipInputStream
;
import
org.apache.commons.compress.archivers.zip.UnixStat
;
import
org.apache.commons.compress.archivers.zip.ZipArchiveEntry
;
import
org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
;
import
org.gradle.api.file.FileTreeElement
;
import
org.gradle.api.specs.Spec
;
/**
* Internal utility used to copy entries from the {@code spring-boot-loader.jar}.
*
* @author Andy Wilkinson
* @author Phillip Webb
*/
class
LoaderZipEntries
{
private
Long
entryTime
;
LoaderZipEntries
(
Long
entryTime
)
{
this
.
entryTime
=
entryTime
;
}
public
Spec
<
FileTreeElement
>
writeTo
(
ZipArchiveOutputStream
zipOutputStream
)
throws
IOException
{
WrittenDirectoriesSpec
writtenDirectoriesSpec
=
new
WrittenDirectoriesSpec
();
try
(
ZipInputStream
loaderJar
=
new
ZipInputStream
(
getClass
().
getResourceAsStream
(
"/META-INF/loader/spring-boot-loader.jar"
)))
{
java
.
util
.
zip
.
ZipEntry
entry
=
loaderJar
.
getNextEntry
();
while
(
entry
!=
null
)
{
if
(
entry
.
isDirectory
()
&&
!
entry
.
getName
().
equals
(
"META-INF/"
))
{
writeDirectory
(
new
ZipArchiveEntry
(
entry
),
zipOutputStream
);
writtenDirectoriesSpec
.
add
(
entry
);
}
else
if
(
entry
.
getName
().
endsWith
(
".class"
))
{
writeClass
(
new
ZipArchiveEntry
(
entry
),
loaderJar
,
zipOutputStream
);
}
entry
=
loaderJar
.
getNextEntry
();
}
}
return
writtenDirectoriesSpec
;
}
private
void
writeDirectory
(
ZipArchiveEntry
entry
,
ZipArchiveOutputStream
out
)
throws
IOException
{
prepareEntry
(
entry
,
UnixStat
.
DIR_FLAG
|
UnixStat
.
DEFAULT_DIR_PERM
);
out
.
putArchiveEntry
(
entry
);
out
.
closeArchiveEntry
();
}
private
void
writeClass
(
ZipArchiveEntry
entry
,
ZipInputStream
in
,
ZipArchiveOutputStream
out
)
throws
IOException
{
prepareEntry
(
entry
,
UnixStat
.
FILE_FLAG
|
UnixStat
.
DEFAULT_FILE_PERM
);
out
.
putArchiveEntry
(
entry
);
copy
(
in
,
out
);
out
.
closeArchiveEntry
();
}
private
void
prepareEntry
(
ZipArchiveEntry
entry
,
int
unixMode
)
{
if
(
this
.
entryTime
!=
null
)
{
entry
.
setTime
(
this
.
entryTime
);
}
entry
.
setUnixMode
(
unixMode
);
}
private
void
copy
(
InputStream
in
,
OutputStream
out
)
throws
IOException
{
byte
[]
buffer
=
new
byte
[
4096
];
int
bytesRead
=
-
1
;
while
((
bytesRead
=
in
.
read
(
buffer
))
!=
-
1
)
{
out
.
write
(
buffer
,
0
,
bytesRead
);
}
}
/**
* Spec to track directories that have been written.
*/
private
static
class
WrittenDirectoriesSpec
implements
Spec
<
FileTreeElement
>
{
private
final
Set
<
String
>
entries
=
new
HashSet
<>();
@Override
public
boolean
isSatisfiedBy
(
FileTreeElement
element
)
{
String
path
=
element
.
getRelativePath
().
getPathString
();
if
(
element
.
isDirectory
()
&&
!
path
.
endsWith
((
"/"
)))
{
path
+=
"/"
;
}
return
this
.
entries
.
contains
(
path
);
}
public
void
add
(
ZipEntry
entry
)
{
this
.
entries
.
add
(
entry
.
getName
());
}
}
}
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveTests.java
View file @
2c2b9622
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
package
org
.
springframework
.
boot
.
gradle
.
tasks
.
bundling
;
package
org
.
springframework
.
boot
.
gradle
.
tasks
.
bundling
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.nio.file.Files
;
import
java.nio.file.Files
;
...
@@ -34,6 +35,7 @@ import java.util.jar.JarFile;
...
@@ -34,6 +35,7 @@ import java.util.jar.JarFile;
import
java.util.jar.JarOutputStream
;
import
java.util.jar.JarOutputStream
;
import
java.util.jar.Manifest
;
import
java.util.jar.Manifest
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipInputStream
;
import
org.apache.commons.compress.archivers.zip.ZipArchiveEntry
;
import
org.apache.commons.compress.archivers.zip.ZipArchiveEntry
;
import
org.apache.commons.compress.archivers.zip.ZipFile
;
import
org.apache.commons.compress.archivers.zip.ZipFile
;
...
@@ -188,13 +190,18 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
...
@@ -188,13 +190,18 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
}
}
@Test
@Test
void
loaderIsWrittenToTheRootOfTheJar
()
throws
IOException
{
void
loaderIsWrittenToTheRootOfTheJar
AfterManifest
()
throws
IOException
{
this
.
task
.
setMainClassName
(
"com.example.Main"
);
this
.
task
.
setMainClassName
(
"com.example.Main"
);
executeTask
();
executeTask
();
try
(
JarFile
jarFile
=
new
JarFile
(
this
.
task
.
getArchivePath
()))
{
try
(
JarFile
jarFile
=
new
JarFile
(
this
.
task
.
getArchivePath
()))
{
assertThat
(
jarFile
.
getEntry
(
"org/springframework/boot/loader/LaunchedURLClassLoader.class"
)).
isNotNull
();
assertThat
(
jarFile
.
getEntry
(
"org/springframework/boot/loader/LaunchedURLClassLoader.class"
)).
isNotNull
();
assertThat
(
jarFile
.
getEntry
(
"org/springframework/boot/loader/"
)).
isNotNull
();
assertThat
(
jarFile
.
getEntry
(
"org/springframework/boot/loader/"
)).
isNotNull
();
}
}
// gh-16698
try
(
ZipInputStream
zipInputStream
=
new
ZipInputStream
(
new
FileInputStream
(
this
.
task
.
getArchivePath
())))
{
assertThat
(
zipInputStream
.
getNextEntry
().
getName
()).
isEqualTo
(
"META-INF/"
);
assertThat
(
zipInputStream
.
getNextEntry
().
getName
()).
isEqualTo
(
"META-INF/MANIFEST.MF"
);
}
}
}
@Test
@Test
...
...
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