Proguard说它找不到任何类。

7

我正在使用Proguard和Spring MVC应用程序以及Maven进行开发。

我的pom.xml文件中的构建部分如下:

<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>

我也尝试过:

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

当我运行以下命令时:

mvn clean install

构建失败信息:
[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]

似乎它已经正确获取了我的jar文件,因为之前的消息都显示正常:
[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, ....

此外,你建议我使用哪些选项?这是一个Spring MVC,所以我有以下注释:
@Autowired @Service @Repository @Controller 因此,这些类/字段中的任何一个都不应该被重命名。
(我的目标只是让反编译变得困难,使得他们不能只是反编译并使用代码。混淆会让他们使用它,但是除非他们重新编写代码,否则他们将无法维护代码库。我没有任何花哨的算法,所以在这方面我没有什么需要隐藏的。)
更新
让我在这里清楚一下,我的Spring MVC在使用Maven时,进行mvn clean install会生成一个myapp.war文件和一个 exploded war myapp/(这是我想要部署到生产环境的内容,而不是myapp.war文件)。
我的myapp文件夹中包含:
/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/

那么 ProGuard 应该在 /target/myapp/web-inf/classes 文件夹中进行混淆,对吗?如何告诉它这样做?

更新2

现在我遇到了这个问题:

好的,我得到的是:failed to execute goal ...proguard .. Can't rename /Users/me/dev/git/project1/myapp/target/myapp/web-inf/classes(请参阅我的更新部分,了解我在 pom.xml 中所做的更改)

我使用以下内容更改了 pom.xml:

            <configuration>
                <obfuscate>true</obfuscate>

                <injar>${project.build.finalName}/WEB-INF/classes/</injar>
                <inFilter>com/myapp/**</inFilter>
            </configuration>

请看我的答案和解决方法,ProGuard不支持这个特定的配置。 - Jonathan S. Fisher
2个回答

5

ProGuard 过滤器作用于文件名,因此

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

可能不会匹配任何类文件。您可能希望

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

查看ProGuard手册 > 使用 > 文件过滤器


啊,是的,我之前没有注意到他在之前的问题中提到过这个(那个问题一开始是不同的)。 - Dave Newton
如何将Proguard指向我的已解压的war文件而不是war文件本身?即/target/myapp/WEB-INF/classes/ - Blankman
我有点困惑,它是期望 meta-inf/maven/ 文件夹中有我的类文件夹吗?还是检查包? - Blankman
好的,我没有理解:执行目标失败...proguard..无法重命名 /Users/me/dev/git/project1/myapp/target/myapp/web-inf/classes目录(请参见我的pom.xml更新部分了解我更改了什么)。 - Blankman
“无法重命名…”可能是来自于Maven或者pyx4me ProGuard Maven插件的消息,而不是来自ProGuard本身;所以我不太清楚。如果ProGuard正常工作,你应该会看到一些控制台信息:“读取程序……,准备输出……,复制资源……”。ProGuard只能处理一个与输入目录不同的输出目录。也许插件在移动结果方面遇到了问题。 - Eric Lafortune
那么,您建议我只使用命令行而不是Maven插件来运行Proguard吗? 我猜我可以将其作为Ant任务在Maven中运行,并采用更手动和明确的方式进行操作? - Blankman

2
您能放上您整个的pom文件吗?
通常情况下,Maven会编译到/target/classes目录下(即使是WAR文件),而WAR插件会在打包阶段之前将文件复制到web-inf/classes目录下。因此,您不应该手动使用Maven将类编译到web-inf/lib目录下。
编辑:好的,经过一番研究,我为您找到了答案。首先,根据ProGuard文档,您的war项目中不应该有任何类:

特别地,在war中WEB-INF/classes目录下的class文件应该被打包到jar文件中并放在WEB-INF/lib目录下。

您需要重新组织项目结构,使得您的Web类被构建成一个独立的JAR文件。一旦您构建了该JAR项目,您必须将它添加为WAR项目的依赖项。
一旦我创建了这样的配置,我就成功地构建了一个WAR项目。
<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>

请注意 "com.example.echo.EchoServlet"。由于 Proguard 将更改我的类名,我必须 "保留" 此 Servlet 名称,以便在 WAR 项目的 web.xml 中引用它。如果您使用基于注释的 Servlet 配置,则我想这将不是必需的。

有了注释,他必须使用-keepattributes参数,因为Proguard默认会剥离它们。 - jackrabbit
好的,我会尝试这个,谢谢你的帮助。我之前尝试了像你建议的那样将Proguard指向目标/类,但是没有起作用,仍然出现相同的错误,说无法重命名文件夹。 - Blankman
哎呀,赏金已经过期了 :( 不过我希望这个答案仍然能解决你的问题。如果它有效或者你需要任何帮助设置其他Maven项目,请务必接受它! - Jonathan S. Fisher
@Blankman,如果这对你有用,请给我一个答案接受和/或点赞。我为你研究了几个小时。如果不行,请告诉我。谢谢! - Jonathan S. Fisher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接