Proguard with Scala - Error 4

Proguard 5.1 does not work during the pruning phase with "Error: 4".
The proguard config file looks like this:

-injars      ReversiRaw.jar
-outjars     Reversi.jar
-libraryjars <java.home>/lib/rt.jar
-libraryjars <java.home>/lib/ext/jfxrt.jar

-dontwarn scala.**

-dontnote
-dontwarn
-ignorewarnings

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

-keepclassmembers class * {
    ** MODULE$;
}

      

Basically this is the Scala default setting as stated in the documentation.
Download link to jar file that compiles to play: download

What is "Error: 4" and how can I fix or avoid it?

+3


source to share


3 answers


Another solution can use gradle.

This is the gradle source for building, getting the fat file (shadowJar file) and compressing the jar file with proguard.

buildscript {
    repositories { 
        flatDir dirs: '/Users/smcho/Dropbox/smcho/bin/jar/proguard5.2/lib'
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath ':proguard'
        classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.0'
    }
}

apply plugin: 'scala'
apply plugin: 'com.github.johnrengelman.shadow'

repositories{
    mavenCentral()
}

shadowJar {
  manifest {
    attributes 'Main-Class': 'HelloWorld'
  }
}

dependencies{
    compile "org.scala-lang:scala-library:2.11.5"
}

task proguard(type: proguard.gradle.ProGuardTask) {
//    injars './build/classes'
    injars './build/libs/scala_all_jar-all.jar'
    outjars './build/libs/main.jar'
    libraryjars "${System.getProperty('java.home')}/lib/rt.jar"

    dontwarn
    dontnote
    ignorewarnings

    keepattributes 'SourceFile,LineNumberTable'

    keepclasseswithmembers 'public class * { \
        public static void main(java.lang.String[]); \
    }'
}

      



You need to install flatDir dirs

to point to where your proguard files are.

gradle build

will give you the compiled classes and jar file, gradle shadowJar

get the big jar file, and gradle proguard

give you a compressed jar file named main.jar

.

I also added the source: https://dl.dropboxusercontent.com/u/10773282/share/2015/scala_all_jar.zip

+1


source


While the answers to prosseek's queries were helpful, I was able to get a simple Pro-Guard Hello-World configuration without working with class files. (Unlike prosseek, I haven't tried Uberjar, though).

Adapting from the Scala example in the Proguard manual , I ended up with a simple *.pro

one that looks something like this:

-injars      build/install/HelloScala/lib/helloscala-1.0.jar
-injars      build/install/HelloScala/lib/scala-library-2.11.6.jar(!META-INF/MANIFEST.MF)
-outjars     helloscalapro.jar
-libraryjars <java.home>/lib/rt.jar

-dontwarn scala.**

//etc.

      



Filtering the manifest from the Scala library.

I also got error 4 when the version of the Scala library I pushed to injar

was a different (patch) version than the Scala version I compiled it with.

+1


source


I also had the same problem where my jarar jar file was a fat jar from plugins build via command sbt assembly

. The solution to this problem is not to use a bunch of fat, but to use classes generated from scala and other java / scala libraries to get a slimmed jar file.

On my mac (OS X 10.10) I have this proguard file (named your.pro).

-injar classes
-injar /usr/local/Cellar/scala/2.11.5/libexec/lib/scala-library.jar(!META-INF/MANIFEST.MF)
-outjar main.jar
-libraryjar /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Classes/classes.jar

-dontwarn
-dontnote
-ignorewarnings

-optimizationpasses 2
-optimizations !code/allocation/variable

-keep,allowoptimization,allowshrinking class * { *; }
-keepattributes SourceFile,LineNumberTable

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

      

This is the directory structure.

.
├── classes
│   ├── HelloWorld$.class
│   ├── HelloWorld$delayedInit$body.class
│   ├── HelloWorld.class
│   └── META-INF
│       └── MANIFEST.MF
├── src
│   └── hello.scala
└── your.pro

      

hello.scala looks like this:

object HelloWorld extends App 
{
    println("Hello, world")
}

      

You can get the class files in the class directory with scalac src/hello.scala -d classes

. A MANIFEST file must be added to indicate what the main class is. Careful with the last blank line.

Manifest-Version: 1.0
Main-Class: HelloWorld
... blank line should be here ...

      

The class file is generated from scala. With proguard @your.pro

I could get a working jar file.

I have uploaded the example at https://dl.dropboxusercontent.com/u/10773282/share/2015/scala_class.zip

0


source







All Articles