3

I am new to obfuscation and trying to figure out how to obfuscate a java application created using gradle. The idea is that the runnable jar created after the gradle build is obfuscated. Here is the gradle file

plugins {
    // Apply the java plugin to add support for Java
    id 'java'
    // Apply the application plugin to add support for building a CLI application.
    id 'application'
}
repositories {
     mavenCentral()
}
dependencies {
    // This dependency is used by the application.
    implementation 'com.google.guava:guava:29.0-jre'
    // Use JUnit test framework
    testImplementation 'junit:junit:4.13'
}
application {
    // Define the main class for the application.
    mainClassName = 'com.abc.gradle.hello.App'
}
jar {
    manifest {
        attributes 'Main-Class': 'com.abc.gradle.hello.App'
    }
}
    
jfk
  • 4,335
  • 34
  • 27
  • These might help: https://stackoverflow.com/questions/12114096/how-do-i-use-proguard https://www.guardsquare.com/en/products/proguard/manual/usage – Nosrep Oct 14 '20 at 15:12
  • Running proguard on a jar is no problem,. I need a solution to integrate it in the gradle project – jfk Oct 14 '20 at 15:14
  • 1
    Gradle plugin: https://www.guardsquare.com/en/products/proguard/manual/gradleplugin – Nosrep Oct 14 '20 at 15:16

1 Answers1

8

Finally I could achieve this with the following steps

  1. Create a runnable jar with all dependent libraries copied to a directory "dependencies" and add the classpath in the manifest.

    task createJar(type: Jar) {
       println("Cleaning...")
       clean
       manifest {
       attributes('Main-Class': 'com.abc.gradle.hello.App',
         'Class-Path': configurations.default.collect { 'dependencies/' + 
          it.getName() }.join(' ')
          )
       }
       from {
          configurations.compile.collect { it.isDirectory() ? it : zipTree(it) 
          }
       } with jar
       println "${outputJar} created"
       }
    
  2. Copy the dependencies

    task copyDepends(type: Copy) {
      from configurations.default
      into "${dependsDir}"
    }
    
  3. Obfuscate the library with Proguard

    task proguard(type: proguard.gradle.ProGuardTask) {
       println("Performing obfuscation..")
       configuration 'proguard.conf'
       injars "${outputJar}"
       outjars "${buildDir}/libs/${rootProject.name}_proguard.jar"
       libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
       libraryjars "${dependsDir}"
     }
    

Here is the complete build.gradle

buildscript {
 repositories {
    mavenCentral()
 }
 dependencies {
    classpath 'net.sf.proguard:proguard-gradle:6.0.3'
    classpath 'net.sf.proguard:proguard-base:6.0.3'
 }
}

plugins {
 id 'java'
 id 'application'
}

repositories {
  mavenCentral()
}

dependencies {
   implementation 'org.slf4j:slf4j-api:1.7.30'
   implementation 'ch.qos.logback:logback-classic:1.2.3'
   implementation 'ch.qos.logback:logback-core:1.2.3'
   testImplementation 'junit:junit:4.13'
}

def outputJar = "${buildDir}/libs/${rootProject.name}.jar"
def dependsDir = "${buildDir}/libs/dependencies/"
def runnableJar = "${rootProject.name}_fat.jar";

task copyDepends(type: Copy) {
 from configurations.default
 into "${dependsDir}"
}

task createJar(type: Jar) {
 println("Cleaning...")
 clean
 manifest {
    attributes('Main-Class': 'com.abc.gradle.hello.App',
            'Class-Path': configurations.default.collect { 'dependencies/' + 
   it.getName() }.join(' ')
    )
  }
  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
   } with jar
   println "${outputJar} created"
  }

task proguard(type: proguard.gradle.ProGuardTask) {
   println("Performing obfuscation..")
   configuration 'proguard.conf'
   injars "${outputJar}"
   outjars "${buildDir}/libs/${rootProject.name}_proguard.jar"

   libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
   libraryjars "${dependsDir}"

  }

Proguard.conf

-keep public class * {
   public * ;
 }

Gradle commands to obfuscate

gradle createJar
gradle copyDepends
gradle proguard
jfk
  • 4,335
  • 34
  • 27