2

I have an applet, which I was writing in Java. Recently, I thought that it would be good to add some Scala code to it (since Scala has good interoperability with Java). Everything works fine, but when I try to optimize the resulting jars using ProGuard, I have java.lang.StackOverflowError. How can I fix it?

Error:

The following error occurred while executing this line:
/var/www/parrot/Parrot/build.xml:84: 
java.lang.StackOverflowError
    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 ...

My ant configuration for proguard:

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

And by the way - there is nothing fancy about Scala code there, actually it is just as simple as

package scala1
object Main {
    def sum = 14
}

which is called from java:

System.err.println(scala1.Main.sum());
Rogach
  • 26,050
  • 21
  • 93
  • 172

2 Answers2

2

There is a known problem related to this; see this troubleshooting link.

However, the link is talking about complicated code. Your code would appear to be simple.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

I played around with proguard configuration, and found that if I set "mergeinterfacesaggressively" to "false", everything starts to work.

I will notify the library owner about this, and I hope this question will help someone.

Rogach
  • 26,050
  • 21
  • 93
  • 172
  • I'm having the same issue in my Android project, but I never set -mergeinterfacesaggressively so I'm at a bit of a loss what to do. – Christopher Perry Jul 09 '12 at 04:18
  • @ChristopherPerry - have you tried turning off other switches and working with simplified snippet of code? Maybe there is some other thing that gets in the way. – Rogach Jul 09 '12 at 11:01