Reputation: 11841
Proguard 5.1 fails during the shrinking phase with "Error: 4".
The proguard configuration file is as follows:
-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$;
}
Which is mostly the default Scala configuration given in the documentation.
A download link to the jar file being compreseed for reproducing: download
What is that "Error: 4", and how can it be fixed or avoided?
Upvotes: 3
Views: 561
Reputation: 51
While prosseek's answers was helpful, I was able to get a simple Hello-World proguard configuration working without having to resort to class files. (Unlike prosseek, I didn't try an Uberjar, though).
Adapting from the Scala example in the Proguard manual, I got a simple *.pro
would look something like:
-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 out the manifest from the Scala library.
I also got Error 4 when the version of the Scala library I passed to injar
was a different (patch) version than the Scala version I'd compiled it with.
Upvotes: 1
Reputation: 191099
The other solution might be using gradle.
This is the gradle source to build, get the fat file (shadowJar file), and shrink 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 set flatDir dirs
to point to where your proguard files are located.
gradle build
will get you the compiled classes and jar file, gradle shadowJar
will get you big jar file, and gradle proguard
will give you the slimmed jar file named main.jar
.
I also uploaded the source: https://dl.dropboxusercontent.com/u/10773282/share/2015/scala_all_jar.zip
Upvotes: 1
Reputation: 191099
I also had the same issue when my injar jar file is a fat jar from plugins assembly through sbt assembly
command.
The solution to this problem is not to use the fat jar, but to use the classes generated from scala, and other java/scala libraries to get 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 is as follows:
object HelloWorld extends App
{
println("Hello, world")
}
You can get the class files in the classes directory with scalac src/hello.scala -d classes
. The MANIFEST file should be added to tell which is the main class. Careful with the last blank line.
Manifest-Version: 1.0
Main-Class: HelloWorld
... blank line should be here ...
The classes file is generated from scala.
With proguard @your.pro
, I could get working jar file.
I uploaded the example in https://dl.dropboxusercontent.com/u/10773282/share/2015/scala_class.zip
Upvotes: 0