среда, 13 июля 2011 г.

How to build Swing forms with IntelliJ UI Designer (javac2) with Maven



<project> 
...
<packaging>jar</packaging>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>ideauidesigner-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>javac2</goal>
</goals>
</execution>
</executions>
<configuration>
<fork>true</fork>
<debug>true</debug>
<failOnError>true</failOnError>
...
</configuration>
</plugin>
</plugins>
</build>
</project>

Hibernate 3.6.5 Final Configuration/Session Factory Serialization

Deserialization of session factory drops exception cause it can't be deserialized without name, because the there are only name/uuid stored. Thus Session Factory can't be serialized in common sense. Result of serialization is reference to JVM instance or JNDI resource.

readResolve method in SessionFactoryImpl. Set hibernate.session_factory_name in properties.

четверг, 17 июня 2010 г.

Особенности коллекций в Javolution

Предположим, что вы впечатлены тем, что в Javolution можно делать так:
for (FastList.Node<Concert> n = head(), end = tail(); (n = n.getNext()) != end;) {
Concert concert = n.getValue();

Colored with dumpz.org


В shared() режиме это замечательно. Кажеться, вы экономите на итераторах?

Недавно обнаружилась одна интересная особенность этих хранилищ, по сравнению с чем Concurrent классы из java.util.concurrent версии 1.6 выглядят куда более привлекательными. Как известно, javolution активно пытается переиспользовать удаляемые ноды. Для этого оно помещает их в конец списка за tail (в хэшах аналогично) и соответственно прибивает старые указатели. Поэтому если вы работаете с FastList, FastMap или еще c чем в 2-ух тредах - один читает, другой удаляет, - ваш читающий поток редко будет дочитывать до конца. В основном он будет терять позицию, из-за того что нода на которой он висит, была удалено параллельно пишушим потоком. А если вы не проверяете node.getValue на null будет еще и падать с NullPointerException. Вот рабочий пример (забавно, тут даже нет никаких локов в рутово треде):
final FastList<Integer> list = new FastList<Integer>();

for (int i = 0; i < 104; i++)
list.add(i);

int count = 0;
for (FastList.Node<Integer> n = list.head(), end = list.tail(); (n = n.getNext()) != end;) {
int x = n.getValue();

if (count > 100) {
final FastList.Node<Integer> z = n;
Runnable remover = new Runnable() {
@Override
public void run() {
list.remove(z.getValue());
}
};

Thread removerThread = new Thread(remover);
removerThread.start();

while (removerThread.getState() != Thread.State.TERMINATED) try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

count ++;
}

Colored with dumpz.org


Соответственно, с ConcurrentLinkedQueue такого не происходит. Вы почти спокойно добегаете по списку по ново\старой версии. В частности, если вы начали читать итератор, и другой тред удалил все последующие элементы, вы их все равно увидите. И в большинстве случаев такое поведение оправдано.

понедельник, 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, которое будет содержать нечто вроде: в вашем методе ... с такой-то сигнатурой ... на вершине стэка ожидалось интовое значение. Выяснить место ошибки автоматически - не получится.