<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Java и J2EE разработка</title>
	<atom:link href="http://ynovikov.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://ynovikov.wordpress.com</link>
	<description>Рабочий блог Юрия Новикова</description>
	<lastBuildDate>Sun, 15 Jan 2012 23:02:19 +0000</lastBuildDate>
	<language>ru</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='ynovikov.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Java и J2EE разработка</title>
		<link>http://ynovikov.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://ynovikov.wordpress.com/osd.xml" title="Java и J2EE разработка" />
	<atom:link rel='hub' href='http://ynovikov.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Reverse Ajax Chat</title>
		<link>http://ynovikov.wordpress.com/2011/03/24/reverse-ajax-chat/</link>
		<comments>http://ynovikov.wordpress.com/2011/03/24/reverse-ajax-chat/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 05:36:44 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[J2EE]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[asynchronous servlet]]></category>
		<category><![CDATA[chat]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[асинхронный сервлет]]></category>
		<category><![CDATA[чат]]></category>
		<category><![CDATA[reverse ajax]]></category>
		<category><![CDATA[servlet 3.0]]></category>
		<category><![CDATA[tomcat 7]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=83</guid>
		<description><![CDATA[Пример построения простейшего чата на основе асинхронных сервлетов (Servlet 3.0, Tomcat 7.0, JQuery) и использования Reverse Ajax (a.k.a Comet, Server Push etc.)<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=83&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">Не так давно был релиз Tomcat 7.0, где в полной мере реализована поддержка Servlet 3.0. Одно из наиболее интересных нововведений &#8211; это поддержка асинхронных сервлетов (asynchronous servlets), что в полной мере позволяет нам реализовать технологию Reverse AJAX.</p>
<p style="text-align:justify;">Если вкратце, то суть ее в том, что клиент открывает долгоживущее HTTP-соединение, которое хранится на сервере до того момента, пока сервер не будет готов отослать ответ обратно. Посылка ответа инициируется сервером (поэтому это и называется AJAX наоборот). Такой подход позволяет избавиться от многократного опроса сервера множеством клиентов с целью получить как можно более свежую информацию. Например, такой сценарий имеет место в онлайн аукционах, разного рода службах информирования об изменении курса акций, чатах и т.д. Суть в том, что момент обновления информации неизвестен, но все хотят получить ее как можно быстрее после опубликования, поэтому начинают бомбить сервер запросами с большой частотой в надежде не пропустить обновление информации на сервисе. Как это влияет на производительность, думаю рассказывать не надо &#8211; имеем вполне себе DoS-атаку. Reverse AJAX избавляет нас от необходимости все время опрашивать сервер &#8211; соединение открывается один раз, и потом сервер сам отошлет ответ, когда будет что отсылать. Естесственно, когда с сервера придет ответ, нужно установить соединение заново.</p>
<p style="text-align:justify;">Обзоры этого уже есть в интернете, их можно почитать <a href="http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html">тут</a>, <a href="http://en.wikipedia.org/wiki/Comet_%28programming%29">тут </a>и <a href="http://en.wikipedia.org/wiki/Reverse_Ajax">тут</a>. Теории хватает, но я так и не смог найти ни одного работаюшего примера. Куски кода конечно встречались, но увы, я так и не нашел, где можно скачать и посмотреть работающий пример. Итак, исправляем ситуацию и пишем простейший онлайн-чат с использованием Asynchronous Servlets.</p>
<p style="text-align:justify;">Класс сообщения:</p>
<p><pre class="brush: java;">
public class Message {

	public final String message;
	public final String username;

	public Message(final String message, final String username) {
		this.message = message;
		this.username = username;
	}
}
</pre></p>
<p style="text-align:justify;">Сам сервлет:</p>
<p><pre class="brush: java;">
@WebServlet(name = &quot;chatServlet&quot;, urlPatterns = { &quot;/chat&quot; }, asyncSupported = true)
public class ChatServlet extends HttpServlet {

	@Override
	protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
		AsyncContext aCtx = req.startAsync(req, resp);
		aCtx.setTimeout(1000*60*5L); //5 min timeout
		ServletContext servletContext = req.getServletContext();
		((Queue&lt;AsyncContext&gt;)servletContext.getAttribute(&quot;chatUsers&quot;)).add(aCtx);
	}

	@Override
	protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
		AsyncContext aCtx = req.startAsync(req, resp);
		ServletContext servletContext = req.getServletContext();
		String message = req.getParameter(&quot;message&quot;);
		String username = req.getParameter(&quot;username&quot;);
		Queue&lt;Message&gt; msgQueue = (Queue&lt;Message&gt;) servletContext.getAttribute(&quot;messages&quot;);
		msgQueue.add(new Message(message, username));
		aCtx.complete();
	}

}
</pre></p>
<p style="text-align:justify;">Hаша служба асинхронных сообщений, которая будет проверять, не пришло ли чего нового и отсылать пришедшее сообщение зарегистрированным адресатам:</p>
<p><pre class="brush: java;">
@WebListener
public class ChatService implements ServletContextListener {

	@Override
	public void contextDestroyed(final ServletContextEvent sce) {

	}

	@Override
	public void contextInitialized(final ServletContextEvent sce) {

		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				final Queue&lt;AsyncContext&gt; chatUsers = new ConcurrentLinkedQueue&lt;AsyncContext&gt;();
				sce.getServletContext().setAttribute(&quot;chatUsers&quot;, chatUsers);

				Queue&lt;Message&gt; messages = new ConcurrentLinkedQueue&lt;Message&gt;();

				sce.getServletContext().setAttribute(&quot;messages&quot;, messages);

				Executor messageExecutor = Executors.newCachedThreadPool();
				final Executor chatExecutor = Executors.newCachedThreadPool();

				while (true) {
					if (!messages.isEmpty()) {
						final Message message = messages.poll();
						messageExecutor.execute(new Runnable() {
							@Override
							public void run() {
								while(!chatUsers.isEmpty()) {
									final AsyncContext aCtx = chatUsers.poll();
									chatExecutor.execute(new Runnable() {
										@Override
										public void run() {
											try {
												ServletResponse response = aCtx.getResponse();
												response.setContentType(&quot;text/xml&quot;);
												response.getWriter().write(messageAsXml(message));
												aCtx.complete();
											} catch (IOException e) {
												e.printStackTrace();
											}
										}

										private String messageAsXml(final Message message) {
											StringBuffer sb = new StringBuffer();
											sb.append(&quot;&lt;message&gt;&quot;)
											.append(&quot;&lt;username&gt;&quot;)
											.append(message.username)
											.append(&quot;&lt;/username&gt;&quot;)
											.append(&quot;&lt;text&gt;&quot;)
											.append(message.message)
											.append(&quot;&lt;/text&gt;&quot;)
											.append(&quot;&lt;/message&gt;&quot;);
											return sb.toString();
										}
									});
								}
							}
						});
					}
				}
			}
		});

		t.start();
	}
}
</pre></p>
<p style="text-align:justify;">Ну и страничка чата собственно. Используется JQuery. Как видно, никакой разницы с точки зрения JQuery между Reverse AJAX и просто АJAX нет:</p>
<p><pre class="brush: xml;">

&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
&lt;title&gt;Servlet 3.0 example&lt;/title&gt;
&lt;script src=&quot;js/jquery-1.5.1.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script&gt;
	$(document).ready(function(){
		function getData() {
			$.ajax({
				  url: &quot;chat&quot;,
				  type: &quot;GET&quot;,
				  dataType: &quot;xml&quot;,
				  context: document.body,
				  success: function(data){
					var username = $(data).find('username').text();
					var text = $(data).find('text').text();
					var history = $('#chat_msgs').text();
				    $('#chat_msgs').html(history + username + &quot;: &quot; + text + &quot;\n&quot;);
				    getData();
				  }
			});
		}
		$(&quot;#sendMsg&quot;).click(function(event){
		     $.post(&quot;chat&quot;, $(&quot;#msgForm&quot;).serialize());
		     $('#message').val('');
		});

		getData();
	});
&lt;/script&gt;
&lt;h3&gt;Asynchronous Servlet 3.0 Based Reverse Ajax Chat&lt;/h3&gt;
&lt;textarea cols=&quot;60&quot; rows=&quot;5&quot; id=&quot;chat_msgs&quot; name=&quot;chat_msgs&quot;&gt;&lt;/textarea&gt;
&lt;br/&gt;
&lt;form id=&quot;msgForm&quot; name=&quot;msgForm&quot;&gt;
	Username: &lt;input type=&quot;text&quot; id=&quot;username&quot; name=&quot;username&quot; value=&quot;&quot; /&gt;
	Message: &lt;input type=&quot;text&quot; id=&quot;message&quot; name=&quot;message&quot; value=&quot;&quot; /&gt;
&lt;/form&gt;
&lt;br/&gt;
&lt;input type=&quot;submit&quot; id=&quot;sendMsg&quot; name=&quot;sendMsg&quot; value=&quot;Send message&quot; /&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre></p>
<p style="text-align:justify;">Вот так это выглядит в действии:</p>
<p style="text-align:justify;"><a href="http://ynovikov.files.wordpress.com/2011/03/reverse_ajax_chat.png"><img class="aligncenter size-full wp-image-87" title="reverse_ajax_chat" src="http://ynovikov.files.wordpress.com/2011/03/reverse_ajax_chat.png?w=450&#038;h=346" alt="" width="450" height="346" /></a></p>
<p style="text-align:justify;">Сразу хочу сказать, что это минимально возможный рабочий вариант. Здесь нет много чего важного, например, обработки ответа сервера по истечении таймаута, обработки ошибок и т.д. Но всё это можно прочитать в специфииации Servlets 3.0. Архив с кодом можно скачать <a href="http://www.filesavr.com/JDBJ1W133EMA5EW">здесь</a>. Проект распаковать, импортировать в Eclipse, деплоить на Tomcat 7.0. Проверено в Opera 11, FF4, Chrome 10, работает без нареканий. IE как всегда на высоте &#8211; завис намертво. Если после прочтения статей по теории в интернете не совсем понятно, что и зачем тут нужно, пишите в коменты, будем обсуждать.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/83/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=83&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2011/03/24/reverse-ajax-chat/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>

		<media:content url="http://ynovikov.files.wordpress.com/2011/03/reverse_ajax_chat.png" medium="image">
			<media:title type="html">reverse_ajax_chat</media:title>
		</media:content>
	</item>
		<item>
		<title>Effective Testing</title>
		<link>http://ynovikov.wordpress.com/2011/02/24/effective-testing/</link>
		<comments>http://ynovikov.wordpress.com/2011/02/24/effective-testing/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 20:47:38 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=78</guid>
		<description><![CDATA[In this blog post I’m going to talk about testing, or more precisely, what makes testing effective. Probably every developer nowadays knows that certain test coverage is required, but not everybody has a clear understanding how to make these tests really effective and helpful.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=78&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Писалось для корпоративного блога, поэтому на английском. Движок блога коряв, поэтому форматирование текста слетает с завидным упорством. Если кому-то захочется версию, годную для печати, можно взять по ссылке <a href="http://ynovikov.files.wordpress.com/2011/02/effective-testing.docx">Effective Testing</a>.</p>
<h2><strong>Effective Testing</strong></h2>
<p>In this blog post I’m going to talk about testing, or more precisely, what makes testing effective. Probably every developer nowadays knows that certain test coverage is required, but not everybody has a clear understanding how to make these tests really effective and helpful.<br />
If one is asked what are tests for, the answer usually is: “They verify that my code works”. This is true but is not everything about it. This mentality usually drives people to write their tests after the actual code is complete just to make sure that it can run and does something. This is better than nothing but still not as good as it could be. There’re several reasons for that.<br />
First, if a developer writes the test after writing the code, he/she has never had the chance to see the test fail and then subsequently pass (once the code is written).  Never seeing a test fail may mean that it is just working by coincidence. The developer sees the green bar and assumes everything is good, but that green bar is actually masking a bug.<br />
Second, it’s not a rare case that the written code is not testable. That is, it can have lots of dependencies that make it very hard to write a good test case for it, so if somebody wants to test it, he/she will have to spend quite an amount of time breaking these dependencies (but quite often people just give up on that and live with the code being completely untested).<br />
Third, this approach leads to a trouble when a code base grows over a certain size. Developers can easily forget to update some test cases or fix the failing tests in an inappropriate way just to make them pass. This makes a test codebase rot which is a huge problem. After a while the amount of effort that one has to spend to keep a rotten test code base in sync with the actual system will be more then he/she has to spend on the actual code changes and after a while it can slow down the whole process so much that a team will have to abandon their  tests completely. This means that they are in big trouble. Now they can’t be sure that their changes do not break anything, so no refactoring can be done and they have to do manual regression testing after each change.<br />
Last but not least – by writing tests after the code you usually test just methods but not behaviour. This is not effective because tests should focus on a valuable behaviour that the class under tests provides. So one needs to test the features of the code to make sure that it works as expected and can be used efficiently in collaboration with its clients instead of just covering all methods with tests one by one &#8211; quite often you need to call several methods of your class in a row to collaborate with other objects.<br />
On the other hand, if you write tests first by following the TDD principles you get a whole bunch of benefits: first, you give up on treating your tests just as something that verifies your code. Your tests become a runnable specification that describes what your code does and not how it does it. That is, you start thinking in terms of features and this helps us to maintain a necessary level of abstraction.<br />
Test first also makes the test readable and maintainable – you think about a certain scenario and this allows you to keep your test clean from unnecessary details. Writing tests first also enforces you to think about the dependencies. Because you  have to pass all the dependencies to the object under test you will get a clear indicator as you are coding that your design is bad. Another indicator is if your test becomes too large and complicated – this points you to the fact that the class under test is doing too much and has too many responsibilities and you probably need to decompose it.<br />
So what should you do to make your test code base effective and helpful besides writing your tests first? There’re several best practices and pieces of advice that can be used. This is not the complete list of course, but it will show you the way to go.<br />
The key factor that makes your tests effective is their readability. If the test is easy to read it is easy to maintain it. This means that you should apply the same code standards to your test code as you apply for production code. You should not treat the test as something that can be written in a mess. Follow the common clean code rules: no magic numbers, good and explanatory variable naming, no nested if-s, etc. Please refer to [1] as a great guide how to write clean and readable code. If you do not follow these standards, it’s just a matter of time until the test codebase starts to rot.<br />
Test methods should be small, ideally 10-15 lines and contain just a few asserts (ideally one). It should be very clear what the test does and what atomic scenario is being executed. If your test is long and has lots of assertions inside you will have to spend a lot of time just figuring out what it actually does. Also, the test method should have a very clear and descriptive name that states what feature is being tested:<br />
<span style="color:#ff0000;">public void testCheckout1() // NO</span><br />
<span style="color:#008000;">public void testCheckoutWithOneCartItemAndDiscountAppliedGivesFreeShipping() //YES</span><br />
Don’t be afraid of long method names – you are not going to call these methods anywhere, but you will be able to understand what kind of scenario is being tested at a glance.<br />
Do not duplicate creation of test objects inside your tests – use test object builders that will help you easily create and maintain families of such object instead [2, 3]. By using the builders you will greatly increase readability and remove duplication from your tests. An example can look like following:</p>
<p><pre class="brush: java;">

List movies = Arrays.asList(
MovieBuilder.movie().withTitle(&quot;Blade Runner&quot;)       // &amp;lt;- here's the builder being used
.withAddedActor(&quot;Harrison Ford&quot;)
.withAddedActor(&quot;Rutger Hauer&quot;)
.build(),
MovieBuilder.movie().withTitle(&quot;Star Wars&quot;)          // &amp;lt;- ... and also here
.withAddedActor(&quot;Carrie Fisher&quot;)
.withAddedActor(&quot;Harrison Ford&quot;)
.build());

</pre></p>
<p>There’s an Eclipse plugin called “Fluent Builders” that allows you to generate these builders automatically from any class you wish and saves your time greatly [4].</p>
<p>All of your test should have the same canonical structure:<br />
1) Setup (prepare context and environment);<br />
2) Execution (trigger the tested behaviour);<br />
3) Verification (check that results are what we expect);<br />
4) Teardown (clean up everything that can influence other tests and release all resources)<br />
This means that all the tests should be completely independent from each other. This is very important, because if you have chained tests and the first test in the chain fails – all other tests will also fail. This is really bad because your test code base becomes very brittle and uninformative – you don’t know if tests are failing because of chaining or because of incorrect behaviour of the code that’s under test. So make your tests completely decoupled and independent.<br />
Do not load data from hardcoded location in the file system, this will ensure that your test suite can be run in different environments under different operation systems and this will increase the maintainability of the test suite.</p>
<p><span style="color:#ff0000;">/home/ynovikov/workspace/project/src/test/resources/config.properties //NO. Absolute path is used</span><br />
<span style="color:#008000;">../test/resources/config.properties //YES. Relative path is used</span></p>
<p>Always use explanatory assertion messages, so that you can easily understand the reason of failure.<br />
<strong>assertEquals(“Price discount hasn&#8217;t been applied”, expectedPrice, actualPrice);</strong><br />
Assertions should be precise &#8211; assert only those results that are triggered by test scenario and are not covered by other tests. This will make your test bas more robust.<br />
Try to use mocks only for something that you can’t change, don’t use them as stubs. There’s a good article by M. Fowler about that [5].<br />
Make sure that the code under test satisfies SOLID principles [6]. If you do that together with writing your test first, you are very likely to get the code that is easier to test, change and maintain.<br />
Very important: your tests (not only unit, but acceptance and integration tests as well) should be fully automated so that you can make running your test as a part of continuous integration process. This will ensure that your build is always in a good and working state.<br />
One more thing to remember – effective unit tests should be fast. This will allow you to execute them very often, may be after every single change you make to the code. This will provide you fast feedback if your changes broke something so that you can very quickly locate and fix the newly introduced bug.<br />
If you start developing a user story, write acceptance test(s) first and don’t forget to follow TDD when you start implementing the feature itself. Each acceptance test suite should include a happy path scenario (when everything works as expected) and tests for cases when something goes wrong or for alternative behaviour.<br />
Write integration tests to ensure that your code works correctly with some third-party libraries or services that you can’t change. All integration points with such things like payment gateways, geoip providers, persistent mechanisms etc. should be covered by integration tests.<br />
If you’ve just started a project from scratch, the first thing you should do is to build a “walking skeleton” – the minimal possible configuration of your product that can be built, deployed and tested in a continuous integration environment against all kind of tests (unit, acceptance, integration). For example, if you develop a web application, it can just show you a page that reads a couple of records from database and displays them (and you create all kinds of tests for this functionality). This will ensure that your test environment and test frameworks are up and running, so that you can be sure that they are working correctly and ready for serious work.<br />
I hope this article has been helpful, but don’t forget to check out the books and links in the list below. I have found them extremely useful and I hope you do too.<br />
<strong>Bibliography and references:</strong><br />
1. “Clean Code: A Handbook of Agile Software Craftsmanship” by Robert C. Martin;<br />
2. “Growing Object-Oriented Software, Guided by Tests” by Steve Freeman, Nat Pryce;<br />
3. http://www.betriebsraum.de/blog/2010/02/08/better-tests-with-test-data-builders/;<br />
4. http://code.google.com/p/fluent-builders-generator-eclipse-plugin/;<br />
5. http://martinfowler.com/articles/mocksArentStubs.html;<br />
6. http://en.wikipedia.org/wiki/Solid_(object-oriented_design)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/78/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=78&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2011/02/24/effective-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>
	</item>
		<item>
		<title>[Scala] By-name parameters</title>
		<link>http://ynovikov.wordpress.com/2010/02/28/scala-by-name-parameters/</link>
		<comments>http://ynovikov.wordpress.com/2010/02/28/scala-by-name-parameters/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 01:14:44 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[by-name parameters]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=72</guid>
		<description><![CDATA[Еще одна интересная конструкция в Scala &#8211; by-name parameters. Эта конструкция позволяет реализовать отложенные вызовы &#8211; до тех пор, пока в теле основной функции не произойдет обращение к функции, переданной как by-name parameter, она вычисляться не будет. Пример: пусть у нас есть некоторая функция, которая проводит расчет и выводит на печать результат неких вычислений, если соответствующий флаг [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=72&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">Еще одна интересная конструкция в Scala &#8211; by-name parameters. Эта конструкция позволяет реализовать отложенные вызовы &#8211; до тех пор, пока в теле основной функции не произойдет обращение к функции, переданной как by-name parameter, она вычисляться не будет. Пример: пусть у нас есть некоторая функция, которая проводит расчет и выводит на печать результат неких вычислений, если соответствующий флаг установлен в true. В интерпретаторе Scala набираем следующие строки:</p>
<div id="_mcePaste">var enabled = true</div>
<div id="_mcePaste">def doCalc(predicate: Int) = if (enabled) println(predicate)</div>
<p style="text-align:justify;">Кстати, тут можно увидеть и замыкание &#8211; функция doCalc обращается к переменной enabled, которая не является ее аргументом, но находится в контексте выполнения. Можно попробовать запустить нашу функцию:</p>
<p>scala&gt; doCalc(5+5)<br />
10</p>
<p>Если установить enabled в false, то ничего на печать не выведется:</p>
<p>scala&gt; enabled = false<br />
enabled: Boolean = false</p>
<p>scala&gt; doCalc(5+5)</p>
<p style="text-align:justify;">Ничего на консоль не выведется, как и было задумано. Вроде бы, наш скрипт делает то, что мы от него хотим &#8211; если разрешено, печатает, если запрещено &#8211; нет. Однако, это не совсем так, в чем легко убедиться, запустив нашу функцию например так (не забыв при этом проверить, что enabled установлен в false):</p>
<p>scala&gt; doCalc(5/0)<br />
java.lang.ArithmeticException: / by zero<br />
at .(:7)<br />
at .()<br />
at RequestResult$.(:3)<br />
at RequestResult$.()<br />
at RequestResult$result()<br />
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br />
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br />
at sun.reflect.DelegatingMethodAcce&#8230;</p>
<p style="text-align:justify;">Как видим, значение передаваемой функции вычисляется уже при передаче ее как параметра, то есть происходит передача по значению вне зависимости от того, будем ли мы вообще обращаться к этой функции. Это нам не подходит, поскольку мы должны вычислять значение функции только тогда, когда  происходит собственно обращение к этому параметру. Тут и поможет передача параметров по имени. Модифицируем нашу функцию следующим образом:</p>
<p>def doCalc2(<strong>predicate: =&gt; Int</strong>) = if (enabled) println(predicate)</p>
<p>и выполним предыдущий вызов:</p>
<p>scala&gt; doCalc2(5/0)</p>
<p style="text-align:justify;">В этот раз значение функции не вычислится, потому что к параметру не обращались. Если установить enabled = true и запустить повторно, увидим знакомую картину &#8211; произошло обращение к параметру и вычислилось значение функции:</p>
<p>scala&gt; doCalc2(5/0)<br />
java.lang.ArithmeticException: / by zero<br />
at .(:7)<br />
at .()<br />
at RequestResult$.(:3)<br />
at RequestResult$.()<br />
at RequestResult$result()<br />
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br />
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br />
at sun.reflect.DelegatingMethodAcce&#8230;</p>
<p>Таким образом можно реализовывать отложенные(lazy) вызовы. Подробнее можно почитать <a href="http://programming-scala.labs.oreilly.com/ch08.html#_call_by_name_call_by_value">тут</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/72/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=72&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2010/02/28/scala-by-name-parameters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>
	</item>
		<item>
		<title>[Scala]Function currying</title>
		<link>http://ynovikov.wordpress.com/2010/02/28/scala-function-currying-%d0%ba%d0%b0%d1%80%d1%80%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5/</link>
		<comments>http://ynovikov.wordpress.com/2010/02/28/scala-function-currying-%d0%ba%d0%b0%d1%80%d1%80%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 00:11:09 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[Scala]]></category>
		<category><![CDATA[function currying]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=69</guid>
		<description><![CDATA[Вот эта тема меня поначалу сильно озадачила Что это такое, в принципе было понятно, не было понятно &#8211; а зачем оно мне надо? Итак, каррирование a.k.a function currying &#8211; что это? Если у нас есть некая функция с несколькими аргументами, то для получения ее значения нам необходимо передать ей значения всех аргументов. При применении каррирования [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=69&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Вот эта тема меня поначалу сильно озадачила <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Что это такое, в принципе было понятно, не было понятно &#8211; а зачем оно мне надо? Итак, </span></span><strong><span style="font-size:small;"><span style="font-family:verdana;">каррирование</span></span></strong><span style="font-size:small;"><span style="font-family:verdana;"> a.k.a </span></span><strong><span style="font-size:small;"><span style="font-family:verdana;">function currying</span></span></strong><span style="font-size:small;"><span style="font-family:verdana;"> &#8211; что это? Если у нас есть некая функция с несколькими аргументами, то для получения ее значения нам необходимо передать ей значения всех аргументов. При применении каррирования мы можем передать ей лишь некоторые из них, а в качестве результата получим функцию, принимающую оставшиеся аргументы. И если уже в эту функцию мы передадим остальные аргументы, то получим собственно результат. Названа техника в честь ее изобретателя, Хаскелла Карри. В некоторых случаях это позволяет уменьшить дублирование кода и упростить его переиспользование.</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">В качестве практического примера позаимствую хороший пример с вычислением налогов, желающие могут ознакомиться с оригиналом на аглицком <a href="http://joelneely.wordpress.com/2008/03/22/currying-without-lab-rats/">здесь</a>.</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Итак, у нас есть несколько штатов, в которых есть города. В каждом городе существует своя политика налогообложения, где сумма облагается налогом по одной ставке и плюс к этому, определенная ее часть облагается дополнительным налогом по другой ставке:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div>
<table style="text-align:justify;">
<tbody>
<tr>
<td><span style="font-size:small;"><span style="font-family:verdana;"><strong>Abbr. </strong></span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;"><strong>State </strong></span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;"><strong>City </strong></span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;"><strong>Tax computation</strong></span></span></td>
</tr>
<tr>
<td><span style="font-size:small;"><span style="font-family:verdana;">TF</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">Terrafirma</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">n/a</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">2% of the entire value</span></span></td>
</tr>
<tr>
<td><span style="font-size:small;"><span style="font-family:verdana;">TC</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">Terracotta</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">n/a</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">6% on the first $1500</span></span></td>
</tr>
<tr>
<td><span style="font-size:small;"><span style="font-family:verdana;">CF</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">Confusion</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">Gotham</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">5% on the entire value plus 4.5% on the first $1000</span></span></td>
</tr>
<tr>
<td><span style="font-size:small;"><span style="font-family:verdana;">CF</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">Confusion</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">Ocean City</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">5% on the entire value plus 3% on the first $1000</span></span></td>
</tr>
<tr>
<td><span style="font-size:small;"><span style="font-family:verdana;">CF</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">Confusion</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">Hometown</span></span></td>
<td><span style="font-size:small;"><span style="font-family:verdana;">5% on the entire value plus 1.5% on the first $1000</span></span></td>
</tr>
</tbody>
</table>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
</div>
<div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Сначала определим обобщенную функцию вычисления налогов:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def pct(rate: Double, amt: Long) = (rate * amt / 100.0D + 0.5D).toLong //helper function for rounded percentage calculation</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def tax(rateA: Double, limit: Long, rateB: Double, amt: Long) = pct (rateA, amt) + pct (rateB, limit min amt)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Теперь определим функции для вычисления налогов в каждом городе без применения каррирования:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def taxTF (amt: Long) = tax(2.0D, 0, 0.0D, amt)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def taxTC (amt: Long) = tax(0.0D, 150000, 6.0D, amt)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def taxGothamCF (amt: Long) = tax(5.0D, 100000, 4.5D, amt)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def taxOceanCityCF (amt: Long) = tax(5.0D, 100000, 3.0D, amt)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def taxHometownCF (amt: Long) = tax(5.0D, 100000, 1.5D, amt)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Дублирование видно сразу &#8211; передаются одинаковые аргументы сразу в нескольких местах. К тому же этот код не очень хорошо читаем, сразу и не понятно, что к чему относится. А теперь добавим карри. Общая функция вычисления налогов станет выглядеть так:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def tax = (rateA: Double) =&gt; (limit: Long) =&gt;</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">(rateB: Double) =&gt; (amt: Long) =&gt;</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">pct (rateA, amt) + pct (rateB, limit min amt)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Первые 2 функции вычисления налогов примут вид:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>def taxTF = tax( 2.0D)(0)(0.0D)</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>def taxTC = tax( 0.0D)(150000)(6.0D</em></span>)</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Здесь мы уже отделили мух от котлет &#8211; константы передаются в общую функцию, которая вернет нам функцию с одним аргументом. Вроде бы не особо на первый взгляд и необходимая вещь, однако это позволяет писать более структурированный код, где функции будут более специализированы. С остальными тремя все еще интереснее &#8211; там первые 2 аргумента дублируются, т.к. для штата процентные ставки и суммы одинаковы. Опрделим функцию налогообложения на уровне штата:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">def taxCF = tax(5.0D)(100000)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Теперь черз нее можно выразить города:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>def taxGothamCF = taxCF(4.5D)</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>def taxOceanCityCF = taxCF(3.5D) </em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>def taxHomeTownCF  = taxCF(1.0D)</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Для города Gotham налог будет таким:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">scala&gt; taxGothamCF(9999)</span></em></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><em><span style="color:#000066;">res0: Long =</span></em> 950</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Дублирования нет, каждая функция делает только то, что от нее требуется. Использовать можно например так &#8211; определим функцию отчетности:</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>def report(taxf: (Long =&gt; Long), amts: List[Long]) = {</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>println(&laquo;Tax on &raquo; + amts + &raquo; is &raquo; + taxf((amts :\ 0L)(_ + _)))</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>}</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>val items = List[Long](20000, 40000, 60000, 80000)</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em><br />
</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>scala&gt; report(taxHomeTownCF, items) </em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><span style="color:#000066;"><em>Tax on List(20000, 40000, 60000, 80000) is 11000</em></span></span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;"><br />
</span></span></div>
<div style="text-align:justify;"><span style="font-size:small;"><span style="font-family:verdana;">Что это даёт? В краткосрочной перспективе вобщем-то особенно ничего, но если нужно обеспечить гибкую функциональность, когда требования меняются часто, и нужно быстро и легко вносить изменения в код &#8211; то этот приём будет однозначно полезен. Кстати, налогообложение &#8211; как раз такая предметная область. Ставки и формулы там меняются весьма часто</span></span><span style="font-size:small;"><span style="font-family:verdana;">.</span></span></div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/69/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=69&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2010/02/28/scala-function-currying-%d0%ba%d0%b0%d1%80%d1%80%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>
	</item>
		<item>
		<title>Google Guice &#8211; вопрос к джавистам</title>
		<link>http://ynovikov.wordpress.com/2009/11/04/google-guice-%d0%b2%d0%be%d0%bf%d1%80%d0%be%d1%81-%d0%ba-%d0%b4%d0%b6%d0%b0%d0%b2%d0%b8%d1%81%d1%82%d0%b0%d0%bc/</link>
		<comments>http://ynovikov.wordpress.com/2009/11/04/google-guice-%d0%b2%d0%be%d0%bf%d1%80%d0%be%d1%81-%d0%ba-%d0%b4%d0%b6%d0%b0%d0%b2%d0%b8%d1%81%d1%82%d0%b0%d0%bc/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 19:14:53 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[1]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[guice]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/2009/11/04/google-guice-%d0%b2%d0%be%d0%bf%d1%80%d0%be%d1%81-%d0%ba-%d0%b4%d0%b6%d0%b0%d0%b2%d0%b8%d1%81%d1%82%d0%b0%d0%bc/</guid>
		<description><![CDATA[Будет ли интересна заметка по разбору этого фреймворка, с примерами? Недавно его как следует поковырял, если будет кому-нибудь интересно, напишу про него.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=68&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Будет ли интересна заметка по разбору этого фреймворка, с примерами? Недавно его как следует поковырял, если будет кому-нибудь интересно, напишу про него.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/68/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=68&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2009/11/04/google-guice-%d0%b2%d0%be%d0%bf%d1%80%d0%be%d1%81-%d0%ba-%d0%b4%d0%b6%d0%b0%d0%b2%d0%b8%d1%81%d1%82%d0%b0%d0%bc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>
	</item>
		<item>
		<title>Mentawai web framework</title>
		<link>http://ynovikov.wordpress.com/2009/11/01/mentawai-web-framework/</link>
		<comments>http://ynovikov.wordpress.com/2009/11/01/mentawai-web-framework/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 10:47:34 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=66</guid>
		<description><![CDATA[Так уж сложилось, что весь мой опыт работы связан с enterprise проектами, со всеми присущими им технологиями, соответственно любой web-проект воспринимается как нечто, содержащее в себе с полдесятка технологий, которые надо интегрировать и конфигурировать. Типовая связка &#8211; Spring+Hibernate+Spring MVC\Webflow. Только для того, чтобы запустить работающий скелет такой системы, необходимо написать весьма приличное количество конфигов, при [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=66&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">Так уж сложилось, что весь мой опыт работы связан с enterprise проектами, со всеми присущими им технологиями, соответственно любой web-проект воспринимается как нечто, содержащее в себе с полдесятка технологий, которые надо интегрировать и конфигурировать. Типовая связка &#8211; Spring+Hibernate+Spring MVC\Webflow. Только для того, чтобы запустить работающий скелет такой системы, необходимо написать весьма приличное количество конфигов, при этом хорошо, если четко помнишь что с чем интегрировать, какие бины создавать и где какой xml править, тогда может и уложишься в пару часов, а если последний раз такое делал давно, то смело можно убить на это полдня. Я уже молчу, что количество зависимостей будет весьма немалым &#8211; с десяток библиотек точно придется деплоить. Ну и конечно xml hell &#8211; я ненавижу писать xml конфиги. Из языка разметки данных xml превратили в еще один язык программирования, причем у каждого фреймворка свои структуры и свой формат. Аннотации спасают положение, но только если их в коде немного. Особенно феерически выглядят классы доменной модели, в которых сразу используются аннотации JPA, валидации и еще например, поискового движка типа Compass. В итоге самих аннотаций становится больше чем кода. Это та цена, которую приходится платить за создание enterprise систем и, надо сказать, по сравнению скажем, с EJB 2.x, все выглядит весьма неплохо <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Однако, такой подход совершенно не вдохновляет, если хочется написать нечто небольшое, какой-нибудь проект для себя, как говорится just for fun. Как только я представляю себе весь этот процесс, мне уже не хочется ничего делать. Всякие Django, руби-на-рельсах и т.д. мне изучать только для свободы самовыражения как-то неохота, поэтому я решил поискать фреймворк на pure Java. Основными критериями были: максимальная простота в использовании (принцип KISS), минимум конфигурации (convention over configuration), возможность быстрого построения веб-проекта малого масштаба. В итоге перебрав около десятка разных вариантов, случайно наткнулся на <a href="www.mentaframework.org">сабж</a>. Парни из солнечной Бразилии судя по всем задались такими же мыслями, как и я, поэтому фреймворк мне очень понравился. Очень прост в использовании, содержит все необходимые фичи &#8211; собственную IoC/DI реализацию, подсистему авторизации/аутентификации, валидацию, простейший персистентный механизм, поддержку AJAX, i18n, поддержку транзакций и т.д. Конечно, это все гораздо примитивнее того, что используется при построении больших корпоративных систем, но ведь и такой задачи перед этим фреймворком не стоит. Гораздо важнее другое &#8211; все это просто работает, без сотен строк xml, кучи зависимостей, многочасовых воскуриваний мануалов и танцев с бубном вокруг особо хитровылетевшего эксепшена. То что надо, если понадобится быстро склепать небольшой вебпроект, которому вовсе не требуется вся мощь энтерпрайз технологий. В будущем наверное буду писать заметки с рассмотрением примеров типовых задач и как это решается с помощью Mentawai,  хотя на сайте есть вполне приличные how-to и примеры.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/66/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=66&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2009/11/01/mentawai-web-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>
	</item>
		<item>
		<title>Mathematica + Java</title>
		<link>http://ynovikov.wordpress.com/2009/10/29/mathematica-java/</link>
		<comments>http://ynovikov.wordpress.com/2009/10/29/mathematica-java/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 05:51:27 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[mathematica]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=57</guid>
		<description><![CDATA[Есть такой популярный пакет для выполнения различных математических расчетов - Mathematica от Wolfram Research. Позволяет вычислять самые разнообразные вещи. Недавно обнаружил у него возможность использования его функционала во многих языках программирования, в том числе и в Java. Очень полезно в немногочисленных случаях, когда нужно использовать в разрабатываемой системе математические расчеты различной степени сложности. Это обеспечивается тем, что [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=57&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Есть такой популярный пакет для выполнения различных математических расчетов - Mathematica от Wolfram Research. Позволяет вычислять самые разнообразные вещи. Недавно обнаружил у него возможность использования его функционала во многих языках программирования, в том числе и в Java. Очень полезно в немногочисленных случаях, когда нужно использовать в разрабатываемой системе математические расчеты различной степени сложности. Это обеспечивается тем, что в составе пакета Mathematica есть четкое разделение на собственно графическую оболочку и ядро, с которым можно наладить взаимодействие не обращаясь к помощи стандартного интерфейса. Само взаимодействие обеспечивается при помощи нативных библиотек, которые есть под все популярные платформы, а для работы с ним из Java предоставляется так называемый коннектор J/Link-MathLink, который представляет собой мост между нашей программой на Java и нативной реализацией адаптера MathLink, который возьмет на себя взаимодействие с ядром Mathematica.</p>
<p>Итак, для начала работы сначала необходимо установить сам пакет. Я использовал версию 6.0. Немного старовата, но для демонстрации работы большего и не нужно. Коннектор J/Link скачиваем с <a href="http://www.wolfram.com/solutions/mathlink/jlink/">сайта производителя</a>. После этого в любой IDE создаем проект с простейшей структурой. Мой пример был создан в Eclipse, скачать его можно <a href="http://rapidshare.com/files/299384294/JavaMath.zip.html">здесь</a>. Далее я буду исходить из того, что проект вы скачали и посмотрели что там за структура, поэтому буду просто называть имена директорий. В classpath проекта входит папка lib, в которой лежит как J/Link коннектор (JLink.jar), так и нативный MathLink адаптер (JLinkNativeLibrary.dll). Его я туда скопировал из системных файлов Mathematica, чтобы лишний раз не указывать его путь &#8211; при загрузке по JNI он будет найден автоматически, т.к. находится в classpath.  Сразу отмечу, что эта dll &#8211; для 32-bit Windows. Если в вашей операционке эта библиотека откажется подгружаться (например, в 64-bit Windows) &#8211; замените соответствующим ей dll из системных файлов Mathematica.  Запускается пример при помощи скрипта startup.bat, в котором указан classpath, заданы параметры загрузки адаптера MathLink (о них подробнее в справочнике Mathematica) и указан путь к ядру (MathKernel.exe). Проверьте, чтобы он был верным для вашей инсталляции пакета. На этом описание структуры проекта закончу и перейду к самому примеру.</p>
<p><pre class="brush: java;">
package com.ynov.javamath;

import com.wolfram.jlink.KernelLink;
import com.wolfram.jlink.MathLinkException;
import com.wolfram.jlink.MathLinkFactory;

public class JavaMathHelloWorld {
	
	public static void main(String[] args) {
		KernelLink kernelLink = null;
	    
	    try {
			kernelLink = MathLinkFactory.createKernelLink(args);
		} catch (MathLinkException e) {
			System.out.println(&quot;Can't create link: &quot; + e.getMessage());
			return;
		}

		try {
			kernelLink.discardAnswer();
			System.out.println(&quot;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&quot;);
			double result;
			kernelLink.putFunction(&quot;EvaluatePacket&quot;, 1);
			kernelLink.putFunction(&quot;Times&quot;, 2);
			kernelLink.put(3);
			kernelLink.put(3);
			kernelLink.endPacket();
			kernelLink.waitForAnswer();
			result = kernelLink.getInteger();
			System.out.print(&quot;1) &quot;);
			System.out.println(&quot;3 * 3 = &quot; + result);
			
			kernelLink.newPacket();
			kernelLink.putFunction(&quot;EvaluatePacket&quot;, 1);
			kernelLink.putFunction(&quot;N&quot;, 2);
				kernelLink.putFunction(&quot;Sqrt&quot;, 1);
				kernelLink.put(3);
			kernelLink.put(20);	
			kernelLink.endPacket();
			kernelLink.waitForAnswer();
			result = kernelLink.getDouble();
			System.out.print(&quot;2) &quot;);
			System.out.println(&quot;Sqrt(3) = &quot; + result);
			System.out.println(&quot;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&quot;);
		} catch (MathLinkException e) {
			System.out.println(&quot;MathLinkException: &quot; + e.getMessage());
		} finally {
			kernelLink.close();
		}
	
	}

}

</pre></p>
<p>В 13 строке создается ссылка на экземпляр ядра Mathematica. Там происходит подгрузка MathLink коннектора (той самой dll, запускается ядро пакета и налаживается с ним взаимодействие). В 20 строке немного танцев с бубном &#8211; при старте ядро посылает нам сообщение, которое нам ни к чему, поэтому удаляем его из буфера вывода при помощи вызова соответствующей функции. Далее можно начинать непосредственно работу с ядром &#8211; отправлять ему для вычисления нужные нам выражения. Для этого необходимо иметь представление, как эти выражения строить как таковые, так что для тех, кто не в курсе &#8211; нужно почитать соответствующий раздел справки. Любое выражение в этом пакете может быть представлено в текстовом виде при помощи <a href="http://reference.wolfram.com/mathematica/guide/CoreLanguageOverview.html">Core Language</a>. Мы рассмотрим 2 примера с использованием простейших <a href="http://reference.wolfram.com/mathematica/guide/MathematicalFunctions.html">математических функций</a> &#8211; умножение 3*3 (будет записано на языке пакета как <strong>Times[3,3]</strong>) и вычисление корня квадратного из 3 с требуемой точностью (<strong>N[Sqrt[3], 20]</strong>). Полное описание этих функций можно найти по ссылкам, приведенным выше в справочной документации. Есть три способа выполнить расчет и получить результат. В первом &#8211; ядру передается строка целиком и оно берет на себя ее анализ, построение выражения и результат вычисления отдается как строка. Во втором &#8211; результат вычисления отдается в соответствии с типом. А мы рассмотрим третий, наиболее сложный и полезный &#8211; построение выражения в виде дерева и возврат значения в соответствии с типом. Итак, в строке 23 мы вызываем функцию создания нового пакета вычислений:</p>
<p><code>kernelLink.putFunction(</code><code>"EvaluatePacket"</code><code>, </code><code>1</code><code>);</code></p>
<p>Это выражение Core Language, инструкция ядру, что вложенные функции должны рассматриваться и вычисляться как один пакет. Первый аргумент &#8211; имя функции, второй &#8211; количество ее аргументов. Далее, как аргумент для EvaluatePacket, в строке 24, передаем собственно функцию, которую нужно вычислить:</p>
<p><code>kernelLink.putFunction(</code><code>"Times"</code><code>, </code><code>2</code><code>);</code></p>
<p>А в строках 25 и 26 передаем аргументы этой функции &#8211; сомножители 3 и 3. После этого в строке 27 закрываем наш пакет заданий при помощи соответствующей функции. Так как это был первый пакет, создавать его явно не было необходимости, но вообще это делается при помощи соответствующей функции, как показано в строке 33. В строке 28 запускаем вычисление и ждем ответа, а после этого в строке 29 получаем результат вычислений. В следующих строках с 33 по 43 вычисление квадратного корня происходит по тому же принципу, только уровней вложенности выражения будет 2 (функция N принимает как аргумент функцию Sqrt),  а остальные принципы ровно те же самые. Ну и в строке 48 закрываем соединение с ядром. Кстати, ядро можно так же запустить в серверном режиме и обращаться к нему по сети &#8211; подробнее в документации. В общем, ничего сложного, но пользы может быть от такого интеграционного решения много. Спасибо за внимание <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/57/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=57&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2009/10/29/mathematica-java/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>
	</item>
		<item>
		<title>Для комментариев</title>
		<link>http://ynovikov.wordpress.com/2009/10/21/%d0%b4%d0%bb%d1%8f-%d0%ba%d0%be%d0%bc%d0%bc%d0%b5%d0%bd%d1%82%d0%b0%d1%80%d0%b8%d0%b5%d0%b2/</link>
		<comments>http://ynovikov.wordpress.com/2009/10/21/%d0%b4%d0%bb%d1%8f-%d0%ba%d0%be%d0%bc%d0%bc%d0%b5%d0%bd%d1%82%d0%b0%d1%80%d0%b8%d0%b5%d0%b2/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 04:06:19 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[Прочее]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=54</guid>
		<description><![CDATA[Зарезервировано для вопросов и предложений<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=54&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Зарезервировано для вопросов и предложений</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=54&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2009/10/21/%d0%b4%d0%bb%d1%8f-%d0%ba%d0%be%d0%bc%d0%bc%d0%b5%d0%bd%d1%82%d0%b0%d1%80%d0%b8%d0%b5%d0%b2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>
	</item>
		<item>
		<title>Working with Maven &#8211; creating a project</title>
		<link>http://ynovikov.wordpress.com/2009/09/28/working-with-maven-creating-a-project/</link>
		<comments>http://ynovikov.wordpress.com/2009/09/28/working-with-maven-creating-a-project/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 02:21:34 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[Maven]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=40</guid>
		<description><![CDATA[If you want to start using Maven you are highly recommended to follow the Maven application model. If you are going to start a new application development you can use Maven archetype plugin to simplify the initial setup for you. The format of the command looks like this: mvn archetype:generate -DgroupId=&#60;groupId&#62; -DartifactId=&#60;artifactId&#62; -DarchetypeArtifactId=&#60;archetypeId&#62; Or you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=40&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">If you want to start using Maven you are highly recommended to follow the Maven application model. If you are going to start a new application development you can use Maven archetype plugin to simplify the initial setup for you. The format of the command looks like this:</p>
<p><strong>mvn archetype:generate </strong><br />
<strong>-DgroupId=&lt;groupId&gt; </strong><br />
<strong>-DartifactId=&lt;artifactId&gt;</strong><br />
<strong> -DarchetypeArtifactId=&lt;archetypeId&gt;</strong></p>
<p style="text-align:justify;">Or you can use more  simple wizard-style approach: just type <strong>mvn archetype:generate </strong>and Maven will ask you to provide all necessary information to create the project structure that will fit your requirements. You will have to make a choice of desired archetype from provided list so there&#8217;s no need to know the correct id &#8211; Maven will help you. I assume that you have Maven2 installed, it&#8217;s bin directory is added to system path. I prefer the second way because it&#8217;s much easier for me &#8211; there&#8217;s no need to remember the archetype ids. A complete list of artifacts can be found <a href="http://docs.codehaus.org/display/MAVENUSER/Archetypes+List">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/40/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=40&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2009/09/28/working-with-maven-creating-a-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>
	</item>
		<item>
		<title>Tomcat под Linux &#8211; включаем консоль</title>
		<link>http://ynovikov.wordpress.com/2009/07/21/tomcat-%d0%bf%d0%be%d0%b4-linux-%d0%b2%d0%ba%d0%bb%d1%8e%d1%87%d0%b0%d0%b5%d0%bc-%d0%ba%d0%be%d0%bd%d1%81%d0%be%d0%bb%d1%8c/</link>
		<comments>http://ynovikov.wordpress.com/2009/07/21/tomcat-%d0%bf%d0%be%d0%b4-linux-%d0%b2%d0%ba%d0%bb%d1%8e%d1%87%d0%b0%d0%b5%d0%bc-%d0%ba%d0%be%d0%bd%d1%81%d0%be%d0%bb%d1%8c/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 20:10:14 +0000</pubDate>
		<dc:creator>Юрий Новиков</dc:creator>
				<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://ynovikov.wordpress.com/?p=37</guid>
		<description><![CDATA[По умолчанию в Linux Catalina при старте не поднимает консоль, как в Windows, а пишет все в логи (%TOMCAT_HOME%/logs/catalina.out). В общем-то, логи можно выводить на консоль при помощи команды tail -f catalina.out (если ее запустить в директории с логами), но такой подход лишает нас всякого интерактива &#8211; таким образом мы можем только читать лог, но [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=37&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>По умолчанию в <strong>Linux Catalina</strong> при старте не поднимает консоль, как в <strong>Windows</strong>, а пишет все в логи (<strong>%TOMCAT_HOME%/logs/catalina.out</strong>). В общем-то, логи можно выводить на консоль при помощи команды <strong>tail -f catalina.out</strong> (если ее запустить в директории с логами), но такой подход лишает нас всякого интерактива &#8211; таким образом мы можем только читать лог, но ничего не сможем ввести. А вводить команды в консоль<strong> Tomcat</strong> мне понадобилось в процессе экспериментов с server-side OSGi, а именно &#8211; <strong><a href="http://www.eclipse.org/equinox/server/" target="_self">Equinox servlet bridge</a></strong>. Он поднимает OSGi-контейнер внутри сервера и среди прочего, при помощи специального сервлета-моста перенаправляет все входящие запросы на OSGi HTTP service. Соответственно, консоль <strong>Equinox</strong> поднимается в консоли <strong>Tomcat</strong>, для этого и понадобилась возможность вводить туда команды. Чтобы получить возможность вводить команды в консоль, необходимо отключить логирование в файл, тогда поток ввода\вывода будет направлен в окно терминала и мы сможем с ним работать. Это делается очень просто &#8211; в файле <strong>catalina.sh</strong> находим такой блок:</p>
<blockquote><p>[...]<br />
else<br />
&laquo;$_RUNJAVA&raquo; $JAVA_OPTS &laquo;$LOGGING_CONFIG&raquo; $CATALINA_OPTS \<br />
-Djava.endorsed.dirs=&raquo;$JAVA_ENDORSED_DIRS&raquo; -classpath &laquo;$CLASSPATH&raquo; \<br />
-Dcatalina.base=&raquo;$CATALINA_BASE&raquo; \<br />
-Dcatalina.home=&raquo;$CATALINA_HOME&raquo; \<br />
-Djava.io.tmpdir=&raquo;$CATALINA_TMPDIR&raquo; \<br />
org.apache.catalina.startup.Bootstrap &laquo;$@&raquo; start \<br />
<strong>#&gt;&gt; &laquo;$CATALINA_BASE&raquo;/logs/catalina.out 2&gt;&amp;1 &amp;</strong><br />
[...]</p></blockquote>
<p>И комментируем там последнюю строчку,  как показано выше.  После этого сохраняем изменения, запускаем сервер при помощи <strong>catalina.sh start</strong> &#8211; и готово:</p>
<p><img class="aligncenter size-full wp-image-38" title="console" src="http://ynovikov.files.wordpress.com/2009/07/console1.png?w=450" alt="console"   /></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ynovikov.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ynovikov.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ynovikov.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ynovikov.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ynovikov.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ynovikov.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ynovikov.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ynovikov.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ynovikov.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ynovikov.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ynovikov.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ynovikov.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ynovikov.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ynovikov.wordpress.com/37/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ynovikov.wordpress.com&amp;blog=8630913&amp;post=37&amp;subd=ynovikov&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ynovikov.wordpress.com/2009/07/21/tomcat-%d0%bf%d0%be%d0%b4-linux-%d0%b2%d0%ba%d0%bb%d1%8e%d1%87%d0%b0%d0%b5%d0%bc-%d0%ba%d0%be%d0%bd%d1%81%d0%be%d0%bb%d1%8c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f340020429674939d26b33e3994250db?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">ynovikov</media:title>
		</media:content>

		<media:content url="http://ynovikov.files.wordpress.com/2009/07/console1.png" medium="image">
			<media:title type="html">console</media:title>
		</media:content>
	</item>
	</channel>
</rss>
