Obfuscated Jars - What are the best practices?

This is the basic template:

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:

configurations {
	infatjar
}

sourceSets {
	main.compileClasspath += configurations.infatjar
	main.runtimeClasspath += configurations.infatjar
	test.compileClasspath += configurations.infatjar
	test.runtimeClasspath += configurations.infatjar
}

and the obfuscate task is modified to include the dependencies like this:

configurations.infatjar.files.each {
	injars it
}
// dependencies
(configurations.runtime - configurations.infatjar).files.each {
	libraryjars it, filter: '!META-INF/versions/**'
}

So dependencies that are in the ‘infatjar’ configuration are added as injars instead of libraryjars

2 Likes