TomDmitriev / gradle-bundle-plugin

Apache License 2.0
47 stars 24 forks source link

JarBuilder still runs the bnd Builder even though it is up to date #74

Open mbelling opened 6 years ago

mbelling commented 6 years ago

We have a large subproject of our build that applies the gradle-bundle-plugin. We found that the plugin will run the aQute.bnd.osgi.Builder, and in the end mark the task as up to date. Being a large subproject with a large amount of classes, this eats up over a minute of build time for an 'up-to-date' task. I think the up to date check should prevent the Builder from being run, to save on build time.

Edit: This was with Gradle 2.14, but I tested with Gradle 4.2-rc-2 as well, so the gradle version does not seem to have an effect.

mbelling commented 6 years ago

A clipping of a Gradle 2.14 debug log if it helps, with some things taken our for brevity.

09:28:30.229 [LIFECYCLE] [class org.gradle.TaskExecutionLogger] :someProject:jar 09:28:30.229 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ':someProject:jar' 09:28:30.229 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Determining if task ':someProject:jar' is up-to-date 09:28:30.245 [DEBUG] [org.gradle.api.internal.changedetection.state.CachingTreeVisitor] Cache hit directory 'C:\someProject\build\classes\main' 09:28:30.245 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting base C:\someProject 09:28:30.245 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting properties { ... stuff ... } ... 09:28:30.276 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting classpath ...classpath... 09:28:30.276 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting source path C:\someProject\src\main\java 09:28:30.955 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting resources C:\someProject\build\classes\main 09:28:30.956 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting version 1.0.0.SNAPSHOT 09:28:30.956 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting name someProject 09:28:30.956 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting trace false 09:28:30.956 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] Setting fail on error false 09:28:31.369 [DEBUG] [org.dm.gradle.plugins.bundle.JarBuilder] The Builder is about to generate a jar using classpath: [... classpath ...] 09:28:31.369 [DEBUG] [aQute.bnd.osgi.Builder] build ... 106 seconds of Builder spam ... 09:30:17.145 [INFO] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Skipping task ':someProject:jar' as it is up-to-date (took 1 mins 46.916 secs). 09:30:17.145 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':someProject:jar' 09:30:17.145 [LIFECYCLE] [class org.gradle.TaskExecutionLogger] :someProject:jar UP-TO-DATE

mbelling commented 6 years ago

I think this might have to do with the manifest being generated. From a clean state, it seems to run the JarBuilder.build method once while generating the manifest in the writeManifestTo method, and again while generating the jar in the writeJarTo method.

void writeManifestTo(OutputStream outputStream, @Nullable Closure c) {
    def builder = build()

    def manifest = builder.jar.manifest.clone() as Manifest
    if (c != null) {
        c manifest
    }
    try {
        Jar.writeManifest manifest, outputStream
    } finally {
        outputStream.close()
        closeBuilder(builder)
    }
}
void writeJarTo(File output) {
    def builder = null
    try {
        builder = build()

        output.getParentFile().mkdirs()
        builder.jar.write output
    } finally {
        closeBuilder(builder)
    }
}

So the issue on a repeated build I assume has to do with the manifest generation calling the build method. Is that avoidable on an up-to-date build?

mbelling commented 6 years ago

With further digging I realize that the builder is run to generate the manifest to determine if it is up to date. Getting around this might be tricky.