понедельник, 15 февраля 2010 г.

Почему генерики Java - отстой

class Data< T > {
protected T[] array;

public Data(T x, T y) {
array = (T[]) new Object[2];
array[0] = x;
array[1] = y;
}

public T[] get() {
return array;
}

}

Попробуйте создать Data и передать туда List. Данный код скомпилируется, - даже не сомневайтесь. Вопрос только в том, что вы будете делать с методом get() - вы не сможете вытащить ничего через этот метод! Вы будете постоянно получать исключение об инвалидном касте.

четверг, 11 февраля 2010 г.

Eclipse JDT Core и L2J Server

Кстати говоря, в опен сорцном сервере Lineage 2, для компиляции части скриптов, используется именно eclipse jdt (кроме питона и bsh). Там реализован wrapper к javax.scripting. Хотя этот враппер в исходниках не идет - disasm welcome, тем кому интересно, все просто и здорово сделано. Кроме того, полезно посмотреть, что происходит с этим компилятором дальше (см L2ScriptManager).

В l2j server сервере у них на Java написаны в основном скрипты AI, и некоторые инстансы и квесты, в осталтом, везде - python.

Еще с недавних пор они используют trove, кому интересно...

Компиляция Java и скрипты

Выяснилось, что компилятор javassist не умеет ооочень многого. Например, он не может резолвить вызываемый метод, в случае, когда для этого требуется неявное приведение типов аргументов. Это говорит о том, что для создания полно-функциональный скриптов этот компилятор мало подходит. Но для интеграции в сторонние библиотеки, которым требуется такой функционал - манипуляция в runtime кодом, оптимизация рефлексии и прочие приятные мелочи, эта штука замечательно подходить. Javassist - маленький, простой, удобный программный интерфейс, - поэтому и ограниченный.

Следующий шаг, смотрим Eclipse JDT Core. Штука намного более навороченная и продвинутая. Очень много полезных вещей содержит для реализации скриптовых движков. Есть автокомплит, поиск, инкрементная компиляция и еще миллион приятных мелочей (Компилятор знает что такое фор-ыч, подробный резолвинг ошибок синтаксиса, АСТ-овое дерево имеет АПИ для реврайтинга кода - ура, товарищи).

понедельник, 8 февраля 2010 г.

Интересный момент компиляции кода с помощью javassist

Если вы собираете класс в runtime с помощью javassist, вам наверняка будет интересно узнать, в каком месте кода у вас ошибка (например, если вы даете ей на вход тело метода).
В работе с javassist обнаружилось несколько интересных моментов:
1) компилятор не знает, что такое for (each).
2) парсер не проверяет код (только явные ошибки).
3) верификатор jvm кода не сообщает положения ошибки.

Таким образом, вы вправе передать компилятору на вход вот такое: { call() = 1; }... и он это прожует. То есть, вы не получите на выходе SyntaxError исключение. Вместо этого, вы получите исключение верификатора jvm VerifyError, которое будет содержать нечто вроде: в вашем методе ... с такой-то сигнатурой ... на вершине стэка ожидалось интовое значение. Выяснить место ошибки автоматически - не получится.