尝试使用 ProGuard 优化 Java+Scala 时出现 java.lang.***Error

Posted

技术标签:

【中文标题】尝试使用 ProGuard 优化 Java+Scala 时出现 java.lang.***Error【英文标题】:java.lang.***Error when trying to optimize Java+Scala with ProGuard 【发布时间】:2011-09-08 08:06:57 【问题描述】:

我有一个小程序,它是用 Java 编写的。最近,我认为在其中添加一些 Scala 代码会很好(因为 Scala 与 Java 具有良好的互操作性)。一切正常,但是当我尝试使用 ProGuard 优化生成的 jar 时,我有 java.lang.***Error。我该如何解决?

错误:

The following error occurred while executing this line:
/var/www/parrot/Parrot/build.xml:84: 
java.lang.***Error
    at proguard.classfile.util.SimplifiedVisitor.visitProgramClass(SimplifiedVisitor.java:53)
    at proguard.optimize.info.StaticInitializerContainingClassFilter.visitProgramClass(StaticInitializerContainingClassFilter.java:50)
    at proguard.classfile.ProgramClass.accept(ProgramClass.java:280)
    at proguard.classfile.ProgramClass.hierarchyAccept(ProgramClass.java:293)
    at proguard.classfile.ProgramClass.hierarchyAccept(ProgramClass.java:333)
    at proguard.classfile.ProgramClass.hierarchyAccept(ProgramClass.java:333)
    at proguard.classfile.ProgramClass.hierarchyAccept(ProgramClass.java:333)
    ... and so on, several thousand times ...

我的 proguard 的 ant 配置:

<proguard
    optimizationpasses="$optpass"
    obfuscate="true"
    verbose="true"
    target="6"
    printseeds="true"
    allowaccessmodification="true"
    overloadaggressively="true"
    mergeinterfacesaggressively="true"
    repackageclasses="def"
    >

    <injar file="dist/Parrot.jar" />
    <injar path="dist/lib/" /><!-- scala-library.jar is also in this lib directory -->
    <libraryjar path="/home/platon/java/jdk1.6.0_24/jre/lib/" />
    <outjar file="dist/ParrotOp.jar" filter="!**.SF" />

    <keep access="public" name="launch.parrotApp" />

    <keepclassmembers extends="java.lang.Enum">
        <method access="public static"
            type="**[]"
            name="values"
            parameters="" />
        <method access="public static"
            type="**"
            name="valueOf"
            parameters="java.lang.String" />
    </keepclassmembers>

        <!-- Processing the scala library (as shown in proguard manual) -->
        -dontwarn **$$anonfun$*
        -dontwarn scala.collection.immutable.RedBlack$Empty
        -dontwarn scala.tools.**,plugintemplate.**

        -keepclasseswithmembers public class * 
            public static void main(java.lang.String[]);
        

        -keep class * implements org.xml.sax.EntityResolver

        -keepclassmembers class * 
            ** MODULE$;
        

        -keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool 
            long eventCount;
            int  workerCounts;
            int  runControl;
            scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack;
            scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack;
        

        -keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread 
            int base;
            int sp;
            int runState;
        

        -keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask 
            int status;
        

        -keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue 
            scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head;
            scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail;
            scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe;
        

    </proguard>

顺便说一句 - Scala 代码没有什么花哨的,实际上它就像

package scala1
object Main 
    def sum = 14

从java中调用:

System.err.println(scala1.Main.sum());

【问题讨论】:

【参考方案1】:

有一个与此相关的已知问题;见this troubleshooting link。

但是,该链接正在谈论复杂的代码。您的代码看起来很简单。

【讨论】:

经过优化和混淆后,我敢肯定代码会变得相当复杂。【参考方案2】:

我玩弄了proguard配置,发现如果我将“mergeinterfacesaggressively”设置为“false”,一切都会开始工作。

我会将此通知图书馆所有者,希望这个问题对某人有所帮助。

【讨论】:

我在我的 android 项目中遇到了同样的问题,但我从来没有设置 -mergeinterfacesaggressively 所以我有点不知所措。 @ChristopherPerry - 您是否尝试过关闭其他开关并使用简化的 sn-p 代码?也许还有其他的事情妨碍了。

以上是关于尝试使用 ProGuard 优化 Java+Scala 时出现 java.lang.***Error的主要内容,如果未能解决你的问题,请参考以下文章

使用混淆ProGuard压缩代码和资源/减少方法数量

JAVA之代码混淆proguard

正余弦算法(SCA)求解单目标优化问题

正余弦算法(SCA)求解单目标优化问题

Scala 可运行 JAR 的 ProGuard 进程

Android 项目的代码混淆,Android proguard 使用说明