【问题标题】:How to publish proguard JAR as Maven Artifact using Gradle Publish Plugin如何使用 Gradle Publish Plugin 将 proguard JAR 发布为 Maven Artifact
【发布时间】:2019-12-15 10:42:16
【问题描述】:

我正在尝试将由 Gradle 6.0.1 ProGuard 插件创建的模糊 JAR 发布到 Maven 存储库。在过去的几天里,我学到了很多关于 Gradle 配置、变体和工件的知识,但我似乎无法完成这项工作。我相信相关文档是here

我创建了一个minimal example showing my intended setup on Github

如果我在这个项目上运行./gradlew publish,我会收到以下错误。

Execution failed for task ':publishMyLibraryPublicationToMyRepoRepository'.
> Failed to publish publication 'myLibrary' to repository 'myRepo'
   > Invalid publication 'myLibrary': multiple artifacts with the identical extension and classifier ('jar', 'null').

我还尝试了已弃用的 maven 插件。不幸的是,这个插件忽略了自定义的 ProGuard jar。

有人可以就如何用 proguard 任务中的混淆 Jar 替换 JAR 任务中的原始 JAR 给我任何建议吗?

编辑: 我能够从this thread 获得解决方案。 Github 上的最小示例包含修补版本。随意看看。我将把工作的 build.gradle 放到下面的答案中。

【问题讨论】:

    标签: java maven gradle proguard


    【解决方案1】:

    添加classifier = "proguard" 解决了它,虽然我不熟悉proguard 来确定发布是否正确。

    artifacts {
        proguard(new File(proguard.outJarFiles[0])) {
            builtBy(proguard)
            classifier = "proguard"
        }
    }
    

    这是为我发布的内容:

    我可以看到原始 JAR 是 592 字节,而 proguard 是 410 字节,所以我假设它正常工作。

    此外,在调试您的问题时,我重构为使用我推荐使用的 Kotlin DSL

    import proguard.gradle.ProGuardTask
    
    plugins {
        `java-library`
        `maven-publish`
    }
    
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath("net.sf.proguard:proguard-gradle:6.2.2")
        }
    }
    
    group = "org.example"
    version = "1.0.0"
    
    repositories {
        jcenter()
    }
    
    configurations {
        val implementation by this
        val runtimeOnly by this
        create("proguard") {
            isCanBeConsumed = false
            isCanBeResolved = false
            extendsFrom(implementation, runtimeOnly)
            attributes {
                attribute(Attribute.of("org.gradle.usage", String::class.java), Usage.JAVA_API)
                attribute(Attribute.of("org.gradle.category", String::class.java), Category.LIBRARY)
                attribute(Attribute.of("org.gradle.libraryelements", String::class.java), LibraryElements.JAR)
                attribute(Attribute.of("org.gradle.dependency.bundling", String::class.java), Bundling.EXTERNAL)
            }
        }
    }
    
    dependencies {
        api("org.apache.commons:commons-math3:3.6.1")
        implementation("com.google.guava:guava:23.0")
        testImplementation("junit:junit:4.12")
    }
    
    val proguard by tasks.registering(ProGuardTask::class) {
        description = "Optimizes and obfuscates the created distribution jar."
        dependsOn(tasks.named("jar"))
        verbose()
    
        injars("$buildDir/libs/${project.name}-${project.version}.jar")
        outjars("$buildDir/proguard/${project.name}-${version}.jar")
    
        if (System.getProperty("java.version").startsWith("1.")) {
            libraryjars("${System.getProperty("java.home")}/lib/rt.jar")
        } else {
            libraryjars(mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), "${System.getProperty("java.home")}/jmods/java.base.jmod")
        }
    
        libraryjars(configurations.named("runtimeClasspath").get().files)
    
        printmapping("out.map")
    
        keep("""
            public class * {
                public protected *;
            }
        """.trimIndent())
    
        keepclassmembers(mapOf("allowoptimization" to true), """
            enum * {
                public static **[] values();
                public static ** valueOf(java.lang.String);
            }
        """.trimIndent())
    
        keepclassmembers("""
            class * implements java.io.Serializable {
                static final long serialVersionUID;
                static final java.io.ObjectStreamField[] serialPersistentFields;
                private void writeObject(java.io.ObjectOutputStream);
                private void readObject(java.io.ObjectInputStream);
                java.lang.Object writeReplace ();
                java.lang.Object readResolve ();
            }
        """.trimIndent())
    
        overloadaggressively()
    }
    
    
    val javaComponent = project.components.findByName("java") as AdhocComponentWithVariants
    javaComponent.addVariantsFromConfiguration(configurations.getByName("proguard")) {
        // I have no idea what I should do here and the documentation is very confusing
    }
    
    publishing {
        publications {
            create<MavenPublication>("myLibrary") {
                from(components["java"])
                artifact(proguard.get().outJarFiles[0]) {
                    builtBy(proguard.get())
                    classifier = "proguard"
                }
            }
        }
    
        repositories {
            maven {
                name = "myRepo"
                url = uri("file://${buildDir}/repo")
            }
        }
    }
    
    tasks.named("publish").configure {
        dependsOn(tasks.named("proguard"))
    }
    

    【讨论】:

    • 谢谢。我明天会检查,如果 ist 有效,给你打勾。
    • 嗨。不幸的是,这不是我正在寻找的解决方案。我不只是希望混淆的 JAR 与普通的 JAR 并排,而是希望普通的 JAR 被混淆的 JAR 覆盖。我发现一个线程在做非常相似的事情 here 并且能够得出一个解决方案。
    【解决方案2】:

    正如已经在问题中编辑的那样,我找到了一个解决方案并相应地更新了 Github-Project。由于 Stackoverflow 喜欢拥有本地信息而不是依赖链接,因此我将工作 build.gradle 文件作为答案发布在这里。 Github-Project 的其余部分只是 gradle init 创建的 Java 库项目。

    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'net.sf.proguard:proguard-gradle:6.2.2'
            classpath 'net.sf.proguard:proguard-base:6.2.2'
        }
    }
    
    plugins {
        id 'java-library'
        id 'maven-publish'
    }
    
    group = 'org.example'
    version = '1.0.0'
    
    repositories {
        jcenter()
    }
    
    dependencies {
        api 'org.apache.commons:commons-math3:3.6.1'
        implementation 'com.google.guava:guava:23.0'
        testImplementation 'junit:junit:4.12'
    }
    
    task createObfuscated(type: proguard.gradle.ProGuardTask, dependsOn: 'jar') {
        description 'Optimizes and obfuscates the created distribution jar.'
        verbose
    
        injars  "${buildDir}/libs/${project.name}-${version}.jar"
        outjars "${buildDir}/obf/${project.name}-${version}.jar"
    
        if (System.getProperty('java.version').startsWith('1.')) {
            libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
        } else {
            libraryjars "${System.getProperty('java.home')}/jmods/java.base.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
        }
        libraryjars configurations.findByName('runtimeClasspath').getFiles()
    
        printmapping 'out.map'
    
        keep 'public class * { \
            public protected *; \
        }'
    
        keepclassmembers allowoptimization: true, 'enum * { \
            public static **[] values(); \
            public static ** valueOf(java.lang.String); \
        }'
    
        keepclassmembers 'class * implements java.io.Serializable { \
            static final long serialVersionUID; \
            static final java.io.ObjectStreamField[] serialPersistentFields; \
            private void writeObject(java.io.ObjectOutputStream); \
            private void readObject(java.io.ObjectInputStream); \
            java.lang.Object writeReplace(); \
            java.lang.Object readResolve(); \
         }'
    
         overloadaggressively
    }
    
    task copyObfuscated(type: Copy, dependsOn: createObfuscated) {
        from "${buildDir}/obf"
        into "${buildDir}/libs"
        include '*.jar'
    }
    
    task deleteObfuscated(type: Delete, dependsOn: copyObfuscated) {
        delete '${buildDir}/obf'
    }
    
    task proguard dependsOn deleteObfuscated
    
    publishing {
        publications {
            myLibrary(MavenPublication) {
                from components.java
            }
        }
    
        repositories {
            maven {
                name = 'myRepo'
                url = "file://${buildDir}/repo"
            }
        }
    }
    
    publish.dependsOn proguard
    
    wrapper {
        gradleVersion '6.0.1'
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      • 2016-04-04
      • 2017-11-01
      相关资源
      最近更新 更多