Monday, December 10, 2007

Microsoft Volta - Microsoft's answer to GWT?

Сегодня наткнулся на довольно таки интересный проект от Microsoft - Volta. В описании много слов, но основное "The compiler creates cross-browser JavaScript for the client tier, web services for the server tier, and communication, serialization, synchronization, security, and other boilerplate code to tie the tiers together". Ничего не напоминает? Ах да, это же концепция старого доброго GWT.

После более детального ознакомления с документацией я всё больше и больше находил схожие концепции GWT и Volta.

Итак, Microsoft таки решилась дать ответ Google. Я пока не сильно вникал в подробности реализации и кодинга, но не смотря на схожесть концепции, различия таки есть. И довольно существенные - Volta имеет более сильную привязку к серверной составляющей, в то время, как код, генерируемый GWT может быть запущен с любым бэк-ендом (Java/PHP/ASP.NET/...) или вообще без сервера.

Что-ж. Ответ есть. Значит будем смотреть-пробовать. Время, как всегда, рассудит.



UPDATE: Посмтрел на самое типа простое демо-приложение Quickstart (ВНИМАНИЕ: Читайте UPDATE2 до открытия ссылки). С помощью HTTP Explorer'а отследил то, какие запросы идут на сервер и какие ответы и ужаснулся. Нет, это совсем не смешно. Вот что получислоь: трейс запроса. Если для загрузки такого маленького приложения пришлось сделать 133 запроса и получить около 2.2мб данных, то такой фреймворк требует ещё очень большой доработки. Бета-версия моего посиковика на GWT (lab.look.org.ua) занимает около 140кб в сумме (с картинками и стилями) и к серверу отсылается аж 6 запросов (или 16 с картинками и стилями). И это на GWT 1.3 (в GWT 1.4, как говорят, уменьшился генерируемый код на 15-20%). Итак, если Volta не будет оптимизирована, то чтоб использовать её надо будет очень хорошие сервера, хорошие каналы и хорошие клиентские машины. В то время, как GWT проводит довольно активную работу над оптимизацией размера кода, уменьшению количества запросов и т.д. Посмотрим, сможет ли Microsoft догнать GWT по этим параметрам, или будет как всегда выигрывать рекламой и маркетингом, а не эффективностью и производительностью?

UPDATE2: Многие знакомые жалуются, что у примеры прилоежний Volta вешают и крашат броузера (FF2, IE6, IE7). У меня FireFox хоть и на пару минут задумался, но потом отвис, хотя IE крашанулся полностью (проц АМД Х2 4600, 2гиг памяти). Так что предупреждение всем: если много открытых закладок и боитесь потерять, лучше или не открывайте их или открывайте в другом инстансе броузера или другим броузером.

UPDATE3: Вот ещё некоторые ссылки по теме:

Monday, December 3, 2007

Google's Andriod: Threat to Java?

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

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

Thursday, November 1, 2007

FAR 1.80: Unicode and OpenSource

Я как-то пропустил, что 26ого октября мой любимый файловый менеджер перешел на модифицированную лицензию BSD и стал OpenSource'овым. Кроме того, в новых версиях (1.80+) обещают поддержку unicode и некоторых новых фичей Windows Vista (к сожалению, поддержка UAC, кроме как через манифест не будет добавленна).

Так что сбрасывать со счетов старый добрый FAR пока не стоит!

Более детальная информация о новом FAR-е.

Monday, September 24, 2007

Google Documents: Presentations

Давно уже ходили слухи о том, что гуглдокс пополнится средством построение презентаций. Лично я уже думал для своих целей уже самому с использованием GWT написать что-то простенькое. Но Google обогнало меня в этом - и теперь на docs.google.com можно создавать презентации.

Да, сейчас они по функционалу не блещут - очень многих мелочей мне лично не хватает. А именно:

  1. Возможности создания своих "тем" (Например, логотип или общий текст на всех страничках) - есть возможность или переключатся между предустановленными темами или копировать уже созданный слайд.
  2. Возможности добавления разных геометрических фигур:  стрелочки, квадратики и т.д.

Но уже то, что есть довольно сильно впечатляет:

  1. Возможность онлайн-демонстрации презентации: после старта презентации можно кинуть урл презентации тем, кто хочет послушать вас и потом в мини-чате уже проводить. Естественно логично добавить бы поддержку звука (с помощью Flash). Возможно это будет в следующей версии
  2. Возможность экспорта презентации для off-line показа: после экспорта мы получаем zip архив, в котором есть все необходимые файлы для запуска презентации там, где нет интернета.

Что ж, резюмируя могу сказать: очень впечатляющее, но только начало. Google, так держать!

Wednesday, August 29, 2007

GWT: Out of beta!

Поздравляю всех, кто работает или заинтересован в GWT. Ибо сегодня "великий день" - с выходом релиза 1.4 GWT уже перестал иметь статус "Beta"!

Кому интересны подробности, советую почитать эту новость в оригинале.

Тут же напишу небольшую выдержку о том, что именно новенького в 1.4 кроме выхода из "бэты":

  • Код после компиляции стал меньше до 30% и скорость компиляции возросла на 20%-50%
  • Ускорен стартап приложения на клиенте (уменьшенно кол-во запросов)
  • Новые стандартные виджеты: RichTextArea, HorizontalSplitPanel, VerticalSplitPanel, SuggestBox, DisclosurePanel, PushButton, ToggleButton
  • Знаменитый "ImageBundle" - одним запросом можно получить много картинок (снова таки оптимизация)
  • Оптимизированы старые виджеты, добавлен новый ф-ционал (напр. Image)
  • Поддержка NumberFormat и DateTimeFormat для более простой локализации
  • Добавлена система бенчмаркинга юнит тестов GWT
  • Поддержка cross-stite трансферов модулей

... и многие другие фичи и очень много багфиксов.

Это действительно огромный шаг в развитии GWT.

Cледующий шаг - поддержка Java 1.5 синтаксиса. И, судя по отзывам разработчиков, это будет уже скоро.

Thursday, August 9, 2007

Google Mashup Editor: New Google project

Проглядывая море ньюсфидов я обнаружил ссылочку на довольно интересный проект: Google Marshup Editor.

Так, как доступ пока закрыт, не совсем ясно что это за зверь такой. Но уже есть галерея готовых "машапов", по которой можно примерно узнать как оно работает.

Довольно простой и интересный пример - TaskList (там же есть и исходники).

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

Интересно, что сам редактор использует GWT, при этом есть отличное обоснование, почему именно.

Tuesday, July 31, 2007

Multiple WAN: OpenWRT solution

Некоторое время назад провайдер, к которому я был подключен наверное больше 4 лет (IpNET) стал совсем уж слабо удовлетворять моим требованиям. По этому я решил сменить его. Но у ИпНета есть один довольно существенный плюс - его внутренняя сеть. И как-то не хотелось терять возможность качать со скоростью 5-6мб/сек. Да и покупка ноутбука с WiFi добавила ещё одну причину поменять рутер.

Недолго думая, я остановился на Asus WL500g Premium. Он сравнительно недорогой (~$90), но, судя по описанию, вполне мог обеспечить необходимый функционал - два WAN(MAN) подключения + WiFi.

Попробовал сначала прошивку от Олега, но мне она всё-таки немного не понравилась - получается просто комбинация стандартного интерфейса Asus и OpenWRT. Так что решил я сразу перейти на OpenWRT, но только с неплохим интерфейсом. По этому, остановил я свой выбор на X-WRT.

Как базовую документацию по созданию двух WAN-ов я взял статейку вики на самом сайте OpenWRT. Но там конфигурация намного сложней, чем мне нужна была - там полноценный load balancing, который мне не нужен был.

По этому, я модифицировал скрипты просто добавив в /usr/share/udhcpc/default.script при инициализации рутинга вызов некоторого кастом-скрипта:

                [ -n "$router" ] && {
#remove previous rule/table
ip route flush table $interface

for i in $router ; do
echo "adding router $i"
#route add default gw $i dev $interface
ip rule add from $ip table $interface
ip route add $TT dev $interface src $ip table $interface
ip route add 192.168.1.0/24 dev eth0.0 table $interface
ip route add default via $i table $interface
valid="$valid|$i"

done

#add the default route with equalize mpath
#echo "deleting and updating routes"
#while route del default >&- 2>&- ; do :; done
#P1=`ip route list table eth0.1 | grep via | cut -d" " -f 3`
#P2=`ip route list table eth0.2 | grep via | cut -d" " -f 3`
#ip route add default scope global \
# nexthop via $P1 dev eth0.1 weight 1 \
# nexthop via $P2 dev eth0.2 weight 1

#echo "deleting old routes"
#$(route -n | awk '/^0.0.0.0\W{9}('$valid')\W/ {next} /^0.0.0.0/ {print "route del -net "$1" gw "$2";"}')
#flush previous route
[ -f /etc/$interface.dhcp ] && . /etc/$interface.dhcp
ip route flush cache
}

После чего, создал файлик /etc/eth0.1.dhcp в котором прописал статические подсетки, которые я хотел рутить на WAN интерфейс eth0.1:

ip route add 172.16.0.0/18 dev $interface src $ip table $interface
ip route add 172.16.140.0/22 dev $interface src $ip table $interface
ip route add 82.193.96.0/20 dev $interface src $ip table $interface
ip route add 82.193.96.0/19 dev $interface src $ip table $interface
ip route add 82.193.96.232/29 dev $interface src $ip table $interface

 


Ну и так, как eth0.2 у меня нужен был как дефолтный, я прописал в /etc/firewall.user (может надо в другом файле, но я не знаю точно в каком) инициализацию дефолтного гейтвея:

......
# Default route
ip route add default scope global via 194.0.91.193

 


Таким образом я получил, что подсетки, указанные в eth0.1.dhcp идут через  eth0.1, а всё остальное - через eth0.2, что и требовалось.


Пользовательская оболочка довольно приятная. Хорошая фича - рисование графиков загружености в реальном времени.


Вот примеры рисования графиков:


 


Piccy.info - Free Image Hosting


Piccy.info - Free Image Hosting

Friday, July 27, 2007

Netcraft Web Servers Survey: who is GFE/GWS?

Попалась на глаза свеженькая статистика веб серверов. Судя по ней, сейчас 4.3 млн. сайтов работают под управлением серверов от Google.

Может я что-то не понимаю, но ведь Google не опубликовывали никаких своих веб-серверов (по типу Apache/IIS). Откуда столько сайтов?

При этом, сами сервисы Google работают на разных веб серверах - вот списочек.

Насколько я знаю, Google использует модифицированные Linux + Apache.

Не удивлюсь, если скоро появится опенсорсовый Google Web Server, который вполне может отобрать определенное количество аудитории от гигантов IIS/Apache.

Хотя, зачем это Google?

Wednesday, July 18, 2007

GWT: Tutorials

Не смог удержатся от того, чтоб не сделать кросс-пост отличной подборки туториалов. Оригинал можно посмотреть тут.

  1. Getting Started Guide - От самого GWT.
  2. Kickstarting Google Web Toolkit on the Client Side - Early "Hello, World!" tutorial with a second, animation example. This quick-start tutorial aims to translate some of the knowledge gained from my monkeying about with GWT into a useful text which will get other developers up and running quickly. To keep things nice and simple, we'll focus on only client-side matters.
  3. Google Web Toolkit Tutorial: The Break Down - Very short tutorial from early on. Demonstrates a simple rollover with GWT.
  4. Working with the Google Web Toolkit - Extensive tutorial with lots of screenshots that demonstrates everything from the basic getting started to some of the more interesting features, such as history support (i.e. the back button.). Article includes a Maven module for GWT.
  5. Introduction to the Google Web Toolkit - another extensive tutorial, this one from Oracle, so if you want to see how to GWT with JDeveloper, this one is for you.
  6. GWT Tutorial with Googlipse - yes, Googlipse is no more, but Cypal Studio has taken it's place. This demonstrates one way of doing GWT with Eclipse.
  7. Exporting WAR in GWT - Tutorial to create a WAR file in command line (works only with WTP 2.0).
  8. GWT Small Guide - I wrote this guide thinking in the user's who want's develope dynamic application's with the  GWT (Google Web Toolkit)  in an AMP(Apache,MySQL,PHP) environment's. The basic idea is write a small and very simple application using  MySQL and PHP at the server side, and GWT for the client interfaze, using JSON for the communication between the client and the server.
  9. Ajax for Java developers: Exploring the Google Web Toolkit - One of several GWT tutorials from IBM's developerworks. In this article, I'll run through creating a simple GWT application to fetch a weather report from a remote Web API and display it in the browser. On the way, I'll briefly cover as many of GWT's capabilities as possible, and I'll mention some of the potential problems you'll come across.
  10. Trivial GWT Example - from Robert Hanson, who went on to write an excellent book on GWT, a simple GWT-RPC example.
  11. Build an Ajax-enabled application using the Google Web Toolkit and Apache Geronimo - recent (May 2007) two part series (part two is here) with source code, flash demos, etc.. Requires registration.
  12. Google Web Toolkit - This article describes the development of a simple Ajax application on Mac OS X using GWT and familiar Java tools, such as Apache Ant, the Tomcat 5.0 servlet container, and the IntelliJ IDEA integrated development environment (the latter is a commercial IDE). The article assumes some knowledge of Java and Ant.
  13. GWT Tutorial - focuses on producing a web site, rather than a webapp.
  14. Getting Started - the first of Paval JBanov's planned five GWT tutorials. The others are First Application, Core widgets and panels, Custom widgets and RPC (not yet written).
  15. GWT Plugin Tutorial - oddly enough, this tutorial demonstrates how to integrate GWT with Struts 2 WITHOUT the GWT plugin. Hmmmm.
  16. Getting Started with Google Web Toolkit (GWT) - Very basic, getting started instructions.
  17. Tutorial: Creating a Login application - demonstrates the use of Instantiations' GWT Designer tool (WYSIWYG UI design for GWT).
  18. Basic GWT / PHP Communication - Part 1: Java and Part 2: PHP. All the GWT documentation is about hooking up Java on the front and back ends. What about PHP? This shows how.
  19. String-based RPC between GWT and PHP - forget about serializing Java objects via XML and JSON; this is the dead simple approach.
  20. Using cURL to Interface GWT with an Existing Site - this one is kind of hard to explain. If you know about curl and PHP, this article is worth reading.
  21. Creating GWT RPC Services Tutorial - short guide to using gwt4nb, the Netbeans plugin for GWT, to create GWT-RPC services.
  22. Creating a simple app with GWT4NB - flash based tutorial on creating an anagram application with GWT and Netbeans.
  23. Googled by GWT - Part 1 and Part 2. Extensive getting started tutorial with lots of screenshots.
  24. Google Web Toolkit Tutorial - short example demonstrates use of the keyboard listener.
  25. Step by Step: A Mortgage Calculator using GWT - as it says, a mortgage calculator demo using GWT.
  26. IntelliJ IDEA: Google Web Toolkit as 1-2-3 - Animated demo walks through the configuration of IntelliJ Idea for the
    Google Web Toolkit and shows how to write a GWT image viewer
    application.
  27. IntelliJ IDEA: Creating GWT Application from a Web Module - Animated demo of using GWT in a web module (IDEA's project/module type for Java webapps).
  28. Ajax for Java developers: Exploring the Google Web Toolkit - extensive tutorial from IBM developerworks that builds all the way to a weather reporter widget.
  29. Integrating the Google Web Toolkit with JSF using G4jsf - I can't say that I really love JSF, but if you bend that way, this will teach you how to marry the two. Extensive with lots of code snippets and screenshots.
  30. Asynchronous Google (Web Toolkit) and Django - Integrating GWT and Django using JSON.
  31. Using VistaFei  IDE 1.0 for GWT: A Tutorial - VistFei is an IDE. The last time I looked at it, this tutorial had somehow lost it's screenshots and the CSS had been jacked up.
  32. Using Google Web Toolkit - video HOWTO by Bruce Johnson, the tech lead of GWT.
  33. GWT-Spring Integration Demystified - any time a new technology comes along, it just has to be integrated into Spring. Here you go.
  34. Build an Ajax application using Google Web Toolkit, Apache Derby, and Eclipse - Part 1 and Part 2. Extensive tutorial in two parts, the first of which deals with the front end, the second of which deals with the back end.
  35. Ease AJAX development with the Google Web Toolkit - develops a book search application as part of a getting started tutorial.
  36. Roughian Examples - combination demo/tutorial of GWT. Version 2 is under development.

 

Если ещё найду, буду добавлять.

Мне когда-то больше всего помогли 1 и  26.

Monday, July 2, 2007

Funny ping from the future

На моём компе стандартные утилиты Windows такие как ping/tracert довольно забавно ведут себя.

Вот записал видео так сказать на память - всё-таки пинги из будущего получается:

 

Вот скриншотики чтоб лучше видно было:

 

GWT: XML-driven user interface

Вчера довёл свой проект gwt-ui до стадии, когда можно его выкладывать. Получился довольно интересный инструмент, который позволяет сильно упростить построение пользовательских интерфейсов для GWT.

Идея появилась после того, как я заметил, что приходится писать много похожего кода при построении интерфейса: панели, внутри ещё панели, внутри которых виджеты и т.д. В то же время, сейчас всё более и более популярны "описательные" способы построения интерфейсов (напр. XAML).

Такой подход более гибкий, наглядный и удобный, чем "последовательное" создание.

В GWT же сейчас используется именно "последовательное" создание интерфейса: созаются панели, внутрь который добавляются виджеты.

Вспомнив о генераторах в GWT, о которых я недавно писал, подумалось - почему бы не использовать их, для генерации хотя бы базового кода генерации интерфейса? Вот и взялся за реализацию этой идеи.

Как результат и появился проект gwt-ui. Что же он из себя представляет? Фактически, это jar-файл, который можно подключить к проекту, и после этого появится возможность воспользоваться генератором, который находится в этом проекте. 

Приведу список возможностей, которые сейчас доступны:

  1. Построение интерфейса используя XML-описание
  2. Простой доступ к сгенерированным объектам (сейчас - к контейнерам)
  3. Простое переключение "состояний" (вызов одного метода)
  4. "Ленивое" создание виджетов: виджеты создаются только тогда, когда они становятся видимыми
  5. Наследование состояний: любое состояние может наследоваться от другого. Можно написать некое "основное" состояние, которое описывает базовое расположение виджетов, а остальные просто описывают изменения.
  6. Возможность задания визуальных свойств контейнеров (напр. "align='right' width='100%' style='bar'")
  7. Нотификация виджетов о новом состоянии: Если виджет имплементирует интерфейс UIStateListener и он добавлен в интерфейс, то ему будет сообщатся о том, что состояние поменялось.

Вот небольшое how-to создания простейшего интерфейса с помощью gwt-ui:

1. Файл описания интерфейса.

Для начала создадим файлик, рядом с файлом описания модуля (который <ModuleName>.gwt.xml), в котором опишем структуру простейшего интерфейса (более сложный пример можно посмотреть в коде примера, доступного в svn):

<gwtui>
<layout>
<container id='main' type='FlowPanel'/>
</layout>
<states widgetpackage='client'>
<state id='fiststate' default='true' >
<content container='main'><widget type='MyWidget1' /></content>
</state>
<state id='anotherstate'>
<content container='main'><widget type='MyWidget2' /></content>
</state>
</states>
</gwtui>

В этом файле определены:



  • Контейнер, имеющий тип FlowPanel под именем 'main'

  • Два состояния:


    • Состояние 'firststate', которое будет использоватся по умолчанию (т.е. при первоначальной загрузке и/или если произведенна попытка изменить состояние, которое не описанно в документе. При установке этого состояния, в контейнер под именем 'main' помещается виджет с типом 'MyWidget1' (находищийся в пакете 'client')

    • Состояние 'anotherstate'. При установке этого состояния, в контейнер под именем 'main' помещается виджет с типом 'MyWidget2' (находищийся в пакете 'client'). При этом, виджеты, которые были помещенны в этот контейнер другими состояниями пропадают.

Думаю, синтаксис достаточно прост.  Более сложное описание примера можно посмотреть на страничке демо-примера, где используется и наследие состояний и визуальные свойства контейнеров.


2. Подключение GWTUI


Для работы gwt-ui, требуется подключение модуля в файле определения модуля GWT. Это можно сделать просто добавив такую строчку в файл определения (<ModuleName>.gwt.xml):

<inherits name='org.olostan.gwtui.GWTUI'/>

 


3. Создание интерфеса-маркера


Для получения объектов, созданных gwt-ui и изменения состояний интерфейса, необходимо определить в своём проекте интерфейс, который будет наследоватся от  интерфейса "UIManager", например:

public interface MyUI extends UIManager {
public Panel getMainContainer();
}

Данный интерфейс позволяет получить екземпляр контейнера 'main', описанного в файле описания интерфейса. Для того, например, чтоб добавить его на страничку.


4. Создание и добавление пользовательского интерфейса


Для того, чтобы создать сгенерированный пользовательский интерфейс, достаточно воспользоватся статическим методом GWT.create(). После этого с помощью полученного интерфейса можно будет получить доступ к созданным объектам и поменять текушее состояние. Например, при инициализации модуля:

public class MyModule implements EntryPoint {
MyUI ui;
public void onModuleLoad() {
ui = (MyUI) GWT.create(MyUI.class);
RootPanel.get().add(ui.getMainContainer());
ui.setState("fiststate");
}
}

В последствии, когда надо поменять текущее состояние, можно вызвать метод setState, например:

ui.setState('anotherstate');.

 


Вот таким способом можно создавать интерфейсы на основе XML-описания интерфейса и потом переключать состояния интерфейса.

Tuesday, June 26, 2007

GWT: Changing locale using cookies

Продолжая работу над своим проектом портирования функционала поисковой системы Look'а на GWT (lab.look.org.ua), я дошел до и18нации. В GWT, как известно, есть довольно хорошо продуманные средства для хорошей локализации. Но мне захотелось, чтоб текущий выбор языка хранился в куках, а не в переменной. В общем, решение получилось довольно простое.

1. Выбор языка и сохранение в cookie.

Этим занимается вот такой виджет:

package client.widgets;

import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Cookies;

import java.util.Date;

/**
* Created by Olostan
* Date: 24.06.2007 23:37:00
*/
public class LangSelection extends Composite {
private static native void RefreshWindow() /*-{
$wnd.location.reload();
}-*/;
private class LangImage extends Image implements ClickListener {
final String code;
public LangImage(String code) {
super();
this.code = code;
this.setUrl("images/flags/"+code+".gif");
this.addClickListener(this);
this.setStyleName("lang-image");
}

public void onClick(Widget sender) {
Date date = new Date();
if (!code.equals("en")) {
Cookies.setCookie("locale",code, new Date(date.getTime()+60*60*60*60));
} else {
Cookies.setCookie("locale","",new Date(date.getTime()-1000));
}
RefreshWindow();
}
}
String[] lang = new String[] { "en","uk","ru" };
public LangSelection() {
HorizontalPanel panel = new HorizontalPanel();
for(int c=0;c<lang.length;c++) {
LangImage img = new LangImage(lang[c]);
panel.add(img);
}
initWidget(panel);
setStyleName("lang-widget");
}
}

 


Тут самый важный код  - это тело метода onClick. Он именно записывает выбранный язык в Cookies и делает рефреш странички.


2. Установка языка при загрузке модуля


Тут пришлось применить вот такой интересный трюк: в исходном html файле в блоке head добавляется вот такой код:

<head>
<title>MyModule title</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript">
function getCookie(name) {
var dc = document.cookie;
var prefix = name + "=";
var begin = dc.indexOf("; " + prefix);
if (begin == -1) {
begin = dc.indexOf(prefix);
if (begin != 0) return null;
} else {
begin += 2;
}
var end = document.cookie.indexOf(";", begin);
if (end == -1) {
end = dc.length;
}
return unescape(dc.substring(begin + prefix.length, end));
}
var locale=getCookie("locale");
if (locale!="") {
document.writeln("<meta name=\"gwt:property\" content=\"locale="+locale+"\"> ");
}
</script>
<meta name='gwt:module' content='MyModule'>
<link rel=stylesheet href="MyModule.css">
</head>

 


(тут попрошу прощение за потерянный origin кода на яваскрипте чтения значения cookie).


Таким образом при загрузке модуля будет установленна нужный язык.


Пример того, как оно работает можно посмотреть вот тут: lab.look.org.ua

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 варианты некоторых пазлов можно посмотреть тут

Thursday, June 21, 2007

Storing revision information using MSBuild

После опубликования заметки про использование WSH для модификации/генерации файлов во время сборки проекта, Kostiantyn Kudriavtsev предложил альтернативный вариант - воспользоваться "тасками" MSBuild'а.

Действительно идея отличная при использовании автоматизированных сборок продуктов. В особенности с использованием MSBuild Community Tasks, в котором реализовано огромное количество "тасков" - от получения версии из SVN/VSS/TFS до модификаций файлов, создания архивов, работой с XML.

Нашел так же хороший простенький пример как раз подобной операции, что мне нужна была.

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

Tuesday, June 19, 2007

Storing revision information using Windows Script Hosting

Вот возникла задача в ASP.NET приложении отображать номер ревизии, дату когда происходил билд. Не знаю, возможно есть и более простые решения, но так, как я их не нашёл, решил написать простенький JScript код, который будет выполняться WScript'ом как prebuild-евент проекте.

Вот какой скриптик получился:

var ws = new ActiveXObject("Wscript.Shell");
var path = "";
if (WScript.Arguments.length == 1) {
path = WScript.Arguments(0);
}
var fso = new ActiveXObject("Scripting.FileSystemObject");
var oSvn = ws.Exec("svn info");
while (oSvn.Status == 0)
{
WScript.Sleep(100);
}
var vers = oSvn.StdOut.ReadAll();
var regex = new RegExp("Revision: (\\d+)","m");
var revArr = regex.exec(vers);
if (revArr==null) {
WScript.Echo("No revision found!");
} else {
rev = revArr[1];
var templateFile = fso.OpenTextFile(path+"ProductVersion.cs.template", 1);
var template = templateFile.ReadAll();
var regex2 = new RegExp("\\$Revision\\$","gm");
template = template.replace(regex2,rev);
var regex_date = new RegExp("\\$Date\\$","gm");
var date = new Date();
template = template.replace(regex_date,date.toGMTString());
var result = fso.CreateTextFile(path+"ProductVersion.cs", true);
result.Write(template);
result.Close();
}

Он фактически на основе темплейта ProductVersion.cs.template создаёт файлик ProductVersion.cs, в котором заменяються $Revision$ текущей ревизией, а $Date$ датой.


Тут разве что стоит отметить два "но":



  1. Скрипт должен запускаться в том месте, где доступна информация о ревизии (+ рядом должен лежать файлик темплейта). По этому, следует перед вызовом скрипта (через wscript/cscript) в prebuild добавить cd $(ProjectDir)
  2. Так, как проект ASP.NET 2.0 не имеет prebuild/postbuild евентов (во всяком случае я не нашёл), нужно иметь другой проект, который будет экспортить инфу о ревизии.

Кстати, почему-то подумалось: решение чем-то похоже на решение с "генераторами", про которое я недавно писал.

REST - Just rest!

Всё чаще и чаще слышу последнее время про REST и всё, что с ним связанно. Интересно тем, что все давно пользуются так или иначе, но стандартизировать все ленятся.

А реализовывать чей-то API ещё хуже - то одно намудрят, то другое.

И по этому меня заинтересовала работа Thomas Steiner'а об автоматизации этого процесса. И ещё больше - реализация идея в виде работающего генератора кода (Кстати, ещё тем, что он написан на GWT, и доступен исходный код со странички проекта).

Довольно полезная тулзовина для реализации кода, использующего REST-запросы.

GWT + iPhone?

Сразу после того, как начали говорить о том, что в iPhone нельзя будет ставить свои проги, возникла мысль -  а как же "виджеты" и прочее, для чего нужно только одно - качественный броузер.

И, как оказалось, эта мысль была не "из воздуха". Как написал Robert Hanson на своём блоге, Apple недавно провели World Wide Developers Conference, на котором был анонс SDK для iPhone. И как написал Роберт "That's right, the new SDK is the same SDK that Web 2.0 developers have been working with for the past few years, including GWT."

Сразу же пошла волна плейсхолдеров для проектов с GWT-виджитами, которые бы использовали фичи iPhone по типу gwt-iphone.

Так же, стоит отметить интересные мысли Joel Webber'а о взаимодействии GWT не только с Safari на iPhone, а так же с броузером Opera на Wii.

Действительно - зачем придумывать новый SDK, если можно воспользоваться уже как бы можно сказать многолетним опытом разработки Web 2.0 приложений? А в особенности используя такие тулкиты, как GWT, Yahoo UI и подобные, которые позволяют создавать довольно сложные пользовательские интерфейсы?

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

К примеру, я так и не нашёл никакого достойного ответа Microsoft'а. Интересно, они имеют какую-то скрытую технологию или просто отстают в развитии?

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-объектам, так как методы последнего могут быть изменены при компиляции)

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

Brainbench: ASP.NET

Недавно проглянул, что некоторые из моих сертификатиков на BrainBench скоро перестанут быть валидными - там срок активности вроде 3 года. Вот и решил пройти какой-то из их тестов.

На глаза попался тест по ASP.NET'у, вот и решил пройти его - не смотря, что с ASP.NET я работаю уже как бы больше года, на брейнбенче так и не проходил этот тест.

Сразу же попался интересный вопрос про количество евентов у global.asax. Интересен он был тем, что варианты были такие - 2, 4, 6, 8, больше 15. Но, насколько я знаю, этот файл есть ничто иное, как обёртка над System.Web.HttpApplication, который в 1.1 имеет ровно 14 event'ов (хотя в 2.0 уже 17).

В остальном тест довольно интересный. Дал повод задуматься о том, что я не так часто, как стоило бы пользовался System.Web.Caching.Cache - оказывается довольно удобная и полезная штука.

В целом, результат, хоть и не очень высокий, но меня удовлетворил.

Интересно как-то пройти ASP.NET 2.0 и С# 2.0

Per compitalis ad astra

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

Для начала хотелось бы описать то, что "Per compitalis ad astra" лично для меня значит. Наверное всё пошло ещё со школьных времён: школа, которую я заканчивал в последние годы моего обучения там была переведена в статус "гимназии", и, кроме умного названия, получила девиз, который весел во многих холах. Девиз был не очень оригинален - "per aspera ad astra" :) Тогда нам объяснили гордый смысл пословицы, но звучание мне понравилась и до сих пор помню.

И проанализировав тот путь, который я прошёл с начала своей девелоперской карьеры, я понял, что, не смотря на все развилки в технологиях, решениях, основная цель одна - добится максимального удобства. Вот и простой заменой одного слова и получилось субжевое название, перевод которого можно примерно озвучить как "через перекрёстки (распутья) к звёздам". Где распутьями я понимаю разные платформы, решения, языки и т.д., а "звёздами" - удобный, красивый, гибкий, работающий продукт (результат).

В общем, тут я буду постить разные интересные ссылки, мысльи, сниппеты кода для совершенно разных платформ, языков и т.д.