shevek / jarjar

Jar Jar Links is a utility that makes it easy to repackage Java libraries and embed them into your own distribution.
Apache License 2.0
735 stars 93 forks source link

Gradle task does not work with version 7.0 #22

Open jgremmen opened 3 years ago

jgremmen commented 3 years ago

Gradle version 7.0 now reports the following error: - Type 'JarjarTask' property 'destinationDir' is missing an input or output annotation.

ungesehn commented 3 years ago

To be more specific about the error message given:

FAILURE: Build failed with an exception.

  • What went wrong: Some problems were found with the configuration of task ':repackaged' (type 'JarjarTask').

    • Type 'org.anarres.gradle.plugin.jarjar.JarjarTask' property 'destinationDir' is missing an input or output annotation.

    Reason: A property without annotation isn't considered during up-to-date checking.

    Possible solutions:

    1. Add an input or output annotation.
    2. Mark it as @Internal.

    Please refer to https://docs.gradle.org/7.0.2/userguide/validation_problems.html#missing_annotation for more details about this problem.

    • Type 'org.anarres.gradle.plugin.jarjar.JarjarTask' property 'destinationName' is missing an input or output annotation.

    Reason: A property without annotation isn't considered during up-to-date checking.

    Possible solutions:

    1. Add an input or output annotation.
    2. Mark it as @Internal.

    Please refer to https://docs.gradle.org/7.0.2/userguide/validation_problems.html#missing_annotation for more details about this problem.

ungesehn commented 3 years ago

I tested this with a local build - the current code on GitHub is compatible with Gradle 7.0. However a new release of the jarjar Gradle plugin is required as the latest version is 1.0.1.

See also the request in #16

andob commented 2 years ago

I just realized, we can use jitpack.io to import the latest snapshot of the plugin (which is compatible with Gradle 7) into our projects.

To import the plugin:

Legacy Gradle API:

build.gradle

buildscript {
    repositories {
        //........................
        maven { url "https://jitpack.io" }
        //........................
    }
    dependencies {
        //........................
        classpath 'com.github.shevek.jarjar:jarjar-gradle:9a7eca72f9'
    }
}

app/build.gradle

apply plugin: 'org.anarres.jarjar'

New Gradle API:

settings.gradle

pluginManagement {
  repositories {
        //........................
        maven { url "https://jitpack.io" }
        //........................
  }
}

app/build.gradle

plugins {
    //.................
    id 'org.anarres.jarjar'
}

To use the plugin:

For instance, to import Apache Tika excluding org.apache.tika.io.MappedBufferCleaner that uses MethodHandle API which is missing on Android API level < 26:

app/build.gradle

dependencies {
    //................................................................
    implementation jarjar.repackage {
        from 'org.apache.tika:tika-core:2.1.0'
        classDelete 'org.apache.tika.io.MappedBufferCleaner'
    }
    //................................................................
}

@ungesehn @matthewhague @cah-anuj-shrivastava @thomasstache @AlexKrupa @cmathew @jgremmen

ghost commented 2 years ago

@andob Unfortunately, when I add id("org.anarres.jarjar"), Gradle can't fetch the plugin:

Plugin [id: 'org.anarres.jarjar'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (plugin dependency must include a version number for this source)
...

UPD. I've resolved it like this:

buildscript {
    repositories {
        maven {
            url = uri("https://jitpack.io")
        }
    }
    dependencies {
        classpath("com.github.shevek.jarjar:jarjar-gradle:master")
    }
}

apply(plugin = "org.anarres.jarjar")
cmeng-git commented 2 years ago

Using master branch may cause problem in project if there a new release with conflict to your current project usage.

https://github.com/shevek/jarjar/issues/22#issuecomment-992623722

I tried your proposal. it did get rid of the warnings. However I found the following problems: a. The new jarjar respects the defined parameters for "destinationDir" but ignore "destinationName" b. During the AS build, it just assigned random names to the newly generated jar files e.g. in project/build/jarjar/CH_223212.jar c. AS just keeps adding new generated jar files every time user do a build, without deleted the old one. d. In aTalk implementation, it needs the actual defined "destinationName" as reference, so the build always failed f. There is another serious problem when doing a "Generate Signed Bundle/APK" process, AS build failed with the following error:

Execution failed for task ':aTalk:collectPlaystoreReleaseDependencies'.

java.io.FileNotFoundException: /~workspace/android/atalk-android/aTalk/build/jarjar (Is a directory)

ghost commented 2 years ago

@cmeng-git

I'm using the current master and you can still assign a name to the repackaged jar, here's in Kotlin DSL:

implementation(files(JarjarController(project).repackage("<your name>", closureOf<JarjarTask> {
    from("...")
    classDelete("...")
})))
cmeng-git commented 2 years ago

Thanks for your input. I am trying to change the following to your proposal, but gradle flagged as unresolved symbol. Is a new plugin or meant something else?

Appreciate your advice, possibly provide an actual output for the example below.

Sorry, I am not familiar with kotlin implementation, not sure if build.gradle file allows a mixture of both existing and kotlin definitions.

    implementation jarjar.repackage {
        from('org.jitsi:fmj:1.0.1-jitsi')
        destinationName "fmj-1.0.1-jitsi.jar"

        // remove extracted modules for changes
        classDelete 'net.sf.fmj.media.RegistryDefaults'
        classDelete 'javax.media.format.VideoFormat'
        classDelete 'javax.media.Manager**'
    }

===>

    implementation(files(JarjarController(project).repackage("fmj-1.0.1-jitsi.jar", closureOf<JarjarTask> {
        from('org.jitsi:fmj:1.0.1-jitsi')

        classDelete 'net.sf.fmj.media.RegistryDefaults'
        classDelete 'javax.media.format.VideoFormat'
        classDelete 'javax.media.Manager**'
    })))
cmeng-git commented 2 years ago

After going through the information on: https://www.javatips.net/api/jarjar-master/jarjar-gradle/src/main/java/org/anarres/gradle/plugin/jarjar/JarjarTask.java

It seems that your proposed scripts has the same task implementation as the one in aTalk gradle script. So the problem of merging multiple output jars into the specified destinationName is not working using jitpack.io

@cmeng-git

I'm using the current master and you can still assign a name to the repackaged jar, here's in Kotlin DSL:

implementation(files(JarjarController(project).repackage("<your name>", closureOf<JarjarTask> {
    from("...")
    classDelete("...")
})))
cmeng-git commented 2 years ago

I am not sure now what my previous comment is correct. When I changed the scripts to the following, found that 1 of 3 output *.jar indeed get renamed to "fmj-1.0.1-jitsi.jar". As I am not familiar with jarjar-gradle, may be someone can give me a hint on how to merged all the output jar files into one, before the file rename process.

    implementation jarjar.repackage("fmj-1.0.1-jitsi.jar", {
        from('org.jitsi:fmj:1.0.1-jitsi')

        // remove extracted modules for changes
        classDelete 'net.sf.fmj.media.RegistryDefaults'
        classDelete 'javax.media.format.VideoFormat'
        classDelete 'javax.media.Manager**'
    })
cmeng-git commented 8 months ago

aTalk uses jarjar master source release for android API-34 release. JarJar is fully compatible with gradle-7.x see https://github.com/shevek/jarjar/issues/22#issuecomment-887420425 with updates as below: You may refer to aTalk repository for the full solution i.e. https://github.com/cmeng-git/atalk-android

For legacy gradle API:

buildscript {
    repositories {
        maven { url "https://jitpack.io" }
    }
    dependencies {
        classpath 'com.github.shevek.jarjar:jarjar-gradle:9a7eca7'

        // Usually this is set in root build.gradle file: gradle-8.x requires JVM 17; aTalk max jvm is 15.
        classpath 'com.android.tools.build:gradle:7.4.2'
    }
}

apply plugin: 'org.anarres.jarjar'

repositories {
    maven {
      // local defined destinationDir if required. Default save directory is build/jarjar
        url 'third_party/m2'

        // Must include these lines for gradle to use local defined destinationDir for jarjar files
        metadataSources {
            mavenPom()
            artifact()
        }
    }
}

dependencies {
    // example use in aTalk to define destinationName for the generated jarjar file
    implementation jarjar.repackage(""ice4j-3.0-SNAPSHOT.jar"") {
        from('org.jitsi:ice4j:3.0-55-g32a8aad') {
            transitive = false
        }

       // Define only if so required; default is in build/jarjar sub-directory
        destinationDir new File("${projectDir}/.....")

        // Consumer was only introduced in API-24; required for API-21
        classRename 'java.util.function.Consumer', 'org.atalk.util.function.Consumer'

        // Duration was added in API level-26; see https://github.com/JakeWharton/ThreeTenABP
        classRename 'java.time.Duration', 'org.threeten.bp.Duration'

        // Clean up and optimize call to weupnp call - reduces threads avoid time race condition
        classDelete 'org.ice4j.ice.harvest.UPNPHarvester**'
    }
}

Note: 
- Set distributionUrl=https://services.gradle.org/distributions/gradle-7.6-bin.zip in gradle-wrapper.properties;
   gradle-8.x does not generate the required smack jarjar files at all.