-
Notifications
You must be signed in to change notification settings - Fork 0
Generating and executing Java
Frizzante is able to generate and run Java methods. Because Java compilation is slow, Frizzante comes with a JavaBatchCompiler
that takes certain measures to avoid a situation where most of CPU time is spent compiling Java rather than executing it:
- Java methods are generated and compiled in batches of 100, thus avoiding compiler overhead;
- The methods are cached to avoid recompilation if the same method is generated again;
Since Java statements are terminated with a semicolon, which is a special character in Frizzante, the grammar needs to be declared as follows:
#option STANDALONE_SEMICOLONS
and optionally also:
#option TRAILING_PIPES
This way semicolons will only be considered rule terminators if they are alone on a line, and will be passed verbatim into the output otherwise. Pipes will be considered rule production separators only if they are at the end of the line.
#option STANDALONE_SEMICOLONS
main:
public static void run() {
body1 | body2
}
;
body1:
System.out.println("foo");
;
body2:
System.out.println("bar");
;
If your Java method does not take an argument or use imports, like the run()
method above, you can use the JavaBatchRunnableFactory
class directly.
java -jar ./target/fuzzer-0.1-jar-with-dependencies.jar --grammar java.grammar --runnableFactory org.stoev.fuzzer.JavaBatchRunnableFactory
Because the Java compiler uses soft references internally, it tends to fill up available memory before beginning massive garbage collections which in turn cause the JVM to grind to a halt. To ensure a smoother running for your test, you may wish to use the following options:
java -XX:SoftRefLRUPolicyMSPerMB=1 -Xincgc -server -jar ...
Frizzante's JavaBatchCompiler
uses soft references to cache compiled methods in memory in order to avoid recompiling them every time. In order to avoid filling up memory, it is recommended that you use --range
to limit the number of distinct pieces of code that Frizzante will generate.
java -jar ./target/fuzzer-0.1-jar-with-dependencies.jar --range 10000
If your Java method must be passed arguments, subclass JavaBatchRunnableFactory
as is done for example in FoundationDBRunnableFactory.java
. You will need to override getHeaders()
and invoke()
.