Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proguard is saying it can't find any classes

I'm using proguard with a spring mvc application and maven.

My pom.xml's build section looks like:

<build>
        <finalName>myapp</finalName>
        <plugins>
           <plugin>
                <groupId>com.pyx4me</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <obfuscate>true</obfuscate>
                    <!--<options>-->
                        <!--<option>-keep public class</option>-->
                    <!--</options>-->
                    <injar>${project.build.finalName}</injar>
                    <injar>${project.build.finalName}</injar>
                    <inFilter>com.myapp.*</inFilter>
                </configuration>
            </plugin>
         </plugins>

I also tried:

<injar>${project.build.finalName}.war</injar>

When I run:

mvn clean install

Build failure message:

[proguard] Reading program war [/Users/me/dev/git/myproject/myapp/target/myapp.war] (filtered)
 [proguard] Error: The input doesn't contain any classes. Did you specify the proper '-injars' options?

ERROR] Failed to execute goal com.pyx4me:proguard-maven-plugin:2.0.4:proguard (default) on project myapp: Obfuscation failed (result=1) -> [Help 1]

It seems to have picked up my jar correctly as the messages before show:

[INFO] --- proguard-maven-plugin:2.0.4:proguard (default) @ myapp ---
[INFO] execute ProGuard [-injars, '/Users/me/dev/gitserver/myproject/myapp/target/myapp.war'(!META-INF/maven/**,com.myapp.*), -outjars, '/Users/me/dev/git/myproject/myapp/target/myapp_pg.war', -libraryjars, ....

Also, what options do you suggest I use? This is a spring mvc so I have annotations like:

  1. @Autowired
  2. @Service
  3. @Repository
  4. @Controller

So any of those classes/fields should not be renamed I would imagine.

(My goal is just to make it a headache to someone who decompiles, such that they can't just decompile and use the code. Obfuscating will let them use it, but they won't be able to maintain the codebase unless they re-write it. I don't have any fancy algorithms so I have nothing really to hide in that respect.)

Update

Let me be clear here, my spring mvc using maven for some reason (I'm new to maven) when doing a mvn clean install produces both a myapp.war file and a exploded war myapp/ (this is what I want to deploy in production, not the myapp.war file)

My myapp folder has:

/target/myapp/
/target/myapp/meta-inf (empty folder)
/target/myapp/web-inf
/target/myapp/web-inf/classes (com.myapp. ...)
/target/myapp/web-inf/lib/
/target/myapp/web-inf/ web.xml, application.xml (for spring)
/target/myapp/web-inf/views/

So proguard should be obfuscating in the /target/myapp/web-inf/classes folder right? How do I tell it to do so?

Update 2

I'm getting this now:

OK, I am not getting: failed to execute goal ...proguard .. Can't rename /Users/me/dev/git/project1/myapp/target/myapp/web-inf/classes (see my updates section for what I changed in my pom.xml)

I changed my pom.xml with:

            <configuration>
                <obfuscate>true</obfuscate>

                <injar>${project.build.finalName}/WEB-INF/classes/</injar>
                <inFilter>com/myapp/**</inFilter>
            </configuration>
like image 810
Blankman Avatar asked Jan 13 '12 03:01

Blankman


2 Answers

ProGuard filters work on file names, so

.....(!META-INF/maven/**,com.myapp.*)

probably won't match any class files. You probably want

.....(!META-INF/maven/**,com/myapp/**)

See ProGuard manual > Usage > File Filters

like image 182
Eric Lafortune Avatar answered Sep 18 '22 19:09

Eric Lafortune


Can you post your entire pom?

Normally, Maven compiles to /target/classes (Even for WAR files) and the WAR plugin does the copy to web-inf/classes right before the package phase. You should not be manually compiling classes to web-inf/lib with Maven.

EDIT: OK this has take quite a bit of research, but I've found an answer for you. First, according to the ProGuard documentation, you should not have ANY classes in your war project:

Notably, class files that are in the WEB-INF/classes directory in a war should be packaged in a jar and put in the WEB-INF/lib directory

You need to refactor your project so your web classes are built in a separate jar. Once you have built that jar project, you must add it as a dependency in your war project.

Once I created that setup, I was successfully able to build a war project with the following configuration:

<build>
        <plugins>
            <plugin>
                <groupId>com.pyx4me</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <inFilter>com/example/**</inFilter>
                    <libs>
                        <lib>${java.home}/lib/rt.jar</lib>
                        <lib>${java.home}/lib/jsse.jar</lib>
                    </libs>
                    <options>
                        <option>-keep class com.example.echo.EchoServlet</option>
                        <option>-injar ${project.build.directory}/${project.build.finalName}.${project.packaging}</option>
                        <option>-outjar ${project.build.directory}/${project.build.finalName}-proguarded.${project.packaging}</option>
                    </options>
                </configuration>
            </plugin>
        </plugins>
    </build>

Note the "com.example.echo.EchoServlet". Since progaurd was going to change the name of my classes, I had to "keep" this servlet name so I could reference it in the WAR project's web.xml. If you use annotation based servlet configuration, I imagine this won't be necessary.

like image 24
Jonathan S. Fisher Avatar answered Sep 22 '22 19:09

Jonathan S. Fisher