Не так давно мне в руки попал портальчик http://codingbat.com (спасибо Виталик!)/ Мне очень понравилось ихняя задумка, и я захотел ее себе на свой тренинговый портал. Мы используем Moodle и все решенные учащимся (на Java тренинге) задания отправляются либо файлом, либо линком на ревизию в репозитории. Не так давно мы пришли к выводу, что заданий покаждому модулю должно быть много, они должны быть мелкими. И тут в руки попадает http://codingbat.com - я понимаю что это именно то, что мне нужно. Мне нужно точно такое же окошко в Moodle, и кнопка отправить, в ответ на нажатие которой я получу либо pass либо сообщение о fail. Задания можно выстраивать в очередь а о результатах рипортить тренеру (средствами Moodle).
Чтоб сделать это мне требуется ответить на вопрос - как копилировать исходный код java в рантайме. Ответ не заставил себя ждать - слава Google.
Может кому пригодится...
Чтоб сделать это мне требуется ответить на вопрос - как копилировать исходный код java в рантайме. Ответ не заставил себя ждать - слава Google.
- Janino - упрощенный, но очень шустрый компилятор.
- The Java 6.0 Compiler API - родной компилятор,
public class CompilerTest {
private JavaCompiler compiler = new JavaCompiler();
@Test
public void shouldRunMethodWithoutParameters() {
JavaCompiler compiler = new JavaCompiler();
JavaMethod method = compiler.getMethod(
"public String qwe() { \n" +
" return \"Hello world!\";\n" +
"}");
String result = (String)method.run();
assertEquals("Hello world!", result);
}
@Test
public void shouldRunMethodWithTwoStrings() {
JavaMethod method = compiler.getMethod(
"public String qwe(String qwe, String asd) { \n" +
" return \"The first is '\" + qwe + \"', the second is '\" + asd + \"'\";\n" +
"}");
String result = (String)method.run("qwe_string", "asd_string");
assertEquals("The first is 'qwe_string', the second is 'asd_string'", result);
}
@Test
public void shouldRunMethodWithTwoInts() {
JavaMethod method = compiler.getMethod(
"public String qwe(int qwe, int asd) { \n" +
" return \"The first is '\" + qwe + \"', the second is '\" + asd + \"'\";\n" +
"}");
assertEquals("The first is '1', the second is '2'", (String)method.run(1, 2));
assertEquals("The first is '2', the second is '3'", (String)method.run(2, 3));
}
@Test
public void shouldCompileClass() throws Exception {
JavaClass clazz = compiler.newClass(
"public class SomeDynaClass {\n" +
" public String qwe(int qwe, int asd) { \n" +
" return \"The first is '\" + qwe + \"', the second is '\" + asd + \"'\";\n" +
" }\n" +
" public String asd(String zxc) { \n" +
" return \"The third is '\" + zxc + \"'\";\n" +
" }\n" +
"}");
Class realClass = clazz.getRealClass();
Object object = clazz.newInstance();
String result = (String) realClass.getMethod("qwe", int.class, int.class).invoke(object, 1, 2);
assertEquals("The first is '1', the second is '2'", result);
result = (String) realClass.getMethod("asd", String.class).invoke(object, "string");
assertEquals("The third is 'string'", result);
}
@Test
public void shouldCompileClassWithoutDefaultConstructor() throws Exception {
JavaClass clazz = compiler.newClass(
"public class SomeDynaClass {\n" +
" private int i;\n" +
" public SomeDynaClass(int i) {\n" +
" this.i = i;\n" +
" }\n" +
" public String qwe(int qwe, int asd) { \n" +
" return \"The first is '\" + (qwe+i) + \"', the second is '\" + (asd+i) + \"'\";\n" +
" }\n" +
" public String asd(String zxc) { \n" +
" return \"The third is '\" + zxc + i + \"'\";\n" +
" }\n" +
"}");
Class realClass = clazz.getRealClass();
Object object = clazz.newInstance(10);
String result = (String) realClass.getMethod("qwe", int.class, int.class).invoke(object, 1, 2);
assertEquals("The first is '11', the second is '12'", result);
result = (String) realClass.getMethod("asd", String.class).invoke(object, "string");
assertEquals("The third is 'string10'", result);
}
}
Код немного сыроват, но все же тесты работают и пока меня это устраивает. Скачать исходники можно тут. Может кому пригодится...

Комментариев нет:
Отправить комментарий