Charlie Hubbard
02/28/2025, 6:40 PMapply
method looks like this:
class SslCertGenPlugin implements Plugin<Project> {
void apply(Project project) {
Security.addProvider(new BouncyCastleProvider())
CertificateExtension certificate = project.extensions.create( "certificate", CertificateExtension )
project.tasks.register("generateCert", X509Certificate, project, certificate )
}
}
However, in a multi-project build where the plugin could be applied to a subproject this doesn’t work. It assumes the plugin is defined at the root project even when it’s not. So how does a plugin know the difference? When it was applied at the root vs a subproject?Thomas Broyer
02/28/2025, 6:42 PMSo how does a plugin know the difference? When it was applied at the root vs a subproject?You can check things like
project.rootProject == project
, project.path == ":"
, or project.parent == null
Charlie Hubbard
02/28/2025, 6:43 PMThomas Broyer
02/28/2025, 6:51 PMapply()
called for each of them.ephemient
02/28/2025, 6:52 PMSecurity.addProvider(new BouncyCastleProvider())
that part seems like not a good idea, even if you can tell if you're applied to the root project or notephemient
02/28/2025, 6:53 PMephemient
02/28/2025, 6:55 PMX509Certificate
task to locally use BC instead of relying on it globallyCharlie Hubbard
02/28/2025, 6:56 PMCharlie Hubbard
02/28/2025, 6:56 PMephemient
02/28/2025, 7:02 PMnew org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory()
instead of java.security.cert.CertificateFactory.getInstance("X.509")
Charlie Hubbard
02/28/2025, 7:07 PMVampire
02/28/2025, 11:09 PMworker with process isolation would definitely be able to do it "locally".... no those processes also are reused if possible, unless you somehow trick Gradle to always create a new one
Charlie Hubbard
02/28/2025, 11:12 PMephemient
02/28/2025, 11:29 PMVampire
02/28/2025, 11:29 PMephemient
02/28/2025, 11:30 PMVampire
02/28/2025, 11:34 PMclasspath for the worker would make that process incompatible with others… so I would have thoughtWhy is the classpath different? It can be the same, especially when doing action from the same plugin repeatedly.
Vampire
02/28/2025, 11:35 PMephemient
02/28/2025, 11:37 PMVampire
02/28/2025, 11:38 PM// For flat classloaders, we include the work classpath along with the WorkerDaemonServer implementation.
// As a consequence of a flat classloader, the work is able to see the classes of the WorkerDaemonServer
// at runtime.
// This is fine for internal work, but for user-provided work, we serialize the work classpath and load
// it on the worker side.
// We primarily use a flat classloader for Java compilation workers, as using a hierarchical classloader
// caused performance regressions. The Java compiler seems to hammer the classloader, and performance
// is better with a flat classloader. A hierarchical classloader should be preferred when classloader
// performance is not a concern.
Vampire
02/28/2025, 11:39 PMVampire
02/28/2025, 11:39 PMephemient
02/28/2025, 11:41 PMVampire
02/28/2025, 11:41 PMVampire
02/28/2025, 11:42 PMah well then. there's definitely some process fork options that can't be handled without a new process though, does Gradle ignore them?Probably not. This is probably handled like with the Gradle daemon args. If those are not equal, the worker is not compatible and is not reused. So you have to check which properties those are and then set one of them to some UUID value, maybe the tmp dir property or something like that. That is what I referred to above as tricking Gradle into not reusing the processes.