Tagged: proguard

Hiding dependencies by Shading and ProGuarding


Let’s say your library depends on commons-lang and you don’t want them exposed.

make it optional

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <scope>compile</scope>
  <optional>true</optional>
</dependency>

shade it

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.4.2</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <relocations>
          <relocation>
            <pattern>org.apache.commons.lang3</pattern>
            <shadedPattern>your.main.commons.lang3</shadedPattern>
          </relocation>
        </relocations>
      </configuration>
    </execution>
  </executions>
</plugin>

proguard it

<plugin>
  <groupId>com.github.wvengen</groupId>
  <artifactId>proguard-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>proguard</id>
      <phase>package</phase>
      <goals>
        <goal>proguard</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <addMavenDescriptor>true</addMavenDescriptor>
    <includeDependency>flase</includeDependency>
    <options>
      <option>
        -dontobfuscate
        -dontoptimize
        -keepattributes *Annotation*
        -keepattributes Signature
        -keepattributes InnerClasses
        -keep class your.main.* { *; }
      </option>
    </options>
    <libs>
      <lib>${java.bootstrap.classes}</lib>
      <lib>${java.cryptographic.extension.classes}</lib>
      <lib>${java.secure.socket.extension.classes}</lib>
    </libs>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>net.sf.proguard</groupId>
      <artifactId>proguard-base</artifactId>
      <version>5.2.1</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
</plugin>

proguard-with-maven


FIY, the latest ProGuard(4.11) doesn’t work with JDK 8. And the 5.0(beta) is on its way.

In my previous entry(profiling the bootstrap classes for proguard in maven), I tried to use different profiles for denoting system-dependent JDK libraries used with proguard in maven.

Things change.

I wrote a simple maven project using same aliases for those JDK libraries.

clone it out

$ git clone git@github.com:jinahya/proguard-with-maven-example.git

pom.xml

/project/properties

<project ...>
  ...
  <properties>
    <java.bootstrap.classes>
      ${java.home}/lib/rt.jar
    </java.bootstrap.classes>
    <java.cryptographic.extension.classes>
      ${java.home}/lib/jce.jar
    </java.cryptographic.extension.classes>
    <java.secure.socket.extension.classes>
      ${java.home}/lib/jsse.jar
    </java.secure.socket.extension.classes>
  </properties>
  ...
</project>

/project/build/plugins

<project ...>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <!--groupId>com.pyx4me</groupId-->
        <groupId>com.github.wvengen</groupId>
        <artifactId>proguard-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>proguard</id>
            <phase>package</phase>
            <goals>
              <goal>proguard</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <options>
            <option>-keep public class * { public protected *; }</option>
          </options>
          <libs>
            <lib>${java.bootstrap.classes}</lib>
            <lib>${java.cryptographic.extension.classes}</lib>
            <lib>${java.secure.socket.extension.classes}</lib>
          </libs>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>net.sf.proguard</groupId>
            <artifactId>proguard-base</artifactId>
            <version>4.10</version>
            <scope>runtime</scope>
          </dependency>
        </dependencies>
      </plugin>
    ...
  </build>
  ...
  <!--profiles--> <!-- no profiles @ * -->
  ...
</project>

I tested with following systems.

Windows 7

>java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b16)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

>mvn --version
Apache Maven 3.1.0 (893ca28a1da9d5f51ac03827af98bb730128f9f2; 2013-06-28 11:15:32+0900)
Maven home: D:\programs\apache-maven-3.1.0\bin\..
Java version: 1.7.0_25, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.7.0_25\jre
Default locale: en_US, platform encoding: MS949
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

>mvn --quiet clean package
 [proguard] ProGuard, version 4.10
 [proguard] Reading program jar [\...\..._proguard_base.jar] (filtered)
 [proguard] Reading library jar [C:\Program Files\Java\jdk1.7.0_25\jre\lib\rt.jar]
 [proguard] Reading library jar [C:\Program Files\Java\jdk1.7.0_25\jre\lib\jce.jar]
 [proguard] Reading library jar [C:\Program Files\Java\jdk1.7.0_25\jre\lib\jsse.jar]
 [proguard] Preparing output jar [\...\proguard-with-maven-1.0-SNAPSHOT.jar]
 [proguard]   Copying resources from program jar [\...\..._proguard_base.jar] (filtered)

>

Ubuntu 13.04 Server

$ java -version
java version "1.7.0_25"
OpenJDK Runtime Environment (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.13.04.2)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)

$ mvn -version
Apache Maven 3.1.0 (893ca28a1da9d5f51ac03827af98bb730128f9f2; 2013-06-28 11:15:32+0900)
Maven home: /opt/apache-maven-latest
Java version: 1.7.0_25, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-7-openjdk-amd64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.8.0-27-generic", arch: "amd64", family: "unix"

$ mvn --quiet clean package
 [proguard] ProGuard, version 4.10
 [proguard] Reading program jar [/.../..._proguard_base.jar] (filtered)
 [proguard] Reading library jar [/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar]
 [proguard] Reading library jar [/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/jce.jar]
 [proguard] Reading library jar [/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/jsse.jar]
 [proguard] Preparing output jar [/.../proguard-with-maven-1.0-SNAPSHOT.jar]
 [proguard]   Copying resources from program jar [/.../..._proguard_base.jar] (filtered)

$

Xubuntu 13.04 Desktop

$ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) Client VM (build 23.25-b01, mixed mode)

$ mvn --quiet clean package
Apache Maven 3.1.0 (893ca28a1da9d5f51ac03827af98bb730128f9f2; 2013-06-28 11:15:32+0900)
Maven home: /opt/apache-maven-latest
Java version: 1.7.0_25, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-7-oracle/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.8.0-27-generic", arch: "i386", family: "unix"

$ mvn --quiet clean package
 [proguard] ProGuard, version 4.10
 [proguard] Reading program jar [/.../..._proguard_base.jar] (filtered)
 [proguard] Reading library jar [/usr/lib/jvm/java-7-oracle/jre/lib/rt.jar]
 [proguard] Reading library jar [/usr/lib/jvm/java-7-oracle/jre/lib/jce.jar]
 [proguard] Reading library jar [/usr/lib/jvm/java-7-oracle/jre/lib/jsse.jar]
 [proguard] Preparing output jar [/.../proguard-with-maven-1.0-SNAPSHOT.jar]
 [proguard]   Copying resources from program jar [/.../..._proguard_base.jar] (filtered)

$ 

OS X

$ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

$ mvn --version
Apache Maven 3.1.0 (893ca28a1da9d5f51ac03827af98bb730128f9f2; 2013-06-28 11:15:32+0900)
Maven home: /usr/local/Cellar/maven/3.1.0/libexec
Java version: 1.7.0_25, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.8.4", arch: "x86_64", family: "mac"

$ mvn --quiet clean package
 [proguard] ProGuard, version 4.10
 [proguard] Reading program jar [/.../..._proguard_base.jar] (filtered)
 [proguard] Reading library jar [/.../rt.jar]
 [proguard] Reading library jar [/.../jce.jar]
 [proguard] Reading library jar [/.../jsse.jar]
 [proguard] Preparing output jar [/.../proguard-with-maven-1.0-SNAPSHOT.jar]
 [proguard]   Copying resources from program jar [/.../..._proguard_base.jar] (filtered)

$ 

profiling the bootstrap classes for proguard in maven


Obsoluted by a new blog entry: proguard-with-maven

<project>
  <properties>
    <!-- default path for Windows -->
    <java.bootstrap.classes>${java.home}/lib/rt.jar</java.bootstrap.classes>
    <java.cryptographic.extension.classes>${java.home}/lib/jce.jar</java.cryptographic.extension.classes>
    <java.secure.socket.extension.classes>${java.home}/lib/jsse.jar</java.secure.socket.extension.classes>
  </properties>
  <build>
    <plugins>
      <plugin>
        <!--groupId>com.pyx4me</groupId-->
        <groupId>com.github.wvengen</groupId>
        <artifactId>proguard-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>proguard</id>
            <phase>package</phase>
            <goals>
              <goal>proguard</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <injar>${project.build.finalName}-jar-with-dependencies.jar</injar>
          <outjar>${project.buil.finalName}-proguarded</outjar>
          <options>
            <option>-keep public class * { *; }</option>
          </options>
          <libs>
            <lib>${java.bootstrap.classes}</lib>
            <lib>${java.cryptographic.extension.classes}</lib>
            <lib>${java.secure.socket.extension.classes}</lib>
          </libs>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>net.sf.proguard</groupId>
            <artifactId>proguard-base</artifactId>
            <version>x.x</version>
            <scope>runtime</scope>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>mac</id>
      <activation>
        <os>
          <family>mac</family>
        </os>        
      </activation>
      <properties>
        <!-- path for OS X -->
        <java.bootstrap.classes>${java.home}/../Classes/classes.jar</java.bootstrap.classes>
        <java.cryptographic.extension.classes>${java.home}/../Classes/jce.jar</java.cryptographic.extension.classes>
        <java.secure.socket.extension.classes>${java.home}/../Classes/jsse.jar</java.secure.socket.extension.classes>
      </properties>
    </profile>
  </profiles>
</project>