Skip to content

Commit c2b15ba

Browse files
committed
First step towards making PlugRegistry resilient to JarURLConnection caching.
1 parent 44099f4 commit c2b15ba

1 file changed

Lines changed: 44 additions & 41 deletions

File tree

atplug-runtime/src/main/java/com/diffplug/atplug/PlugRegistry.kt

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import java.io.ByteArrayOutputStream
1010
import java.lang.reflect.Constructor
1111
import java.net.URL
1212
import java.nio.charset.StandardCharsets
13-
import java.util.*
1413
import java.util.jar.Manifest
1514
import java.util.zip.ZipException
1615

@@ -33,16 +32,6 @@ interface PlugRegistry {
3332
private const val PATH_MANIFEST = "META-INF/MANIFEST.MF"
3433
private const val DS_WITHIN_MANIFEST = "AtPlug-Component"
3534

36-
internal fun parseComponent(manifestUrl: String, servicePath: String): PlugDescriptor {
37-
val serviceUrl =
38-
URL(manifestUrl.substring(0, manifestUrl.length - PATH_MANIFEST.length) + servicePath)
39-
40-
val out = ByteArrayOutputStream()
41-
serviceUrl.openStream().use { it.copyTo(out) }
42-
val serviceFileContent = String(out.toByteArray(), StandardCharsets.UTF_8)
43-
return PlugDescriptor.fromJson(serviceFileContent)
44-
}
45-
4635
fun setHarness(data: PlugInstanceMap?) {
4736
val registry = instance.value
4837
if (registry is Eager) {
@@ -62,44 +51,58 @@ interface PlugRegistry {
6251
val values = Eager::class.java.classLoader.getResources(PATH_MANIFEST)
6352
while (values.hasMoreElements()) {
6453
val manifestUrl = values.nextElement()
65-
manifestUrl.openStream().use { stream ->
66-
// parse the manifest
67-
val manifest = Manifest(stream)
68-
val services = manifest.mainAttributes.getValue(DS_WITHIN_MANIFEST)
69-
if (services != null) {
70-
// it's got declarative services!
71-
for (service in
72-
services.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
73-
val servicePath = service.trim { it <= ' ' }
74-
try {
75-
if (servicePath.isNotEmpty()) {
76-
val asString = manifestUrl.toExternalForm()
77-
val component = parseComponent(asString, servicePath)
78-
synchronized(this) {
79-
data.putDescriptor(component.provides, component)
80-
owners[component.provides]?.doRegister(component)
81-
}
82-
}
83-
} catch (e: ZipException) {
84-
// When a JVM loads a jar, it mmaps the jar. If that jar changes
85-
// (as it does when generating plugin metadata in a Gradle daemon)
86-
// then you get ZipException after the change. The accuracy of the
87-
// registry is irrelevant during metadata generation - the registry
88-
// exists during metadata generation only because the `SocketOwner`s
89-
// register themselves in their constructors. Therefore, it is safe to
90-
// ignore these errors during metadata generation.
91-
val prop = System.getProperty("atplug.generate")
92-
if (prop != "true") {
93-
throw e
94-
}
54+
parseManifest(manifestUrl)
55+
}
56+
}
57+
}
58+
59+
private fun parseManifest(manifestUrl: URL) {
60+
manifestUrl.openStream().use { stream ->
61+
// parse the manifest
62+
val manifest = Manifest(stream)
63+
val services = manifest.mainAttributes.getValue(DS_WITHIN_MANIFEST)
64+
if (services != null) {
65+
// it's got declarative services!
66+
for (service in
67+
services.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
68+
val servicePath = service.trim { it <= ' ' }
69+
try {
70+
if (servicePath.isNotEmpty()) {
71+
val asString = manifestUrl.toExternalForm()
72+
val component = parseComponent(asString, servicePath)
73+
synchronized(this) {
74+
data.putDescriptor(component.provides, component)
75+
owners[component.provides]?.doRegister(component)
9576
}
9677
}
78+
} catch (e: ZipException) {
79+
// When a JVM loads a jar, it mmaps the jar. If that jar changes
80+
// (as it does when generating plugin metadata in a Gradle daemon)
81+
// then you get ZipException after the change. The accuracy of the
82+
// registry is irrelevant during metadata generation - the registry
83+
// exists during metadata generation only because the `SocketOwner`s
84+
// register themselves in their constructors. Therefore, it is safe to
85+
// ignore these errors during metadata generation.
86+
val prop = System.getProperty("atplug.generate")
87+
if (prop != "true") {
88+
throw e
89+
}
9790
}
9891
}
9992
}
10093
}
10194
}
10295

96+
private fun parseComponent(manifestUrl: String, servicePath: String): PlugDescriptor {
97+
val serviceUrl =
98+
URL(manifestUrl.substring(0, manifestUrl.length - PATH_MANIFEST.length) + servicePath)
99+
100+
val out = ByteArrayOutputStream()
101+
serviceUrl.openStream().use { it.copyTo(out) }
102+
val serviceFileContent = String(out.toByteArray(), StandardCharsets.UTF_8)
103+
return PlugDescriptor.fromJson(serviceFileContent)
104+
}
105+
103106
override fun <T> registerSocket(socketClass: Class<T>, socketOwner: SocketOwner<T>) {
104107
synchronized(this) {
105108
val prevOwner = owners.put(socketClass.name, socketOwner)

0 commit comments

Comments
 (0)