Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Sunday, April 10, 2011

Very simple EventBus/PubSub implementation (Java)

While investigating and learning usage of CQRS parrtern I've found that there is no any simple event bus implementation for Java (exept this one, but it do not had sources).

So I've used idea of "Java Programming Tip: Building Your Own Event Bus" blog post, and made my own implementation.

It allows very-very simple and not optimized way of publishing/subscribing on events with consentation on simplicity.

Friday, August 28, 2009

Google Apps Engine: все еще слишком экспериментальный

Недавно пришлось таки отказаться от GAE по ряду  причин. Все-таки не стоило насколько легко игнорировать все предупреждения о том, что он имеет пока только экспериментальную поддержку.

Основные причины отказа:

  1. Достаточно низкие лимиты на процессорное время, при этом довольно низкая производительность (то что на локальной машине выполняется 1секунду, в “реальном” окружении может выходить за пределы лимита в 30 секунд)
  2. Наличие серьезных открытых issues, которые фактически сильно усложняют разработку
    1. Невозможно очистить хранилище (только кодом, но если классы не совместимы, то полная очистка невозможно вообще)
    2. Невозможно удалить приложение (что в совокупности с предидущим пунктом и наличием лимита в 10 приложений дает серьёзную “ложку дёгтя”)
    3. Ошибки при построении индексов и невозможность управлять ими при ошибках (например, если индекс находится в состоянии построения, и возникла ошибка, только работники Гугл могут помочь очистить индексы)
  3. Позднее оповещение об неподдерживаемых библиотеках (фактически можно довольно долго разрабатывать локально, задеплоить, и только при какой-то операции получить сообщение что какая-то библиотека юзает “запрещенный” класс, что заставляет фактически полностью переписывать некоторые блоки). Мне кажется, что зная список разрешенных JRE классов, могли бы написать небольшой анализатор, который скажет есть ли использование плохих классов).
  4. Отсутствие  агрегационных функций при работе с хранилищем. Конечно, это не проблема для некоторых проектов, но в том, над которым я работал, анализ данных был чуть ли не основной задачей. И если у Амазона есть их Amazon Elastic MapReduce, то у Google нет адекватной альтернативы.

Сейчас прорабатываем вариант перехода на Amazon Web Services. Пока выглядит очень и очень привлекательно.



P.S.: Небольшая анти-статья про Amazon SimpleDB и чуток GAE - тут

Friday, August 29, 2008

GWT 1.5 Released

Наконец-то произошел давно ожидаемый релиз GWT версии 1.5. Хотя релиз-кандидаты и так показывали довольно стабильную работу и обладали довольно большим списком нововведений, но официальный релиз позволяет использовать его в реальных проектах.

 

Итак, позволю себе сделать вольный перевод списка того, что изменилось с небольшими комментариями (оригинал):

Поддержка Java 1.5 и расширенная эмуляция JRE

  1. Теперь можно спокойно использовать “генерики”. И не только для более комфортной работы на клиентской стороне, но и для реализации более “тесного” RPC между клиентом и сервером (теперь можно возвращать клиенту List<MyClass> не беспокоясь о @gwt.typeArgs)
  2. Синтаксический сахарок: for-each loops, autoboxing, static import, enum
  3. Переработана архитектура подсистем (RPC, image bundles, benchmarking, интернационализация). Так же стало допустимо использование “левых” аннотаций, что позволяет повторное использование кода для других систем.
  4. Добавлена реализация разных вспомогательных классов, к которым так привыкли ява-девелоперы (StringBuilder, TreeMap, LinkedHashMap)
  5. Теперь Assertion-ы можно отключить (фактически появилась возможность делать более “релиз” версию).

 

Производительность и связь с JavaScript

  1. Компилятор более тщательно проводит “инлайнинг” функций – т.е. вместо вызова функции, код функции вставляется прямо в то место, откуда был бы вызов.
  2. Дерево переработано полностью. В результате на ИЕ прирост скорости работы от 5 до 10 раз.
  3. Добавлены типы JavaScript overlay. Это позволяет интегрировать уже написанные JavaScript библиотеки без дополнительных издержек. А так же более “прямую” конвертацию JSON данные в GWT объекты.
  4. Система “линкеров” позволяет генерировать различные варианты окончательных сборок для разных контейнеров, которые могут выполнять JavaScript (привет Google Gadgets, Filefox расширения, Greasemonkey скрипты, Gears но и … Flex и Android)

Красивые виджеты, лучшая поддержка DOM, доступность, и bi-di.

  1. Переделали демку
  2. Добавили дефолтные “темы” (раньше были только в примерах)
  3. Добавили функционал для обеспечения “доступности” (WAI-ARIA) и вывод “наоборот” (для арабских локалей например)
  4. Новый DOM package покрывает полностью спецификацию W3C – т.е. можно использовать “нативные” элементы вместо виджетов для простоты реализации.

 

…и многое другое :)

 

В общем, GWT продолжает довольно активно развивается, и этот релиз – ещё один сильный и уверенный шаг вперёд.

Monday, December 3, 2007

Google's Andriod: Threat to Java?

Прочитал вот интереснейшую статейку про то, что новая ОС для мобильных устройств от Google может довольно сильно пошатнуть позиции Java. Доводы, конечно, пока очень шаткие, но аргументы вполне разумные.

Что же за зверь такой, этот Андроид? Конечно первая OpenSource ОС для мобильных телефонов - звучит гордо, но настолько ли это хорошо для софтверного бизнеса в целом? Время покажет.

Monday, June 25, 2007

Interesting code puzzles

Периодически встречаю разные интересные приколы интересного неоднозначного кода. Интересные они не только тем, что однозначно не скажешь результат кода, а ещё и тем, что можно случайно и в реальной жизни нарваться на грабли от таких приколов.

Вот и решил собрать небольшую подборочку таких приколов. Если ещё найду, буду дополнять.

Начнём с простеньких. Возможно кому-то они покажутся слишком, но меня удивили.

Какой метод будет вызван?

(C#, на Java вроде то же самое)

using System;

namespace ConsoleApplication2
{
class Program
{
private static void A(Object o)
{
Console.WriteLine("Object");
}
private static void A(String s)
{
Console.WriteLine("String");
}
static void Main(string[] args)
{
A(null);
}
}
}


Ответ: "String". Потому, что String наследуется от Object, а null можно привести к String. т.е. полностью однозначный вызов метода с параметром наиболее "высокого" в иерархии классов параметра.


Пока не нашёл точной спецификации в MSDN описания этого поведения. Подредактирую этот пост как найду.



Инкриментинг


(C#, на Java же самое)

using System;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
int tricky = 0;
for (int i = 0; i < 3; i++)
tricky += tricky++;
Console.WriteLine(tricky);
}
}
}


Ответ: 0. Потому, что каждый раз к 0 будет прибавляться 0, с постинкримент будет происходить до изменения переменной.


Кстати, интересно то, что если в C/C++ выражение i=i++ является неопределённым (т.е. выдаёт на разных компайлерах разные результаты - см п 3.8), то в C#/Java всё довольно чётко определенно.



Массив


(C#, на Java же самое)

using System;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
int[] arr = new int[2] { 0, 1} ;
int i = 0;
try
{
arr[i] = i = 2;
Console.WriteLine("{" + arr[0] + "," + arr[1] + "} i=" + i);
} catch (IndexOutOfRangeException)
{
Console.WriteLine("Out of bounds!");
}
}
}
}

Ответ:



{2,1} 2

При компиляции операция "=" обрабатывается слева на право - т.е. сначала занесёться в стек текущее значение i, потом произойдёт изменение i и уже после этого будет непосредственное изменение массива.


Равенства


Думаю всем известно, что в Java и в C# есть разные способы сравнивать. Вот интересный и простой тест (хотя в Java есть только два способа из-за невозможности перегрузки операторов). Первая часть скорее проверка базовых знаний, а вторая уже немного интересней.

using System;
namespace ConsoleApplication
{
class Program
{
public static void Check(object a, object b)
{
Console.Write(a == b ? "same" : "not same");
Console.Write(a.Equals(b) ? " and equals" : " not equals");
Console.Write(object.ReferenceEquals(a, b) ? " and ref equals" : " not ref equals");
Console.WriteLine();
}

static void Main(string[] args)
{
int inta = 1000;
int intb = 1000;
Check(inta, intb);

String stringA = "test";
String stringB = "test";
Check(stringA, stringB);

}
}
}

Ответ:


not same and equals not ref equals
same and equals and ref equals
Для int'ов - ссылки разные из-за того, что произошел boxing, а для строк ссылки одинаковые из-за того, что компилятор одинаковые строки собирает, и при инициализации ссылки на строку передаёт один и тот же объект.


В принципе если посмотреть на сборку, которая получается в результате, то объяснение ответа второго вывода довольно простое.


Инициализация


Этот пазл имхо уже довольно сложный. И снова таки как и в C# так и в Java поведение его одинаково.


Вот собственно код:

using System;
using System.Threading;

namespace ConsoleApplication
{
class Program
{
public class TestingClass
{
public static bool inited = false;
static TestingClass()
{
Thread thr = new Thread(new ThreadStart(delegate { inited = true; }));
thr.Start();
thr.Join();
}
}


static void Main(string[] args)
{
Console.WriteLine("Lets check if TestingClass was inited:");
Console.WriteLine(TestingClass.inited);
Console.WriteLine("Done.");
}
}
}


Ответ:


Программа войдёт в dead-lock: во время инициализации класса будет вызван статический конструктор класса. Внутри которого создаёться поток, в котором выполняется код клоужера, который обращаеться к статическому ствойству класса. Но так, как класс ещё не прошёл инициализацию, а доступ происходит из другого потока, то этот поток будет ждать пока завершиться инициализация, т.е. завершится выполнятся статический конструктор. А конструктор-то ждёт завершение потока. Т.е. получаем классический dead-lock.



PS. Ах да, некоторые идеи а так же Java варианты некоторых пазлов можно посмотреть тут

Monday, June 18, 2007

GWT Generators (GWT-Exporter as example)

Ray Cromwell на своём блоге закончил цикл статей о том, как использовать генераторы в GWT.

Идея отличная: зачем делать что-то в run-time, если можно сделать то же самое в compile-time? Если можно просто при компиляции сгенерить нужный код?

Мало того, идея совсем не новая - насколько я знаю. есть много "мета-языков", которые делают то же самое.

Но в GWT это интегрировано в сам компилятор: к примеру, для классов, помеченных, как имплементирующие IsSerializable создаются автоматом "стабы", в которых и происходит сериализация/десиализация. В .NET происходит практически то же самое, но в рантайме - создаётся временная сборка, которая сериализует необходимый класс.

Вроде бы то же самое, но есть одно "но" - повторить подобную процедуру достаточно сложно. В GWT с помощью генераторов можно это сделать намного легче.

Как? Вот статьи Рея и открывают "мистику" генераторов:

GWT Demystified

GWT Demystified: Generators, Part 1

GWT Demystified: Generators Part Deux

и финальная GWT Demystified: Generators Part 3, Meet the Oracle

Так же доступны через svn исходники его проекта GWT-Exporter, позволяющего помечая интерфейсом Exportable генерировать "стабы" для вызова GWT-объектов из JavaScript (без него надо было бы создавать специальные методы для "бриджинга" вызовов к GWT-объектам, так как методы последнего могут быть изменены при компиляции)

В любом случае, очень интересная статейка.