I want to publish an obfuscated jar (using Proguard) and I don’t want the un-obfuscated jar to “escape” so I don’t want it published.
When using the maven-publish plugin, the POM does not get the dependencies generated unless I use “from components.java” instead of “archive someJar” so when I have this:
publishing {
publications {
main(MavenPublication) {
//from components.java // <-publishes unobfuscated jar
// Below uses right jar, but dependency info is omitted from pom
artifact(file("$projectDir/build/proguard/obfuscated.jar")) {
builtBy obfuscate
}
}
}
}
I get the right jar with a bad pom.xml
The obvious thing to try is to copy the obfuscated jar over top of the unobfuscated jar before the upload happens. That gets ugly though. Without eventually restoring the original jar, the jar task will see the mismatched output and always run for example.
Do we have any best-practices for dealing with obfuscation yet?
by replacing the artifacts AFTER doing “from components.java” the pom is generated with the dependencies, but the artifact from components.java is not included. The docs here were very confusing as they stated, "For example, to exclude the dependencies declared by a component and instead use a custom set of artifacts"
I misinterpreted that as the dependencies would be excluded from the pom
@swpalmer do you have a complete example? Looks like you are one of a very few people who got this working and there’s still no good guides online on how to do it
This seems to have the least side-effects. The thing to note is that the default artifact is the unobfuscated jar. So sibling projects that simply declare a project dependency will get the unobfuscated jar. You can clear the artifacts and add the obfuscated jar to work around that.
thank you, for completeness what does your obfuscate task look like? how do you set libraryjars to the dependencies that don’t form part of the fat jar (and the java runtime?)
task obfuscate(type: proguard.gradle.ProGuardTask, dependsOn: jar) {
mustRunAfter ('javadoc')
inputs.file file("${jar.archivePath}")
outputs.file file("$buildDir/proguard/${project.name}-${project.version}.jar")
injars "${jar.archivePath}"
// JDK 8 and below use jars on the classpath
if (JavaVersion.current().java8Compatible && !JavaVersion.current().java9Compatible) {
println "Obfuscation inputs based on JDK 8 layout."
libraryjars "$javaHome/lib/rt.jar"
libraryjars "$javaHome/lib/jce.jar"
libraryjars "$javaHome/lib/ext/jfxrt.jar"
} else {
// JDK 9 and above use modules on the module-path
println "Obfuscation inputs based on JDK 9+ module layout."
def jdkModuleList = [
'java.base', 'java.datatransfer', 'java.desktop',
'java.instrument', 'java.logging',
'java.management', 'java.prefs', 'java.rmi',
'java.scripting', 'java.xml',
'jdk.attach'
]
jdkModuleList.forEach {
libraryjars "$javaHome/jmods/${it}.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
}
target '10' // JDK 9 is obsolete, would target 11, but Proguard can't deal with 11's class files yet
}
// dependencies
configurations.runtime.files.each {
libraryjars it, filter: '!META-INF/versions/**'
}
outjars "$buildDir/proguard/${project.name}-${project.version}.jar"
printseeds "$buildDir/proguard/proguard_seeds.txt"
printmapping "$buildDir/proguard/proguard_map.txt"
configuration 'src/main/proguard/configuration.pro'
}
I avoid fat jars, but there was a project that used them and for that I used a configuration for which dependencies should be included in the fat jar.
something like this: