Crash when using IntStream
adrianbn opened this issue ยท 4 comments
adrianbn commented
Seems like yGuard has some trouble obfuscating code that uses IntStream. Here's a sample application that fails:
import java.util.Random;
public class Test {
private Random rng;
public Test(long seed) {
this.rng = new Random(seed);
}
/*
* Generates alphanumeric strings of given length
*/
public String randomAlphaString(int targetStringLength) {
int leftLimit = 48; // '0'
int rightLimit = 122; // 'z'
return rng.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(targetStringLength)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
public static void main(String[] args) {
Test t = new Test(1337);
System.out.println(t.randomAlphaString(10));
}
}
After obfuscating the jar, trying to execute it results in:
> java -jar build/libs/test-1.0-SNAPSHOT_obf.jar
Error: Unable to initialize main class com.example.Test
Caused by: java.lang.VerifyError: Operand stack underflow
Exception Details:
Location:
com/example/Test.A(I)Ljava/lang/String; @17: invokeinterface
Reason:
Attempt to pop empty stack.
Current Frame:
bci: @17
flags: { }
locals: { 'com/example/Test', integer, integer, integer }
stack: { 'java/util/stream/IntStream' }
Bytecode:
0000000: 1030 3d10 7a3e 2ab4 0014 1c1d 0460 b600
0000010: 23b9 0029 0200 1b85 b900 2d03 00b9 0031
0000020: 0400 c000 33b6 0037 b0
yGuy commented
How exactly did you obfuscate the jar? Did you try to use the shrinker? There are some known incompatibilities: https://yworks.github.io/yGuard/compatibility/
We have plans to improve the situation, though. @Fohlen - where is the corresponding issue, I can't seem to find it.
adrianbn commented
Hey @yGuy,
this is what I used to obfuscate:
task obfuscate {
dependsOn jar
group 'yGuard'
description 'Obfuscates and shrinks the java archive.'
doLast {
ant.taskdef(
name: 'yguard',
classname: 'com.yworks.yguard.YGuardTask',
classpath: sourceSets.main.runtimeClasspath.asPath
)
println(jar.archivePath)
def archivePath = jar.archivePath.absolutePath
ant.yguard {
inoutpair(in: archivePath, out: archivePath.replace(".jar", "_obf.jar"))
shrink(logfile: "${buildDir}/yshrink.log.xml") {
keep {
method(name: "void main(java.lang.String[])", "class": application.mainClassName)
}
}
rename(mainclass: application.mainClassName, logfile: "${buildDir}/yguard.log.xml") {
property(name: "error-checking", value: "pedantic")
}
}
}
thomasbehr commented
The shrink(logfile: "${buildDir}/yshrink.log.xml") {...}
part of your ant.yguard
target means that you are shrinking your application. Shrinking is not yet supported for Java 8 and newer class files.