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?
source to share
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
source to share
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.
source to share
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
source to share