<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Записки искателей &#187; Java</title>
	<atom:link href="http://voituk.kiev.ua/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://voituk.kiev.ua</link>
	<description>while ( isAlive() ) {doCode(); doFun();}</description>
	<lastBuildDate>Sun, 29 Apr 2012 18:50:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Hello World на Google App Engine</title>
		<link>http://voituk.kiev.ua/2010/02/15/hello-world-google-app-engine/</link>
		<comments>http://voituk.kiev.ua/2010/02/15/hello-world-google-app-engine/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 11:38:49 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=1633</guid>
		<description><![CDATA[Небольшая заметка о том, как создать и разместить свой проект на сервисе Google App Engine. По &#8220;долгу службы&#8221; довелось пощупать интересную технологию, до которой раньше не доходили руки. Думаю, Google App Engine будет интересен не только мне, поэтому начинаю мини-цикл статей о разработке для App Engine.  После того, как вы впервые войдёте в сервис appengine, [...]]]></description>
			<content:encoded><![CDATA[<p>Небольшая заметка о том, как создать и разместить свой проект на сервисе Google App Engine.</p>
<p>По &#8220;долгу службы&#8221; довелось пощупать интересную технологию, до которой раньше не доходили руки. Думаю, Google App Engine будет интересен не только мне, поэтому начинаю мини-цикл статей о разработке для App Engine.  <span id="more-1633"></span></p>
<p>После того, как вы впервые войдёте в сервис appengine, вам нужно будет подтвердить свою &#8220;личность&#8221;. Google вышлет на номер указанного вами телефона SMS с текстом вроде Google App Engine Code: 1234567. Лично мне SMSка дошла меньше чем за минуту (такой способ куда лучше бумажной почты, которую Google использует для Adsense). Такая проверка проводится только для первого создаваемого приложения.</p>
<p>Следующий шаг &#8211; зарегистрировать имя-идентификатор для приложения.</p>
<p>Теперь регистрация окончена, приступаем к разработке. App Engine работает на Java 6 и именно эта платформа является рекомендуемой, хоть и Java 5 тоже поддерживается. Я навскидку не смог придумать, что может пойти не так, если приложение скомпилированное на Java 5 запустить на JVM шестой версии, но Google&#8217;у виднее.</p>
<p>Скачиваем и распаковываем Google App Engine SDK для Java <a href="http://code.google.com/appengine/downloads.html">http://code.google.com/appengine/downloads.html</a>.</p>
<p>Теперь дело за малым &#8211; написать простое приложение и отправить на сервер :-)</p>
<p>Тут Google оставил меня без материала для заметки, поскольку минимальный Hello World уже есть в комплекте SDK. Хранится он в папке demos\new_project_template. Тут есть и build.xml и статический контент, и сервлет и даже пара файлов с конфигурацией для самых распространённых logging API: Log4J и JUL (java.util.logging). Скопировав содержимое в папку, где будет жить ваш проект, вы получите отличный каркасс для начала разработки. Единственное, что нужно теперь сделать &#8211; указать путь к развёрнутому SDK: либо в параметрах при запуске ant либо прямо в build.xml.</p>
<p>Перед тем, как запустить приложение на локальном &#8220;эмуляторе&#8221; appengine, давайте посмотрим, что ещё есть в &#8220;комплекте&#8221;. Кроме стандартного web.xml в WEB-INF лежит файл appengine-web.xml &#8211; дополнительная конфигурация для движка appengine:</p>
<pre><code>&lt;appengine-web-app xmlns="http://appengine.google.com/ns/1.0"&gt;
 &lt;!-- Replace this with your application id
    from http://appengine.google.com --&gt;
 &lt;application&gt;juriytest&lt;/application&gt;
 &lt;version&gt;1&lt;/version&gt;
&lt;/appengine-web-app&gt;
</code></pre>
<p>Как и следует из комментария, в теге application нужно указать id приложения, котрый был зарегистрирован на appengine.</p>
<p>Кроме того в src/META-INF находится файл jdoconfig.xml, который является (неожиданно) конфигурацией для JDO &#8211; persistance механизма, который используется в среде appengine. Сейчас его трогать не будем, пускай живёт, hello world и без него запустится.<br />
В проекте есть файл index.html, как пример статичного контента и HelloAppEngineServlet.java, который является привычным сервлетом без экзотики.</p>
<p>Чтобы запустить приложение локально выполняем ant runserver из корня тестового проекта.<br />
Для того, чтобы &#8220;доставить&#8221; приложение на живую платформу нужно использовать утилиту из SDK: bin\appcfg.cmd</p>
<p>appcfg.cmd update www</p>
<p>www тут &#8211; путь к &#8220;развёрнутому&#8221; проекту. Appengine не поддерживает war файлы, а вместо этого работает с директориями с той же структурой. После того, как build.xml собрал для нас проект в папку www указанной выше командой можно загрузить его на appengine.</p>
<p>Пара полезных моментов и &#8220;граблей&#8221;.</p>
<p>App Engine сохраняет всё что вы напишите в System.out и System.err в логи. При этом e.printStackTrace в логи упорно не попадает. Немного сбивает с толку.</p>
<p>Логи в административном интерфейсе обновляются не моментально, а только через несколько секунд.</p>
<p>Последние грабли стоили жизни моим нервным клеткам. В конфиге appengine указывается версия проекта. Не надейтесь, что если будет указана версия выше текущей развёрнутой, то новая версия заменит старую. Всё обстоит совершенно не так. Новая версия затирает развёрнутую версию с <em>таким же</em> индексом. Затем, пользователь выбирает, какая из версий будет доступна по умолчанию. То есть, я могу развернуть версии 1, 2, 3. После разворачивания версии 3, пользователи видели только версию 1, пока в интерфейсе администратора не будет указана другая.</p>
<p>На этом пока что всё. В следующей заметке опишу, как заставить app engine работать с groovy.</p>
<p>__________<br />
Спонсор заметки: &#8220;Идеал&#8221;, <a href="http://ideal.kiev.ua/">раскрутка сайта</a> в Украине</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2010/02/15/hello-world-google-app-engine/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Разминка для хвоста</title>
		<link>http://voituk.kiev.ua/2009/12/02/razminka-dlya-xvosta/</link>
		<comments>http://voituk.kiev.ua/2009/12/02/razminka-dlya-xvosta/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 23:01:49 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Задачки]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=1303</guid>
		<description><![CDATA[Ух, как же давно ничего не писал в блог! Отчасти тому виной твиттер. Я обязательно напишу отдельную заметку об этом &#8220;убийце блогов&#8221;. А сейчас, хочу представить вам пару свеженьких Java задачек. 1. Не изменяя код первго метода сделать так, чтобы программа компилировалась и печатала &#8220;This is right&#8221;. У этой задачки, как минимум, 3 решения. Комментировать [...]]]></description>
			<content:encoded><![CDATA[<p>Ух, как же давно ничего не писал в блог! Отчасти тому виной твиттер. Я обязательно напишу отдельную заметку об этом &#8220;убийце блогов&#8221;. А сейчас, хочу представить вам пару свеженьких Java задачек.<br />
<span id="more-1303"></span><br />
1. Не изменяя код первго метода сделать так, чтобы программа компилировалась и печатала &#8220;This is right&#8221;. У этой задачки, как минимум, 3 решения. Комментировать код первого метода тоже нельзя.</p>
<pre>
public class A {

	public static void main(String[] args) {
		System.out.println("This is wrong");
	}

	public static void main(String[] args) {
		System.out.println("This is right");
	}
}
</pre>
<p>2. Написать стандартный Hello World на Java. При этом нельзя использовать ни одной точки с запятой. Закодированные UTF символы тоже использовать нельзя.</p>
<p>Ответы я опубликую через сутки, а пока что жду комментариев.</p>
<p>P.S. За мной уже закрепилась слава человека, обожающего абсолютно бесполезные, с практической точки зрения, задачи. Я пришел к выводу, что для таких &#8220;упражнений&#8221; слово &#8220;задача&#8221; совсем не подходит. Все привыкли, что &#8220;задачи&#8221; это упражнения, которые развивают какие-то практические навыки. К примеру &#8220;реализовать генератор случайных чисел на Java&#8221; это задачка. А для того, что публикую я, лучше подходит слово &#8220;загадка&#8221;. Так что вот вам свежая &#8220;без окон без дверей полна горница людей&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2009/12/02/razminka-dlya-xvosta/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Apache Tomcat init.d script</title>
		<link>http://voituk.kiev.ua/2009/04/28/apache-tomcat-initd-script/</link>
		<comments>http://voituk.kiev.ua/2009/04/28/apache-tomcat-initd-script/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 13:33:18 +0000</pubDate>
		<dc:creator>Vadim Voituk</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=1022</guid>
		<description><![CDATA[Продолжая серию заметок &#8220;Из программиста в руководители админы&#8221; :), опять же себе на заметку пишем init-скрипт для корректного запуска/перезапуска Apache Tomcat под Linux. Создаем файл /etc/init.d/tomcat такого содержания: # Tomcat auto-start # # chkconfig: - 90 15 # description: Jakarta Tomcat Java Servlets and JSP server export JAVA_HOME=/usr/java/default export JRE_HOME=/usr/java/latest export CATALINA_HOME=/home/vadim/tomcat case $1 in [...]]]></description>
			<content:encoded><![CDATA[<p>Продолжая серию заметок &#8220;Из программиста в <span style="text-decoration: line-through;">руководители</span> админы&#8221; :), опять же себе на заметку пишем init-скрипт для корректного запуска/перезапуска Apache Tomcat под Linux.</p>
<p>Создаем файл <strong>/etc/init.d/tomcat</strong> такого содержания:</p>
<pre><code># Tomcat auto-start
#
# chkconfig: - 90 15
# description: Jakarta Tomcat Java Servlets and JSP server

export JAVA_HOME=/usr/java/default
export JRE_HOME=/usr/java/latest
export CATALINA_HOME=/home/vadim/tomcat

case $1 in
start)
  sh $CATALINA_HOME/bin/startup.sh
  ;;
stop)
  sh $CATALINA_HOME/bin/shutdown.sh
  ;;
restart)
  sh $CATALINA_HOME/bin/shutdown.sh
  sh $CATALINA_HOME/bin/startup.sh
  ;;
*)
  echo "Usage: $0  {start|stop|restart}"
  exit 1
  ;;
esac
exit 0</code></pre>
<p>После этого выполняем:<br />
<code>chmod +x /etc/init.d/tomcat<br />
 chkconfig tomcat on</code></p>
<p>Аналогичный <a href="http://voituk.kiev.ua/2009/02/09/nginx-initd-script/">init.d-скрипт для запуска nginx</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2009/04/28/apache-tomcat-initd-script/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Java + Groovy on Google App Engine</title>
		<link>http://voituk.kiev.ua/2009/04/08/java-groovy-on-google-app-engine/</link>
		<comments>http://voituk.kiev.ua/2009/04/08/java-groovy-on-google-app-engine/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 06:30:10 +0000</pubDate>
		<dc:creator>Vadim Voituk</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=1000</guid>
		<description><![CDATA[Вот и свершилось то, чего так долго ждали и просили большевики прогрессивные ИТ-гики &#8211; Google добавляет поддержку Java (а вместе с ней и Groovy) в Google App Engine. Как сообщает в корпоративном блоге SpringSource Guillaume Laforge (project-manager проекта Groovy), последние несколько недель они работали совместно с командой Google App Engine над &#8220;правильным&#8221; запуском Groovy на [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" title="Google App Engine Groovy" src="http://voituk.kiev.ua/wp-content/uploads/google-app-engine-groovy.png" alt="" width="250" height="202" />Вот и свершилось то, чего так долго <a href="http://voituk.kiev.ua/2008/04/14/java-groovy-on-google-appspot/">ждали и просили</a> <span style="text-decoration: line-through;">большевики</span> прогрессивные ИТ-гики &#8211; Google <a href="http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html">добавляет поддержку Java</a> (а вместе с ней и Groovy) в Google App Engine.</p>
<p>Как сообщает в корпоративном блоге SpringSource Guillaume Laforge <em>(project-manager проекта Groovy)</em>, последние несколько недель они работали совместно с командой Google App Engine над &#8220;правильным&#8221; запуском Groovy на GAE.</p>
<p>Совмесная работа вылилась в набор дополнений в реализацию security-модели Groovy.</p>
<p>Небольшая <a href="http://blog.springsource.com/2009/04/07/write-your-google-app-engine-applications-in-groovy/">заметка о том, как запустить Groovy приложение в среде Google App Engine</a> от того же Guillaume Laforge.</p>
<p>P.S. Что-то мне подсказывает что теперь GAE перестанет быть игрушкой для питонистов, а станет упрощенной версией Amazon AWS, тем самым накорню убив остальные Java in Cloud &#8211; сервисы а-ля <a href="http://voituk.kiev.ua/2008/12/26/running-java-in-a-cloud/">Stax</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2009/04/08/java-groovy-on-google-app-engine/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>JavaScript applet loader.</title>
		<link>http://voituk.kiev.ua/2009/02/06/javascript-applet-loader/</link>
		<comments>http://voituk.kiev.ua/2009/02/06/javascript-applet-loader/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 11:50:09 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaScript/Ajax]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=958</guid>
		<description><![CDATA[У каждого разработчика есть свои маленькие &#8220;заморочки&#8221; по поводу того как должно выглядеть приложение. Одна из моих любимых: пользователь должен знать минимум о том, как работает приложение и на каких технологиях оно построено. Взять, к примеру, Flash. Загружается тихонько в окне браузера, крутит пользователю картинки или видео и до тех пор, пока пользователь не начнет [...]]]></description>
			<content:encoded><![CDATA[<p>У каждого разработчика есть свои маленькие &#8220;заморочки&#8221; по поводу того как должно выглядеть приложение. Одна из моих любимых: пользователь должен знать минимум о том, как работает приложение и на каких технологиях оно построено. Взять, к примеру, Flash. Загружается тихонько в окне браузера, крутит пользователю картинки или видео и до тех пор, пока пользователь не начнет по нему кликать правой кнопкой, не признаЕтся кто он такой.</p>
<p>С другой стороны Java. Вот тебе пользователь раз логотип при загрузке апплета, да побольше, побольше, а если ты вдруг забыл про то, что работаешь с великой и могучей Java, мы тебе иконку в трей кинем, чтобы он тебе оттуда напоминал что пора качать новую версию.<br />
Вобщем, вы мою позицию поняли.</p>
<p>Недавно я задался вопросом, как организовать загрузку апплета на странице так, чтобы пользователь не увидел экрана загрузки. Вместо него я бы хотел, к примеру, разместить логотип и progress bar (не настоящий, а просто картинку, которая показывает, что процесс идет). Второе обязательное требование: чтобы приложение отображалось, как только GUI прорисован. Мы не хотим заставлять пользователя ждать лишнее время.<br />
<span id="more-958"></span><br />
Перечитав комментарии <a href="http://voituk.kiev.ua/2008/05/28/java-deployment-toolkit/">http://voituk.kiev.ua/2008/05/28/java-deployment-toolkit/</a> я решил не использовать стандартный JavaScript от Sun. Я воспользовался альтернативой &#8211; скриптом из классного, но не очень известного проекта <a href="http://www.interactivepulp.com/pulpcore/">PulpCore</a>. Этому проекту можно было бы посвятить отдельную заметку, отличная разработка заслуживающая более пристального внимания. После небольшой &#8220;доводки напильником&#8221; вышло отличное решение, которое я протестировал на тех браузерах, что были у меня под рукой. </p>
<p>Кроме &#8220;сокрытия&#8221; экрана загрузки, скрипт умеет определять версию JRE (как и аналог от Sun), делать &#8220;отложенную загрузку&#8221;: апплет загружается после того, как пользователь нажмет на кнопку. </p>
<p>Принцип работы скрипта прост: он определяет браузер и версию Java плагина, генерирует текст HTML элемента, который загружает апплет и отображает сплеш-скрин поверх него. Пользователь видит &#8220;правильный&#8221; сплеш, а не стандартный экран загрузки Java. Если же версия Java не подходит, отображается сообщение предлагающее пользователю решить эту проблему.</p>
<p>Когда апплет полностью загрузился и готов к тому чтобы предстать перед пользователем во всей красе, он (апплет) вызывает через LiveConnect функцию, которая убирает экран загрузки. Вуаля. Если LiveConnect по какой-то причине не сработал, сплеш автоматически исчезнет после таймаута.</p>
<p>Вот пример кода, который отобразит апплет на странице:</p>
<pre><code>
	&lt;script type="text/javascript"&gt;&lt;!--
		pulpcore_width = 500;
		pulpcore_height = 300;
		pulpcore_archive = "applet-17.jar";
		pulpcore_class = "TestApplet.class";
	//-->
	&lt;/script&gt; 

	&lt;div id="game"&gt;
		&lt;script type="text/javascript" src="loader.js">&lt;/script&gt;
		&lt;noscript>&lt;p&gt;To play, enable JavaScript from the Options or Preferences menu.&lt;/p&gt;&lt;/noscript&gt;
	&lt;/div&gt;
</code></pre>
<p>Примеры скрипта в действии можно посмотреть на сайте проекта <a href="http://www.interactivepulp.com/pulpcore/bubblemark/">PulpCore</a>.</p>
<p>Вот так, просто и надежно мы оставляем пользователей в блаженном неведении, какая именно платформа делает работу. Жаль иконку из трея так же просто убрать не выйдет.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2009/02/06/javascript-applet-loader/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>POST сюрприз</title>
		<link>http://voituk.kiev.ua/2009/02/02/post-surprize/</link>
		<comments>http://voituk.kiev.ua/2009/02/02/post-surprize/#comments</comments>
		<pubDate>Mon, 02 Feb 2009 12:09:04 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=956</guid>
		<description><![CDATA[Сейчас, в мире web 2.0 самый модный buzzword это давно уже не ajax. Асинхронные запросы на страничках настолько прочно вошли в нашу жизнь, что воспринимаются как должное. Более модный нынче термин &#8211; Comet. Comet &#8211; технология общения клиента с сервером, похожая на Ajax, за тем исключением, что Comet держит HTTP подключение открытым. Что это означает? [...]]]></description>
			<content:encoded><![CDATA[<p>Сейчас, в мире web 2.0 самый модный buzzword это давно уже не ajax. Асинхронные запросы на страничках настолько прочно вошли в нашу жизнь, что воспринимаются как должное. Более модный нынче термин &#8211; Comet. Comet &#8211; технология общения клиента с сервером, похожая на Ajax, за тем исключением, что Comet держит HTTP подключение открытым. Что это означает? К примеру, сервер может в любой момент оповестить клиента о событии, не дожидаясь, пока клиент спросит сам.<br />
По такому принципу, к примеру, работает Google Talk из браузера.<br />
Это преамбула.</p>
<p>На выходных я решил реализовать такое подключение из Java-апплета к серверу. Я хотел, чтобы _оба_ канала (и канал для запросов и канал для ответов) были постоянно открыты. Таким образом задержка передачи сообщений была бы идентична задержке TCP/IP подключения.<br />
<span id="more-956"></span><br />
К тому времени у меня было неплохо работающее симплексное подключение (канал от сервера был открыт всегда, а вот сообщения клиента доставлялись обычным способом). Казалось, работы совсем немного, но меня ждал большой и неприятный сюрприз, которому и посвящена заметка.</p>
<p>Вот классический код POST запроса к серверу. Уверен, каждый хоть раз да писал такой:</p>
<pre><code>
URL url = new URL("http://somehost.com:8080/do");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStream out = conn.getOutputStream();
out.write(data);
out.flush();

InputStream is = conn.getInputStream();
processOutput(is)
out.close();
is.close();
</code></pre>
<p>Поскольку я держал подключение открытым и ответы сервера меня не интересовали (они приходили в другом потоке), код приобрел такой вид:</p>
<pre><code>
URL url = new URL("http://myserver:8080/do");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStream out = conn.getOutputStream();

while (работаем) {
	data = // получить данные из очереди, или спать, если очередь пуста
	out.write(data);	

	// Вот это нельзя забыть, а то вдруг данные закешируются :-)
	out.flush();
}
</code></pre>
<p>Каково же было мое удивление, когда я понял, что такой код вообще ничего не отправляет! Оказалось, что URLConnection кеширует на клиенте _все_ данные до момента отправки. Самое грустное в этой истории то, что отключить этот &#8220;функционал&#8221; изысками вроде setUseCaches(false) не выходит. </p>
<p>Неприятное следствие, которое я подтвердил экспериментом. При попытке передать через POST файл, вы элементарно можете получить Error, если размер файла больше оставшегося места в heap. Ведь все содержимое файла будет вначале сохранено в памяти.</p>
<p>Способа полностью обойти эту коварную особенность, похоже, нет. Прелесть URLConnection&#8217;а заключается в том, что он позволяет неявно использовать настройки прокси пользователя. То есть, он идеален для апплетов: нет необходимости подписывать апплет, нет необходимости просить пользователя: &#8220;выбирите прокси, его тип, введите логин и пароль&#8221;. Большинство конечных пользователей просто закроют окно, появись такой диалог на экране.</p>
<p>Если прокси не является проблемой, можно использовать HTTPClient или написать &#8220;мини HTTP&#8221; используя &#8220;чистый&#8221; сокет, как показал Rex Young: </p>
<pre><code>
URI uri = new URI("http://localhost:8080/FullDuplexHttp/");
Socket socket = new Socket(uri.getHost(), uri.getPort());
OutputStream out = socket.getOutputStream();
out.write(("POST " + path + " HTTP/1.1\r\n").getBytes());
out.write("User-Agent: FullDuplexHttp\r\n".getBytes());
out.write(("Host: " + host + ":" + port + "\r\n").getBytes());
out.write("Transfer-Encoding: chunked\r\n".getBytes());
out.write("\r\n".getBytes());

// Теперь можно отправлять данные
</code></pre>
<p>Или же использовать пул открытых подключений к серверу и использовать одно подключение для отправки одного сообщения. IMHO этот вариант легко убьет сервер количеством бесполезных соединений.</p>
<p>Вот полезные ссылки по теме для интересующихся:<br />
<a href="http://www.innovation.ch/java/HTTPClient/fullduplex.html">http://www.innovation.ch/java/HTTPClient/fullduplex.html</a> &#8211; описание области проблемы и вариантов рещения &#8211; довольно интересное чтиво.<br />
<a href="http://weblogs.java.net/blog/rexyoung/archive/2008/09/turn_a_http_con_1.html">http://weblogs.java.net/blog/rexyoung/archive/2008/09/turn_a_http_con_1.html</a> &#8211; блог Rex Young, который реализовал этот функционал, используя сокеты и chunked transfer encoding.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2009/02/02/post-surprize/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Не верьте кодогенераторам,</title>
		<link>http://voituk.kiev.ua/2009/01/05/ne-verte-kodogeneratoram/</link>
		<comments>http://voituk.kiev.ua/2009/01/05/ne-verte-kodogeneratoram/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 09:57:20 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=901</guid>
		<description><![CDATA[или история одного маленького и противного бага. Сегодня убил некоторое время, отлавливая мерзкий баг. Баг был наглядно продемонстрирован юнит тестом, который, помимо всего прочего, проверял два объекта на эквивалентность. Сами объекты &#8211; простые java-бины с парой полей &#8211; одно типа int, второе типа String[][]. Код для equals и hashCode поручил сгенерировать eclipse&#8217;у. Подвох оказался в [...]]]></description>
			<content:encoded><![CDATA[<p><strong>или история одного маленького и противного бага.</strong></p>
<p>Сегодня убил некоторое время, отлавливая мерзкий баг. Баг был наглядно продемонстрирован юнит тестом, который, помимо всего прочего, проверял два объекта на эквивалентность. Сами объекты &#8211; простые java-бины с парой полей &#8211; одно типа int, второе типа String[][]. Код для equals и hashCode поручил сгенерировать eclipse&#8217;у. Подвох оказался в том, что метод equals попросту не работал &#8211; он всегда возвращал false. При детальном рассмотрении проблема нашлась: </p>
<pre><code class="java">if (!Arrays.equals(fieldTwo, other.fieldTwo))
	return false;
</code></pre>
<p>Все ведь просто, Arrays.equals сравнивает типы массива и количество элементов в каждом из них. Затем проверяет эквивалентность поэлементно. Первые две проверки проходят, а вот третья проваливается с треском. Ведь никакие два объекта-массива в java не эквиваленты:</p>
<pre><code class="java">System.out.println(new int[]{1}.equals(new int[]{1})) // Выведет false.
</code></pre>
<p>Для проверки эквивалентности многомерных массивов нужно использовать метод deepEquals, который, кстати, находится в том же классе Arrays. </p>
<p>Ради интереса я попробовал сгенерировать код equals и hashCode в IntelliJ IDEA. Idea отказалась учитывать многомерный массив при создании кода equals. По крайней мере, это честнее, чем создавать нерабочий код.</p>
<p>Учитывайте эти грабли, когда в следующий раз будете нажимать кнопочку кодогенератора.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2009/01/05/ne-verte-kodogeneratoram/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Java in a Cloud</title>
		<link>http://voituk.kiev.ua/2008/12/26/running-java-in-a-cloud/</link>
		<comments>http://voituk.kiev.ua/2008/12/26/running-java-in-a-cloud/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 13:49:25 +0000</pubDate>
		<dc:creator>Vadim Voituk</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=891</guid>
		<description><![CDATA[Пока прогрессивное мировое ИТ-сообщество самозабвенно обсуждает особенности трендового термина cloud-computing, массово уговаривает Google сделать поддержку Java&#38;Groovy в Google App Engine, гадает будет или не будет в GAE поддержка Perl-а, небольшая компания из Вашингтона представила миру свое понимание cloud-computing в Java-мире. Речь идет о компании Stax Networks, 16 декабря уходящего года запустившей под лозунгом &#8220;Java applications [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://voituk.kiev.ua/wp-content/uploads/2008/stax.png" alt="" hspace="5" vspace="5" align="left" />Пока прогрессивное мировое ИТ-сообщество <a rel="nofollow" href="http://google.com/trends?q=Cloud+Computing">самозабвенно</a> обсуждает особенности трендового термина cloud-computing, массово <a href="http://voituk.kiev.ua/2008/04/14/java-groovy-on-google-appspot/">уговаривает Google сделать поддержку Java&amp;Groovy в Google App Engine</a>, гадает будет или не <a href="http://voituk.kiev.ua/2008/07/24/google-app-engine-perl-support/">будет в GAE поддержка Perl-а</a>, небольшая компания из Вашингтона представила миру свое понимание cloud-computing в Java-мире.</p>
<p>Речь идет о компании<a href="http://www.stax.net/"> Stax Networks</a>, 16 декабря уходящего года запустившей под лозунгом <em>&#8220;Java applications in the cloud&#8221;</em> свой аналог Google App Engine для Java-разработчиков, который предоставляет завершенную инфраструктуру для разработки, тестирования и развертывания масштабируемых Java WEB-приложений.</p>
<p>Технически решение Stax построено поверх Amazon EC2 и позволяет создавать приложения основанные Servlets/JSP, Struts, GWT, Wicket, JRuby, Jython, Flex, ColdFusion.<br />
В качестве СУБД в данный момент поддерживается только MySQL.</p>
<p>Инфраструктура Stax построена так, чтоб разработчику на этапе написания кода не нужно было думать о том, что находится на уроверь ниже чем Stax.<br />
Управление приложениями и базами данных производится через удобную web-консоль, а локальная разработка и отладка производится привычными методами (я использовал для этого Eclipse и консольную утилиту stax).</p>
<p>Чем ещё интересен данный стартап &#8211; так это то, что в данный момент они не взымают плату за использование, аргументируя это тем, что вырабатываю правильную бизнесс-модель.<br />
В итоге попробовать Stax в действии, в отличии от аналогов, можно абсолютно бесплатно и даже не имея кредитной карты.</p>
<p>Что я собственно уже и сделал: написал небольшое <a href="http://jabber2twitter.vadim.staxapps.net/">приложение, которое выводит список контактов из БД</a> и запустил его в cloud-е на 2х серверах.<br />
Под заголовком &#8220;Running Java in Cloud&#8221; можно увидеть IP и имя сервера в cloud-e, который обслуживает текущий запрос. И если понажимать F5 &#8211; можно заметить, что серверов всего-то 2.</p>
<p>В принципе идея предоставления Platform-as-a-Service (PaaS) далеко не новая, но более или менее популярных решений для Java мне пока не встречалось.</p>
<p>Аналогичные разработки:</p>
<ul>
<li><a rel="nofollow" href="http://code.google.com/appengine/">Google App Engine</a> (GAE) &#8211; самый известный из подобных app-хостингов.<br />
Пока поддерживает только Python и хранение данных в нереляционной БД Google BigTable.</li>
<li><a rel="nofollow" href="http://www.microsoft.com/azure/">Microsoft Azure</a> &#8211; аналогичный GAE сервис от Microsoft. Поддерживает .NET языки.</li>
<li><a rel="nofollow" href="http://www.salesforce.com/platform/">Salesforce.com</a> &#8211; CRM-хостинг для приложений написанных на проприетарном языке Apex</li>
<li><a rel="nofollow" href="http://heroku.com/">Heroku</a> &#8211; аналог Stax, построенный на Amazon EC2, но для RubyOnRails приложений</li>
<li><a rel="nofollow" href="http://www.10gen.com/">10Gen</a> &#8211; ещё одна платформа, поддерживающая Python, Ruby и ServerSide JavaScript, а также обьекную СУБД Mongo.</li>
</ul>
<p>P.S. В комплекте со Stax SDK идет Groovy древней версии 1.5.6</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2008/12/26/running-java-in-a-cloud/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Simple &amp; Reliable Java HTTP-server</title>
		<link>http://voituk.kiev.ua/2008/12/22/simple-reliable-java-http-server/</link>
		<comments>http://voituk.kiev.ua/2008/12/22/simple-reliable-java-http-server/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 11:43:15 +0000</pubDate>
		<dc:creator>Vadim Voituk</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=886</guid>
		<description><![CDATA[Думаю никто не будет спорить с тем, что на данный момент HTTP является самым популярным высокоуровневым сетевым протоколом. Как следствие, все больше и больше приложений используют его для организации сетевых коммуникаций, и все больше и больше приложений содержат в себе функционал примитивного HTTP-сервера. Вариантов, как встроить в свое приложение небольшой HTTP-сервер уйма &#8211; начиная от [...]]]></description>
			<content:encoded><![CDATA[<p>Думаю никто не будет спорить с тем, что на данный момент HTTP является самым популярным высокоуровневым сетевым протоколом.<br />
Как следствие, все больше и больше приложений используют его для организации сетевых коммуникаций, и все больше и больше приложений содержат в себе функционал примитивного HTTP-сервера.</p>
<p>Вариантов, как встроить в свое приложение небольшой HTTP-сервер уйма &#8211;<br />
начиная от аскетичного и сложно-развиваемого <a href="http://voituk.kiev.ua/2007/08/26/simple-http-server-in-10-lines-of-groovy-code-en/">10-ти строчного HTTP-сервера на Groovy</a>, заканчивая <a href="http://voituk.kiev.ua/2008/05/26/embedded-fever/" rel="bookmark">интеграцией в приложение небольшого сервлет-контейнера Jetty</a>.</p>
<p>Я же хочу предложить что-то среднее между этими двумя вариантами.<br />
Начиная с 6й версии, в составе JRE поставляется пакет &#8220;com.sun.net.httpserver&#8221;, который содержит реализацию достаточно производительного и гибкого HTTP-сервера, построенного на асинхронной технологии NIO.</p>
<p>С его использованием код самого простого HTTP-сервера умещается в 30 строк Java-кода:</p>
<pre><code class="java">
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class HttpServerEx implements HttpHandler {

	public static void main(String[] args) throws IOException {
		HttpServer server = HttpServer.create(new InetSocketAddress(80), 10);
		server.createContext("/", new HttpServerEx());
		server.start();
		System.out.println("Server started\nPress any key to stop...");
		System.in.read();
		server.stop(0);
		System.out.println("Server stoped");
	}

	@Override
	public void handle(HttpExchange exc) throws IOException {
		exc.sendResponseHeaders(200, 0);
		PrintWriter out = new PrintWriter(exc.getResponseBody());
		out.println( "Hello moto!" );
		out.close();
		exc.close();
	}

}
</code></pre>
<p>Теперь, думаю, никому не составит труда расширить метод handle() под свои нужды.</p>
<p>Более подробную документацию можно найти тут: <a href="http://java.sun.com/javase/6/docs/jre/api/net/httpserver/spec/overview-summary.html" rel="nofollow">Javadoc пакета &#8220;Java™ HTTP Server&#8221;</a></p>
<p>К сожалению исходный код пакета доступен только как часть <i>Standard Edition Development Kit Source Release</i> под <i>Java Research License</i>, что вынуждает немного &#8220;попотеть&#8221; чтоб его добыть.</p>
<p>P.S. За наводку спасибо <a href="http://twitter.com/dima767">Dmitriy Kopylenko</a> и его ссылке на реализацию подобного HTTP-сервера на Scala.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2008/12/22/simple-reliable-java-http-server/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>The power of 4k</title>
		<link>http://voituk.kiev.ua/2008/11/27/the-power-of-4k/</link>
		<comments>http://voituk.kiev.ua/2008/11/27/the-power-of-4k/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 09:25:19 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://voituk.kiev.ua/?p=842</guid>
		<description><![CDATA[Уже много-много времени я увлекаюсь разработкой игр на Java. Да что тут говорить, мое первое приложение на Java была мини-игра для мобильного телефона Siemens M55, моя первая постоянная &#8220;программистская&#8221; работа была тоже связана разработкой игрушек на Java. Эта заметка посвящена ежегодному событию, которое проходит по инициативе www.javagaming.org &#8211; состязанию Java 4k. Правила очень простые &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Уже много-много времени я увлекаюсь разработкой игр на Java. Да что тут говорить, мое первое приложение на Java была мини-игра для мобильного телефона Siemens M55, моя первая постоянная &#8220;программистская&#8221; работа была тоже связана разработкой игрушек на Java.</p>
<p>Эта заметка посвящена ежегодному событию, которое проходит по инициативе <a href="http://www.javagaming.org/">www.javagaming.org</a> &#8211; состязанию Java 4k. Правила очень простые &#8211; необходимо сделать интересную игру на Java, так чтобы размер архива (jar) с игрой (и всеми ресурсами) не привышал 4 килобайта. Трюки вроде &#8220;напишу-ка я на 4 кб загрузчик, который подтянет с сайта мой 50-мегабайтный движок&#8221; не проходят.<br />
Естественный вопрос: &#8220;что, черт побери, можно написать на 4 килобайта?&#8221;. Чтобы на него ответить достаточно взглянуть на игрушки прошлых лет:</p>
<p>Победитель прошлого года, простая, но интересная аркада:</p>
<table border="0" align="left">
<tr>
<td><img src="http://voituk.kiev.ua/wp-content/uploads/2008/11/spiderball.png" alt="" title="spiderball" align="left" /></td>
<td> <a href="http://java4k.com/index.php?action=games&#038;method=view&#038;gid=185">Spiderball4k</a></td>
</tr>
<tr>
<td><img src="http://voituk.kiev.ua/wp-content/uploads/2008/11/t4kns.png" alt="" title="t4kns" align="left"/></td>
<td>
А эта игра потрясет любого:  изометрическая Real-Time стратегия, где есть разные юниты, можно строить здания, добывать ресурсы и воевать с AI! Комментарий к этой работе с форума javagaming выражает основную мысль как нельзя лучше: &#8220;Hey, where did you put other 100k?!&#8221;<br/> <a href="http://java4k.com/index.php?action=games&#038;method=view&#038;gid=182">T4anks</a></td>
</tr>
</table>
<p>Есть еще множество интересных игр. В этом году я думаю присоединиться к соревнованию. Надеюсь, времени хватит.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2008/11/27/the-power-of-4k/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

