Skip to main content

module lang::java::Runner

rascal-Not specified

Simple Rascal API for executing JVM bytecode, as static main method or as Junit4 test class.

Usage

import lang::java::Runner;

Dependencies

import IO;
import lang::java::Compiler;
import String;
import util::FileSystem;
import util::Reflective;
import util::UUID;
import Location;

Benefits

  • Run the static main method of any .class file in JVM bytecode format, stored anywhere reachable through a loc and using any library reachable through a loc, to JVM bytecode using the current JVM.
  • Run any Junit4 test class in JVM bytecode format, stored anywhere reachable through a loc and using any library also reachable through a loc

Pitfalls

  • If you are looking for Java analysis and transformation support in Rascal please go find the java-air package. The current module only provides a Java to bytecode compilation API.

function runJavaMain

Execute the static main function of a (compiled) java class

void runJavaMain(str qualifiedName, list[str] args, list[loc] classpath=[])

Benefits

  • This function can use class files from any support loc scheme

Pitfalls

  • The current Rascal runtime/interpreter classloaders, including vallang, are always used before any other class.

data JUnitVersion

data JUnitVersion  
= junit4()
;

function runJUnitTestClass

list[Message] runJUnitTestClass(str qualifiedName, list[loc] classpath = [], JUnitVersion version = junit4())

Benefits

  • This function can use class files from any support loc scheme
  • Classes are loaded from the classpath parameter with any loc scheme that supports class loading.

Pitfalls

  • The current Rascal runtime/interpreter classloaders, including vallang, are always used before any other class.

function getJUnitClassPath

Locate the right classpath for JUnit

loc getJUnitClassPath(JUnitVersion version=junit4())

Benefits

  • Yhis comes in handy for the compiler libs parameter, if the test still needs to be compiled from source.

Tests

test factorialMainTest

test bool factorialMainTest() {
root = uuid()[scheme="memory"];
target = root + "target";

source = |project://rascal/test/org/rascalmpl/benchmark/Factorial/Factorial.java|;
qname = "org.rascalmpl.benchmark.Factorial.Factorial";

messages = compileJavaSourceFile(
source,
target,
[|project://rascal/test/|]);

runJavaMain(
qname,
[],
classpath=[target, resolvedCurrentRascalJar()]
);

return true;
}

test junitTestRunTest

test bool junitTestRunTest() {
root = uuid()[scheme="memory"];
target = root + "target";
sources = root + "sources";
sourceFile = sources + "TheTestClass.java";

code = "import org.junit.Test;
'import static org.junit.Assert.assertTrue;
'public class TheTestClass {
' @Test
' public void aTestExample() {
' assertTrue(true);
' }
'}";

writeFile(sourceFile, code);

messages = compileJavaSourceFile(sourceFile, target, [sources], libs=[resolvedCurrentRascalJar(), getJUnitClassPath()]);

assert messages == [] : "example should compile without errors: <messages>";

qname = replaceAll(relativize([sources], sourceFile)[extension=""].path[1..], "/", ".");

results = runJUnitTestClass(qname, classpath=[target, getJUnitClassPath()]);

assert [info("aTestExample(TheTestClass) started", loc _), info("aTestExample(TheTestClass) finished", _)] := results;

code = "import org.junit.Test;
'import static org.junit.Assert.assertTrue;
'public class TheTestClass {
' @Test
' public void aTestExample() {
' assertTrue(false);
' }
'}";

writeFile(sourceFile, code);

messages = compileJavaSourceFile(sourceFile, target, [sources], libs=[resolvedCurrentRascalJar(), getJUnitClassPath()]);

assert messages == [] : "example should compile without errors: <messages>";

results = runJUnitTestClass(qname, classpath=[target, getJUnitClassPath()]);

assert [
info("aTestExample(TheTestClass) started", _),
error("aTestExample(TheTestClass) failed", _),
info("aTestExample(TheTestClass) finished", _)] := results;

return true;
}