About :: Projects :: Articles :: JBlog.getInstance()

JBlog.getInstance()

Поиск:


Разное: Архивы по категориям: Архивы по месяцам:

Работа с датами @ 03.03.2008 19:12

Категории: Links

Очень веселая ошибка в последней бете MS SQLServer 2008. Из-за неправильной работы с датой, сервер отказывался стартовать 29-ого февраля.

Microsoft'у довольно сильно повезло. Если бы они не успели к настоящему моменту выпустить бету, то вероятность того, что следующем вискосном 2012-ом, куча production-сервером грохнулась бы была была бы далеко не нулевой.

Linux for desktop @ 28.02.2008 16:40

Категории: linux

Уже лет 10 прошло с тех пор, как я активно пользуюсь компьютером. Всё это время в качество ОС использовалась Windows (Windows 95 -> Windows 98 -> Windows XP -> Windows Vista). С линуксом, конечно, сталкиваться приходилось. Делались робкие попытки использовать его в качестве desktop-системы, много раз приходилось иметь дело с Linux/FreeBSD серверами, но полноценным пользователем я не был. Итак, от любопытства и избытка времени я решил провести эксперимент — пользоваться две недели исключительно Линуксом. Эксперимент, собственно, начался ещё вчера (однако, так как я не успел перенести всё рабочее окружение, пост этот пишется ещё из Windows Live Writer). В качестве дистрибутива был выбран OpenSUSE 10.3. Вообще, все рекомендуют Ubuntu, yо из-за проблем с драйверами видеокарточки (попытка установки ATIшных драйверов вылилась в полную потерю работоспособности X-сервера). Итак, после устаноки OpenSUSE образовался следующий статус-кво:

  • Загружается и работает KDE
  • Работает WiFi, следовательно работает internet
  • Разрешение экрана — 1024х768 (вместо 1280х1024). Драйвера видео-карты не установлены
  • Звук работает, но не проигрываются mp3'шки. Видео-плеер опять же из-за отсутсвия кодеков не может проиграть не один фильм
  • Непонятно, откуда устанавливать программы. В менеджере пакетов доступен только один репозиторий — CD, с которого ставилась система. Все пакеты из этого репозитория, очевидно, уже поставлены
  • KDE кажется субъективно убогим. Шрифты — уродливые уже объективно
  • Отсутсвие файлового менеджера, хоть отдалённо напоминающего Total Commander на данном этапе страшно раздражает
  • Отсутсвует русская раскладка
Собственно, все эти проблемы решались вчера:
  • Для того, чтобы в менеджере пакетов появился осмысленный надор програм, надо было запустить YaST (аналог control panel из windows), кликнуть соответсвующем разделе на Community Repositories и отметить там галочкой Main OSS (свободные программы), Main Non-OSS (бесплатные несвободные программы), ATI (атишные драйвера), Packman (кодеки).
  • Проблема с разрешением экрана и драйверами для видео-карточки решилась без всяких проблем. Надо было сделать всё по этой инструкции, по дороге забив на warning'и от менеджера пакетов.
  • Проблема с неудобным KDE решилась установкой на вид более приятного Gnome'а. Шрифты остались всё такими же отвратительными.
  • В качестве файлового менеджера был выбран Krusader. До total commander'а ему, конечно, далеко. Но на первое время сойдёт.
  • С проигрыванием mp3 и видео было сложнее. Для начала, были поставлены все пакеты содержащии в названии xine и mp3 и codec. Потом выяснилось, что данным действием было поставлено два audio/video-framework'а: GStreamer и Xine — оба с поддержкой mp3 и и богатого набора видео-кодеков. Аудио плееры (Amarok, Totem, Koffeine) поддерживают оба этих framework'а (какой из них используется выбирается в настройках). Для проигрывания mp3 был выбран Amarok+xine. Amarok по субъективному удобству. Xine из-за того, что gstreamer по непонятным причинам отказался проигрывать mp3. Для видео был выбран Koffeine+Xine (по аналогичным причинам).
  • Русская раскладка была с легкость настроена через Display Settings в YaST. После выбора варианта раскладки winkeys, установки галочки Shift+Numpad windows behavior и настройки переключения раскладки на Ctrl+Shift в gnome'овском настройщике клавиатуры, всё стало работать в точности, как в windows

Так же было сделано несколько мелких улучшений:

  • На нижнюю панель были добавлены Volume Control и Language Indicator.
  • В настройщике клавиатуры был добавлен глобальный shortcut winkey+D, который сворачивает все окна.
  • В firefox был перенесен windows'овский профиль.
  • Написан скрипт, монтирующие windows'овские расшареные папки со второго домашнего компьютера: mount -f cifs -o username=user,password=***,ip=computer //computer/folder /net/folder. Чтобы данная команда заработала, были установлены все пакеты, содержащие в названии samba.

В принципе, пользоваться компьютером уже можно. Но до нормального состояния ещё далеко. Осталось настроить следующее:

  • Автозапуск KNetworkManager'а при старте gnome'а. Эта программа висит в трее и показывает доступные wifi сети, а так же состояние подключения
  • Решение проблемы двухпанельного файлового менеджера. Вариантов масса: настройка Krusader до приемлемого состояния, переход на midnight commander либо вообще отказ от файлового медежера.
  • Добавление в контекстное меню на mp3'шках пункта "Enqueue to Amarok"
  • Выбор и настройка терминала. Пока это konsole, но она даже менее удобна чем, windows'овская console2.
  • Выбор утилиты мониторинга системы (процессы, память, использования CPU и т.д.). Консольные top, ps и kill говно.
  • Настройка интернета через телефон. А так же бэкапа телефонных контактов.
  • Выбор программы для работы с фотографиями (resize, crop, red eyes)
  • Установка thunderbird и перенос профайла из windows.
  • Установка более приятной темы для gnome
  • Настройка шрифтов
  • Настройка окружения для работы (Java, IDEA, Ant и т.д.)

 

 

    Annotation Processor @ 25.12.2007 15:45

    Категории: Opinion

    В Jdk 1.6 появилась новая функциональность — annotation processing. В общих словах работает данная функциональность так:

    • Вы пишете класс, реализующий интерфейс Processor
    • Вы передаете javac'у в опциях имя вашего класса
    • Javac строит в памяти модель кода
    • Ваш класс работает с модолью кода через уродский API.
    • Javac генерирует byte-code

    Во-первых, полезность данной функциональности очень спорная (API действительно страшно неудобный). А, во-вторых, в ней есть довольно критический баг

    Разработчикам заняться нечем, наверное.

    Java Events @ 08.12.2007 20:36

    Категории: Solutions

    Многие программисты, сравнивая Java с C#, часто говорят о том, что в Java не хватает функциональности, для работы с событиями. В C# такая функциональность есть. Однако, если немного подумать, аналогичную фичу можно реализовать и в Java довольно легко.

    1. Как это может выглядеть

    interface SomethingListener {
        public void doSmth(String a, String b);
    }
    public class EventsDemo    
        private static EventMulticaster<SomethingListener> handlers =
                EventMulticaster.create(SomethingListener.class);
        private static void addHandlers() {
            handlers.add(new SomethingListener() {
                public void doSmth(String a, String b) {
                    System.out.println(a + ", " + b);
                }
            });
            handlers.add(new SomethingListener() {
                public void doSmth(String a, String b) {
                    System.out.println(b + ", " + a);
                }
            });
        }
        public static void main(String[] args) {
            addHandlers();
            handlerSet.getMulticaster().doSmth("1", "2");
        }
    }

    Посмотрим на этот кусок кода. Если запустить метод main класса EventsDemo на консоль будет выведено следующее:

    1, 2
    2, 1
    

    Основная функциональность заключена в члене класса EventsDemo handlers (экземпляр класса EventMulticaster). При создании экземпляра factory-методу EventMulticaster'а create передаётся интерфейс SomethingListener. Далее вызовами метода add к handlers (в методе addHandlers) добаляются реализации интерфейса SomethingListener. Строка handlerSet.getMulticaster().doSmth("1", "2") вызывает метод doSmth у всех ранее добавленных методом add реализаций SomethingListener.

    2. Как это реализовать

    Реализация класса EventMulticaster — хорошая задача на знание стандартной библиотеки Java. Привожу свой вариант реализации

    public class EventMulticaster<T> {
        private final Set<T> set = new LinkedHashSet<T>();
        private final T multicaster;
    
        private EventMulticaster(final Class<T> iface) {
            if (!iface.isInterface()) {
                throw new IllegalArgumentException(iface + " is not an interface");
            }
    
            multicaster = (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class<?>[]{iface},
                    new InvocationHandler() {
                        public Object invoke(Object proxy, Method method, Object[] args) {
                            Set<T> list = getSet();
                            for (T listener : list) {
                                try {
                                    method.invoke(listener, args);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                            return null;
                        }
                    });
        }
    
        private synchronized HashSet<T> getSet() {
            return new HashSet<T>(set);
        }
    
        public static <T> EventMulticaster<T> create(Class<T> iface) {
            return new EventMulticaster<T>(iface);
        }
    
        public synchronized void add(T listener) {
            set.add(listener);
        }
        public T getMulticaster() {
            return multicaster;
        }

    Если знать, как работает класс java.reflect.Proxy (прочитать про него можно тут) реализация в целом вызывать вопросов не должна. Поясню отдельные моменты:

    • Почему нельзя итерировать по set напрямую, а вместо этого используется метод getSet(), копирующий коллекцию?
      Это нужно для того, чтобы избежать ConcurrentModificationException. Работа с multicaster'ом и вызом метода add могут происходить из разных потоков
    • Почему конструктор объявлен, как private, а для создания нового экземпляра EventMulticaster используется factory-метод create?
      Для сокращения количества кода. Если не сделать метод create, то создание нового экземпляра EventMulticaster будет выглядеть как new EventMulticaster(SomethingListener.class). Согласитесь, EventMulticaster.create(SomethingListener.class) выглядет приятнее

    3. Дополнения

    В класс EventMulticaster, скорее всего, стоит добавить методы remove, clear и подобные. Так же использовать e.printStackTrace() для обработки ошибок — не лучшая идея (хотя пробрасывать исключение дальше — тоже нельзя). Тут надо либо записывать сообщение об ошибке в общий лог, или придумать какое-нибудь более гибкое решение.

      © Vladimir Klimontovich; modified: Sunday, 20-Jul-2008 02:20:54 PDT