forked from mockito/mockito
/
osgi.gradle
114 lines (88 loc) · 3.76 KB
/
osgi.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import java.nio.file.attribute.FileTime
import java.util.jar.Attributes
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.jar.JarOutputStream
import java.util.jar.Manifest
import static java.util.Calendar.FEBRUARY
apply plugin: 'biz.aQute.bnd.builder'
jar {
classpath = project.configurations.runtime
bnd(
'Bundle-Name': 'Mockito Mock Library for Java. Core bundle requires Byte Buddy and Objenesis.',
'Bundle-SymbolicName': 'org.mockito.mockito-core',
'Bundl-version': project.version.replace('-', '.'),
'-versionpolicy': '[${version;==;${@}},${version;+;${@}})',
'Export-Package': "!org.mockito.internal.*,org.mockito.*;version=${version}",
'Import-Package': [
'net.bytebuddy.*;version="[1.6.0,2.0)"',
'junit.*;resolution:=optional',
'org.junit.*;resolution:=optional',
'org.hamcrest;resolution:=optional',
'org.objenesis;version="[2.5,3.0)"',
'org.opentest4j.*;resolution:=optional',
'org.mockito.*'
].join(','),
'-removeheaders': 'Private-Package',
'Automatic-Module-Name': 'org.mockito'
)
}
jar.doLast {
JarFile originalJar = new JarFile(jar.archivePath)
new RemoveOsgiLastModifiedHeader(originalJar)
.transform()
.renameTo jar.archivePath
}
/*
* The OSGi plugin in Gradle 5.3 has a known issue (https://github.com/gradle/gradle/issues/6187) where it embeds
* a Manifest entry "Bnd-LastModified" (set to the last modified time of the build directory) even if you ask it not to
* using `-noextraheaders` or `-removeheaders`.
*
* It cannot be pinned or removed, and is a source of non-determinism in the build.
*
* This class addresses the problem by rewriting the JAR and removing that entry from the Manifest. A side-effect of this
* is having to set `lastModifiedTime` for each entry to a fixed value, else this would also introduce non-determinism.
*
* The fixed value is the same as the default value for Gradle's fixed timestamps, and the rationale behind it is detailed
* in https://github.com/gradle/gradle/blob/58538513a3bff3b7015718976fe1304e23f40694/subprojects/core/src/main/java/org/gradle/api/internal/file/archive/ZipCopyAction.java#L42-L57
*/
class RemoveOsgiLastModifiedHeader {
private final long CONSTANT_TIME_FOR_ZIP_ENTRIES = new GregorianCalendar(1980, FEBRUARY, 1, 0, 0, 0).timeInMillis
private final JarFile artifact
RemoveOsgiLastModifiedHeader(JarFile artifact) {
this.artifact = artifact
}
File transform() {
File temp = File.createTempFile("temp",".jar")
temp.withOutputStream { os ->
JarOutputStream stream = new JarOutputStream(os)
this.artifact
.entries()
.sort { it.name }
.each { JarEntry entry ->
stream.putNextEntry(newJarEntry(entry))
if (entry.name == "META-INF/MANIFEST.MF") {
newManifest(entry).write(stream)
} else {
stream << this.artifact.getInputStream(entry)
}
stream.closeEntry()
}
stream.finish()
}
temp
}
Manifest newManifest(JarEntry entry) {
Manifest manifest = new Manifest()
manifest.read(this.artifact.getInputStream(entry))
manifest
.getMainAttributes()
.remove(new Attributes.Name("Bnd-LastModified"))
manifest
}
JarEntry newJarEntry(JarEntry original) {
JarEntry newEntry = new JarEntry(original.name)
newEntry.setLastModifiedTime(FileTime.fromMillis(CONSTANT_TIME_FOR_ZIP_ENTRIES))
newEntry
}
}