<?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>Splatch's devblog &#187; Moje publikacje</title>
	<atom:link href="http://blog.dywicki.pl/category/moje-publikacje/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dywicki.pl</link>
	<description>Pragmatyzm kontrolowany</description>
	<lastBuildDate>Thu, 01 Dec 2011 15:47:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>EasyMock i IAnswer, recepta na zachowanie metod</title>
		<link>http://blog.dywicki.pl/2008/12/03/easymock-inaswer-as-method-behaviour-recipe/</link>
		<comments>http://blog.dywicki.pl/2008/12/03/easymock-inaswer-as-method-behaviour-recipe/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 16:06:42 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Porady]]></category>
		<category><![CDATA[Testy jednostkowe]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=240</guid>
		<description><![CDATA[Złym zwyczajem jest modyfikowanie argumentów zamiast zwracania nowej wartości, jakkolwiek trafiają się sytuacje gdy testowany kod powinien weryfikować takie wywołania. W EasyMock mamy do dyspozycji w takim przypadku interfejs IAnswer. Jego użycie jest w miarę proste &#8211; dobieramy się do tablicy argumentów i robimy z nią co potrzeba. Oto przykład &#8211; interfejs Populator dodaje do [...]]]></description>
			<content:encoded><![CDATA[<p>Złym zwyczajem jest modyfikowanie argumentów zamiast zwracania nowej wartości, jakkolwiek trafiają się sytuacje gdy testowany kod powinien weryfikować takie wywołania. W EasyMock mamy do dyspozycji w takim przypadku interfejs IAnswer. Jego użycie jest w miarę proste &#8211; dobieramy się do tablicy argumentów i robimy z nią co potrzeba.<br />
<span id="more-240"></span><br />
Oto przykład &#8211; interfejs Populator dodaje do przekazanej tablicy określoną wartość w puste miejsca. Zwraca też ilość zmian, które zaprowadził. Całość jest oparta na bardzo prostym kodzie, zaledwie jedna pętla, jakkolwiek na potrzeby przykładu jest to wystarczające. Pragnę jednak nadmienić, że w podobny sposób można testować bardziej złożony kod, gdzie kolaborują ze sobą dwa obiekty &#8211; tj. Observator i Observable czy też Visitor i Visitable.</p>
<pre class="brush: java;">package org.code_house.test.mock;

interface Populator {
    int fill(String value, String[] arguments);
}
</pre>
<p>Implementacja interfejsu jest bardzo prosta:</p>
<pre class="brush: java;">package org.code_house.test.mock;

class FillAnswer implements IAnswer&lt;Integer&gt; {
    public Integer answer() throws Throwable {
        // pobranie argumentow
        Object[] arguments = EasyMock.getCurrentArguments();
        String name = (String) arguments[0];
        Object[] values = (Object[]) arguments[1];

        // logika potrzebna do testu
        int populated = 0;
        for (int i = 0; i &lt; values.length; i++) {
            if (values[i] == null) {
                populated++;
                values[i] = name;
            }
        }
        return populated;
    }
}
</pre>
<p>Test jest również niezbyt skomplikowany &#8211; bazuje on na poprzedniej nocie &#8211; &#8220;Testowanie tablic argumentów z EasyMock&#8221;:</p>
<pre class="brush: java;">package org.code_house.test.mock;

import static org.easymock.EasyMock.*;
import org.easymock.IAnswer;

import java.util.Arrays;

import junit.framework.TestCase;

public class AnswerTest extends TestCase {

    public void testPopulate() {
        Populator populator = createMock(Populator.class);
        expect(populator.fill(eq(&quot;Code House&quot;), aryEq(new String[3])))
            .andAnswer(new FillAnswer());
        expect(populator.fill(eq(&quot;Code House&quot;), aryEq(new String[] {&quot;1&quot;})))
            .andAnswer(new FillAnswer());
        replay(populator);

        // tablica do wypełnienia
        String[] populated = new String[3];
        int added = populator.fill(&quot;Code House&quot;, populated);
        assertEquals(3, added);
        // w odpowiedzi oczekujemy dodania 3 nowych elementów
        assertTrue(Arrays.equals(
            new String[] {&quot;Code House&quot;, &quot;Code House&quot;, &quot;Code House&quot;},
            populated
        ));

        // w tym przypadku nie oczekujemy nowości
        added = populator.fill(&quot;Code House&quot;, new String[] {&quot;1&quot;});
        assertEquals(0, added);
    }
}
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/12/03/easymock-inaswer-as-method-behaviour-recipe/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testowanie tablic argumentów z EasyMock</title>
		<link>http://blog.dywicki.pl/2008/11/26/testing-array-parameters-with-easymock/</link>
		<comments>http://blog.dywicki.pl/2008/11/26/testing-array-parameters-with-easymock/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 06:00:02 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Porady]]></category>
		<category><![CDATA[Testy jednostkowe]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=239</guid>
		<description><![CDATA[Często zdarza się że metody, które piszemy i później testujemy mają argumenty w postaci tablic. EasyMock wówczas potrafi zgłosić wyjątek, że przekazana tablica jest różna od oczekiwanej mimo, że zawartość tablic jest identyczna. java.lang.AssertionError: Unexpected method call find([Ljava.lang.String;@1ad77a7): find([Ljava.lang.String;@b8f82d): expected: 1, actual: 0 package org.code_house.test.mock; import static org.easymock.EasyMock.aryEq; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import [...]]]></description>
			<content:encoded><![CDATA[<p>Często zdarza się że metody, które piszemy i później testujemy mają argumenty w postaci tablic. EasyMock wówczas potrafi zgłosić wyjątek, że przekazana tablica jest różna od oczekiwanej mimo, że zawartość tablic jest identyczna.<br />
<span id="more-239"></span></p>
<pre class="brush: java;">java.lang.AssertionError:
  Unexpected method call find([Ljava.lang.String;@1ad77a7):
    find([Ljava.lang.String;@b8f82d): expected: 1, actual: 0
</pre>
<pre class="brush: java;">
package org.code_house.test.mock;

import static org.easymock.EasyMock.aryEq;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;

import java.util.Collections;
import java.util.List;

import junit.framework.TestCase;

interface Finder {
    List&lt;String&gt; find(String[] names);
}

public class FinderTest extends TestCase {

    public void testFind() {
        Finder mock = createMock(Finder.class);
        expect(mock.find(aryEq(new String[] {&quot;Amy&quot;, &quot;Luke&quot;}))).andReturn(
            Collections.EMPTY_LIST);
        replay(mock);

        List&lt;String&gt; list = mock.find(new String[] {&quot;Amy&quot;, &quot;Luke&quot;});
        assertTrue(list.isEmpty());
    }
}
</pre>
<p>Rozwiązaniem tych problemów jest użycie mechanizmu &#8220;matcherów&#8221;, które są wbudowane w sam szkielet. Najprostszym sposobem na ich użycie jest odwołanie przy pomocy statycznego wywołania którejś z metod EasyMock. Poniżej znajduje się lista dostępnych matcherów. Wartość &#8220;given&#8221; to argument przekazany w wywołaniu metody. </p>
<ul>
<li><strong>eq</strong>(X value)<br />
    Argument pasuje jeśli wyrażenie value.equals(given) zwróci true. Dostępny dla wszystkich typów prostych i obiektów.</li>
<li><strong>anyBoolean</strong>(), <strong>anyByte</strong>(), <strong>anyChar</strong>(), <strong>anyDouble</strong>(), <strong>anyFloat</strong>(), <strong>anyInt</strong>(), <strong>anyLong</strong>(), <strong>anyObject</strong>(), <strong>anyShort</strong>()<br />
    Dowolna wartość zostanie przepuszczona niezależnie od tego co będzie przekazane. Dostępny dla wszystkich typów.
</li>
<li><strong>eq</strong>(X value, X delta)<br />
    Pasuje jeśli aktualna jeśli wyrażenie given jest równe value z dokładnością do delta. Dostępne dla typów float oraz double.</li>
<li><strong>aryEq</strong>(X value)<br />
    Pasuje jeśli wyrażenie Arrays.equals(value, given) zwraca true. Dostępne dla tablic typów prostych jak i dla obiektów.</li>
<li><strong>isNull</strong>()<br />
    Pasuje jeśli given == null. Dostępne tylko dla obiektów.</li>
<li><strong>notNull</strong>()<br />
    Pasuje jeśli given != null. Dostępne tylko dla obiektów.</li>
<li><strong>same</strong>(X value)<br />
    Pasuje jeśli wyrażenie value == given jest prawdziwe. Dostępne tylko dla obiektów.</li>
<li><strong>isA</strong>(Class clazz)<br />
    Pasuje jeśli given instanceof clazz zwraca true. Given może być instancję clazz jak i pochodną.</li>
<li><strong>lt</strong>(X value), <strong>leq</strong>(X value), <strong>geq</strong>(X value), <strong>gt</strong>(X value)<br />
    Zwraca true jeśli given jest mniejsze, mniejsze równe, większe równe bądź większe niż value. Dostępne dla wszystkich numerycznych typów prostych.</li>
<li><strong>startsWith</strong>(String prefix), <strong>contains</strong>(String substring), <strong>endsWith</strong>(String suffix)<br />
    Zwraca true jeśli given  zaczyna się, zawiera bądź kończy się daną wartością. Dostępne dla argumentów typu String.</li>
<li><strong>matches</strong>(String regex), <strong>find</strong>(String regex)<br />
    Pasuje jeśli given pasuje w całości do wyrażenia/fragment pasuje. Dostępne dla argumentów typu String.</li>
<li><strong>and</strong>(X first, X second)<br />
    Zwraca true jeśli matcher first oraz second zwracają prawdę.</li>
<li><strong>or</strong>(X first, X second)<br />
    Zwraca true jeśli matcher first bądź second pasuje.</li>
<li><strong>not</strong>(X value)<br />
    Zwraca true jeśli matcher value zwrócił fałsz.</li>
</ul>
<p>Uzbrojeni w taki zestaw matcherów możemy poprawić kod testu tak by był on poprawny:</p>
<pre class="brush: java;">

public class FinderTest extends TestCase {

    public void testFind() {
        Finder mock = createMock(Finder.class);
        expect(mock.find(aryEq(new String[] {&quot;Amy&quot;, &quot;Luke&quot;}))).andReturn(
            Collections.EMPTY_LIST);
        replay(mock);

        List&lt;String&gt; list = mock.find(new String[] {&quot;Amy&quot;, &quot;Luke&quot;});
        assertTrue(list.isEmpty());
    }
}
</pre>
<p>Inny przykład:</p>
<pre class="brush: java;">
public class FinderTest extends TestCase {

    public void testFind() {
        Finder mock = createMock(Finder.class);
        expect(mock.find(&quot;Lucy&quot;, aryEq(new String[] {&quot;Amy&quot;, &quot;Luke&quot;}))).andReturn(
            Collections.EMPTY_LIST);
        replay(mock);

        List&lt;String&gt; list = mock.find(&quot;Lucy&quot;, new String[] {&quot;Amy&quot;, &quot;Luke&quot;});
        assertTrue(list.isEmpty());
    }
}
</pre>
<p>Warto zwrócić uwagę na to, że jeśli korzystamy dla matchera aby dopasować argument to musimy zrobić to dla wszystkich, inaczej poleci wyjątek:</p>
<pre class="brush: java;">
java.lang.IllegalStateException: 2 matchers expected, 1 recorded.
</pre>
<p>Stąd nasz test w końcowej postaci powinien wyglądać następująco:</p>
<pre class="brush: java;">
package org.code_house.test.mock;

import static org.easymock.EasyMock.aryEq;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;

import java.util.Collections;
import java.util.List;

import junit.framework.TestCase;

interface Finder {
    List&lt;String&gt; find(String[] names);

    List&lt;String&gt; find(String name, String[] names);
}

public class FinderTest extends TestCase {

    public void testFind() {
        Finder mock = createMock(Finder.class);
        expect(mock.find(eq(&quot;Lucy&quot;), aryEq(new String[] {&quot;Amy&quot;, &quot;Luke&quot;}))).andReturn(
            Collections.EMPTY_LIST);
        replay(mock);

        List&lt;String&gt; list = mock.find(&quot;Lucy&quot;, new String[] {&quot;Amy&quot;, &quot;Luke&quot;});
        assertTrue(list.isEmpty());
    }
}
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/26/testing-array-parameters-with-easymock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uruchom inny język w Javie</title>
		<link>http://blog.dywicki.pl/2008/11/24/scripting-inside-java/</link>
		<comments>http://blog.dywicki.pl/2008/11/24/scripting-inside-java/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 06:00:02 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Porady]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=236</guid>
		<description><![CDATA[Do Javy 6.0 zostało dołączone API (JSR 223) umożliwiające wywoływanie różnych języków wewnątrz wirtualnej maszyny. Można w ten sposób przesunąć chociażby moment kompilowania kodu na później bądź od razu podpiąć język interpretowany. Poniżej przykład: package org.code_house.scripting; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; public class JSMain { public static void main(String[] args) throws Exception { ScriptEngineManager [...]]]></description>
			<content:encoded><![CDATA[<p>Do Javy 6.0 zostało dołączone <acronym title="Application Programming Interface">API</acronym> (<a href="http://www.jcp.org/en/jsr/detail?id=223">JSR 223</a>) umożliwiające wywoływanie różnych języków wewnątrz wirtualnej maszyny. Można w ten sposób przesunąć chociażby moment kompilowania kodu na później bądź od razu podpiąć język interpretowany.<br />
<span id="more-236"></span><br />
Poniżej przykład:</p>
<pre class="brush: java;">
package org.code_house.scripting;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;

public class JSMain {

    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();

        System.out.println(&quot;Dostępne języki&quot;);
        for (ScriptEngineFactory engine : manager.getEngineFactories()) {
            System.out.println(engine.getNames());
        }

        ScriptEngine engine = manager.getEngineByName(&quot;js&quot;);
        engine.put(&quot;y&quot;, 12);

        if (engine != null) {
            engine.eval(&quot;var x = 1; print(x + y);&quot;);
        }
    }

}
</pre>
<p>W taki oto sposób na naszej konsoli powinno wylądować coś takiego:</p>
<pre class="brush: java;">
[js, rhino, JavaScript, javascript, ECMAScript, ecmascript]
13
</pre>
<p>
<img src="http://blog.dywicki.pl/wp-content/uploads/2008/11/js-swing.jpg" alt="Swing + Java Script" title="Swing + Java Script" width="180" height="80" align="right" /></p>
<p>Możemy również uruchomić plik js. Wystarczy do metody <b>eval</b> przekazać FileReader. Po uruchomieniu kodu który jest niżej powinno pokazać się okienko podobne do tego, które widzicie przy tym akapicie.
</p>
<pre class="brush: java;">package org.code_house.scripting;

import java.io.*;
import javax.script.*;

public class JavaScriptMain {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName(&quot;js&quot;);
        engine.eval(new FileReader(new File(&quot;print.js&quot;)));
    }
}</pre>
<pre class="brush: jscript;">
frame = new javax.swing.JFrame;
frame.defaultCloseOperation = javax.swing.JFrame.EXIT_ON_CLOSE;
frame.title = &quot;Test&quot;
frame.setSize(new java.awt.Dimension(180, 80));

button = new javax.swing.JButton(&quot;Kliknij mnie&quot;)
button.addActionListener(function(event) {
    print(event.source);
});
frame.add(button);

frame.show()
</pre>
<p>Z dodatkowych języków można podpiąć między innymi <a href="http://php.net"><acronym title="Pre-Hypertext Processing">PHP</acronym></a>, <a href="http://java.sun.com/javafx/">Java FX</a>, <a href="http://groovy.codehaus.org">Groovy</a>, <a href="http://www.beanshell.org/">BeanShell</a> i wiele innych. Aby to zrobić należy ściągnąć ze strony <a href="https://scripting.dev.java.net/">scripting.dev.java.net</a> rozszerzenia (dostępne w sekcji Documents &#038; files) i dodać JAR dla języka którego potrzebujemy do classpath.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/24/scripting-inside-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interfejs InitializingBean</title>
		<link>http://blog.dywicki.pl/2008/11/21/interfejs-initializingbean/</link>
		<comments>http://blog.dywicki.pl/2008/11/21/interfejs-initializingbean/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 06:00:27 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Porady]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=235</guid>
		<description><![CDATA[Każdy z obiektów który jest konfigurowany w kontekście Springa ma szansę zweryfikować swój stan tuż po zainicjowaniu wszystkich wartości, które zostały mu przekazane. Wynika to z tego, że czasami obiekty potrafią działać na kilku różnych zasobach i można wstrzyknąć do nich tylko jeden rodzaj tegoż. Czasami po prostu potrzebujemy sprawdzić czy są przekazane wszystkie ustawienia [...]]]></description>
			<content:encoded><![CDATA[<p>Każdy z obiektów który jest konfigurowany w kontekście Springa ma szansę zweryfikować swój stan tuż po zainicjowaniu wszystkich wartości, które zostały mu przekazane. Wynika to z tego, że czasami obiekty potrafią działać na kilku różnych zasobach i można wstrzyknąć do nich tylko jeden rodzaj tegoż. Czasami po prostu potrzebujemy sprawdzić czy są przekazane wszystkie ustawienia konfiguracyjne bądź zainicjować połączenie do bazy danych na podstawie przekazanych parametrów.<br />
<span id="more-235"></span><br />
Mamy wówczas do wyboru dwie metody. Pierwszą z nich jest implementacja interfejsu <a href="http://www.docjar.com/docs/api/org/springframework/beans/factory/InitializingBean.html">org.springframework.beans.factory.InitializingBean</a>. Jeśli wyrzuci ona jakiś wyjątek to Spring wyrzuci wyjątek wyżej i wstrzyma powoływanie kontekstu. Oto przykład:</p>
<pre class="brush: java;">
package org.code_house.samples.spring;

import java.util.Properties;

import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;

public class PropertiesConfiguration implements InitializingBean {

    /**
     * Ustawienia konfiguracyjne.
     */
    private Properties properties;

    public void setProperties(Properties props) {
        this.properties = props;
    }

    public void afterPropertiesSet() throws Exception {
        if (properties == null) {
            throw new BeanInitializationException(&quot;Nie przekazano ustawień &quot;
                +&quot;konfiguracyjnych. Pole properties jest wymagane.&quot;);
        }
    }
}
</pre>
<p>Spring nie wymusza jednak implementowania interfejsu. Jeśli nasz kod już istnieje i jest metoda która weryfikuje stan obiektu możemy użyć atrybutu init-method dla znacznika bean:</p>
<pre class="brush: xml;">
    &lt;bean class=&quot;org.code_house.samples.xml.JaxbConfiguration&quot;
        init-method=&quot;verify&quot;&gt;
        &lt;property name=&quot;source&quot; value=&quot;classpath:data.xml&quot; /&gt;
    &lt;/bean&gt;
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/21/interfejs-initializingbean/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Odwołanie do klasy Properties w kontekście springa</title>
		<link>http://blog.dywicki.pl/2008/11/20/odwolanie-do-klasy-properties-w-kontekscie-springa/</link>
		<comments>http://blog.dywicki.pl/2008/11/20/odwolanie-do-klasy-properties-w-kontekscie-springa/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 06:00:46 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Porady]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=233</guid>
		<description><![CDATA[Jako, że nie zawsze mam czas pisać dłuższe noty, a nie wszyscy znają Springa postanowiłem publikować krótkie porady, które mogą kiedyś komuś się przydać. Klasa java.util.Properties to jeden z najprostszych sposobów na odwołanie do prostych ustawień konfiguracyjnych. Składnia pliku properties jest zbliżona do ini i wygląda następująco: nazwa.wlasnosci wartosc inna.nazwa.wlasnosci=costam # to jest komentarz jeszcze.cos.nowego [...]]]></description>
			<content:encoded><![CDATA[<p><em>Jako, że nie zawsze mam czas pisać dłuższe noty, a nie wszyscy znają Springa postanowiłem publikować krótkie porady, które mogą kiedyś komuś się przydać.</em><br />
<span id="more-233"></span><br />
Klasa java.util.Properties to jeden z najprostszych sposobów na odwołanie do prostych ustawień konfiguracyjnych. Składnia pliku properties jest zbliżona do ini i wygląda następująco:</p>
<p>nazwa.wlasnosci wartosc<br />
inna.nazwa.wlasnosci=costam<br />
# to jest komentarz<br />
jeszcze.cos.nowego</p>
<p>Jeśli chcemy przekazać obiekt klasy Properties do jakiegoś innego obiektu możemy skorzystać z poniższej wstawki w kontekście springa:</p>
<pre class="brush: xml;">
&lt;bean class=&quot;org.springframework.beans.factory.config.PropertiesFactoryBean&quot;&gt;
    &lt;property name=&quot;location&quot; value=&quot;classpath:corba.properties&quot; /&gt;
&lt;/bean&gt;
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/20/odwolanie-do-klasy-properties-w-kontekscie-springa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache ServiceMix, Open Source ESB</title>
		<link>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/</link>
		<comments>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 18:23:35 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[ESB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Moje publikacje]]></category>
		<category><![CDATA[ServiceMix]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=215</guid>
		<description><![CDATA[Jakiś czas temu, jeszcze podczas pracy w poprzedniej firmie przypadło mi zadanie podpięcia się pod magistralę usług opartą o Apache Service Mix (SMX). Był to wówczas dla mnie temat zupełnie nowy, ba nawet nie wiedziałem z czym to się je. :) Koniec końców jednak podpięcie pod ESB (Enterprises Service Bus) nie było w ogóle trudne. [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu, jeszcze podczas pracy w poprzedniej firmie przypadło mi zadanie podpięcia się pod magistralę usług opartą o <a href="http://servicemix.apache.org">Apache Service Mix</a> (SMX). Był to wówczas dla mnie temat zupełnie nowy, ba nawet nie wiedziałem z czym to się je. :) Koniec końców jednak podpięcie pod <acronym title="Enterprise Service Bus">ESB</acronym> (Enterprises Service Bus) nie było w ogóle trudne. Po jakimś czasie i drobnych przetasowaniach na płaszczyźnie zawodowej zająłem się SMX-em nie jako klient magistrali a osoba implementująca usługi na szynie a ten wpis jest drobną przeróbką prezentacji, którą przygotowałem w pracy.<br />
<span id="more-215"></span></p>
<h3>Czym jest <acronym title="Enterprise Service Bus">ESB</acronym></h3>
<p>Jednoznaczne określenie terminu <acronym title="Enterprise Service Bus">ESB</acronym> nie jest łatwe, ponieważ wokół tego tematu rozpętana została burza marketingowa. Jedni uważają je za oś <acronym title="Service Oriented Architecture">SOA</acronym> (Service Oriented Architecture) inni jako zło konieczne w dużych instytucjach.</p>
<p>Dlatego pomijając teorię przejdźmy do najistotniejszych cech, jakie oferuje <acronym title="Enterprise Service Bus">ESB</acronym>, niezależnie od producenta oraz osoby definiującej pojęcie. Sam nie chciałbym wdawać się w dyskusję na temat postrzegania i <acronym title="Enterprise Service Bus">ESB</acronym> i <acronym title="Service Oriented Architecture">SOA</acronym>. </p>
<p><img src="http://blog.dywicki.pl/wp-content/uploads/2008/06/esb.jpg" alt="" title="esb" width="500" height="378" class="aligncenter size-full wp-image-217" /><br />
<em>Źródło &#8211; <a href="http://www.codeplex.com/esb">CodePlex</a></em></p>
<p>Na załączonym wyżej obrazku widać typową strukturę logiczną w oparciu o <acronym title="Enterprise Service Bus">ESB</acronym>. Z lewej strony mamy komercyjne rozwiązanie – <a href="http://www-306.ibm.com/software/integration/wmq/">MQ Series</a> firmy <a href="http://www.ibm.com/us/">IBM</a>, dalej idąc dołem, widzimy bazę danych, serwer pocztowy a na końcu mainframe. U góry natomiast pojawiają się klienci.</p>
<h3>Ciąg dalszy</h3>
<p>Na bazie tego obrazku można powiedzieć co nieco o tym, czym owa niebieska rurka symbolizująca <acronym title="Enterprise Service Bus">ESB</acronym> jest:</p>
<ul>
<li>Jest to z pewnością centralny rejestr usług firmy, dzięki któremu nie jest konieczne wiązanie aplikacji między sobą. Wiąże się je tylko i wyłącznie z jednym elementem – z magistralą.</li>
<li>Kolejny ważny punkt, to most pomiędzy protokołami. W dobie, gdy wszyscy żyją już Web Services nie można zapomnieć o innych sposobach komunikacji – poczynając od poczciwej <a href="http://pl.wikipedia.org/wiki/CORBA">Corby</a> po kolejki JMS czy też odczyt zasobów z <acronym title="File Transfer Protocol">FTP</acronym>.</li>
<li>Transformacja komunikatów to opcjonalna czynność, której nie widać na wyżej wymienionym obrazku. Jest ona wykonywana pod maską, wewnątrz magistrali, w zależności od potrzeb. W chwili gdy mamy komunikaty z systemu A do systemu B możemy wszystko sprowadzić do jednego uniwersalnego <acronym title="Application Programming Interface">API</acronym> danych.</li>
<li>Inteligentny router informacji. Większość magistral ma coś wspólnego z pojęciem EIP, czyli <a href="http://www.enterpriseintegrationpatterns.com/">Enterprise Integration Patterns</a>. Jednym z tych wzorców jest <a href="http://www.enterpriseintegrationpatterns.com/ContentBasedRouter.html">Content Based Router</a>, to znaczy w zależności od kształtu, zawartości komunikatu, nagłówka, fragmentu, czegokolwiek możemy odbijać komunikat w różnych kierunkach. Dalej z wzorców można wymienić <a href="http://www.enterpriseintegrationpatterns.com/Filter.html">Message Filter</a>, <a href="http://www.enterpriseintegrationpatterns.com/RecipientList.html">Recipient List</a>, <a href="http://www.enterpriseintegrationpatterns.com/RoutingTable.html">Routing Slip</a>, <a href="http://www.enterpriseintegrationpatterns.com/WireTap.html">Wire Tap</a>, <a href="http://www.enterpriseintegrationpatterns.com/Sequencer.html">Splitter</a>, <a href="http://www.enterpriseintegrationpatterns.com/Resequencer.html">Resequencer</a> itd.</li>
<li>Integrator procesów biznesowych (bardziej marketingowo) – po pierwsze odwzorowanie usług magistrali do czynności biznesowych w organizacji a po drugie wsparcie dla procesorów reguł biznesowych (<a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsbpel">WS-BPEL</a>).</li>
</ul>
<h3>Service Mix jako <acronym title="Enterprise Service Bus">ESB</acronym></h3>
<p>Mając zestaw wyżej wymienionych cech możemy przejść do omówienia projektu Apache Service Mix.<br />
Może na początku kilka słów o tym, czym jest JBI, ponieważ pojawia się sam skrót, ale nie ma jego omówienia.<br />
Otóż, <a href="http://jcp.org/en/jsr/detail?id=208">JBI</a> w rozwinięciu oznacza Java Business Integration. Jest to standard przyjęty w ramach <a href="http://jcp.org/">Java Community Process</a> w celu określenia norm budowania rozwiązań <acronym title="Service Oriented Architecture">SOA</acronym> (znów buzzword). Pomijając politykę wielkich korporacji oraz marketing przejdźmy do elementów, które standard ten określa:<br />
<img src="http://blog.dywicki.pl/wp-content/uploads/2008/06/msgflow3.png" alt="Źródło: Java.net" title="Komponenty JBI" align="center" /><br />
<em>Źródło <a href="http://download.java.net/general/open-esb/docs/jbi-admin-guide/">Open <acronym title="Enterprise Service Bus">ESB</acronym> Starter Kit</a></em></p>
<ul>
<li>Typy komponentów:
<ol>
<li>Service Engine (SE) – backend do obsługi zapytań.</li>
<li>Binding Components (BC) – frontend, do nasłuchiwania w danym standardzie.</li>
<li>Shared Libraries (SL) – kod współdzielony przez w/w komponenty.
<li>
<li>Service Assembly (SA) – zbiór usług rozumianych jako jedność przez magistralę (zwykle para BC+SE).</li>
</ol>
<li>Normalized Message Router – jest to serce rozwiązania opartego o JBI, ponieważ w nim są transportowane komunikaty. To on zapewnia przepływ informacji z komponentów bindujących do silników.</li>
<li>Message Exchange Patterns – w oparciu o definicję dla <acronym title="Simple Object Access Protocol">SOAP</acronym> JBI przewiduje następujące typy komunikatów:</li>
<ol>
<li>In-Only – tylko wejście, usługa nie zwraca żadnej odpowiedzi
<li>Rebust In-Only – zwrócony zostanie status po obsłudze zapytania bądź wyjątek.
<li>In-Out – standardowa obsługa wejście-wyjście.
<li>In Optional-Out – wejście z niewiążącą (nieobowiązkową) odpowiedzią.
    </ol>
</ul>
<p>Dostępnych jest kilka implementacji JBI:</p>
<ul>
<li><a href="https://open-esb.dev.java.net/">Open <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://servicemix.apache.org">Apache Service Mix</a></li>
<li><a href="http://open.iona.com/products/enterprise-servicemix/">FUSE <acronym title="Enterprise Service Bus">ESB</acronym></a> (na bazie Service Mix)</li>
<li><a href="http://www.bostechcorp.com/products_cb_esb.htm">Bostech Chain Builder <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://mule.mulesource.org/display/MULE/Home">Mule</a></li>
<li><a href="http://www.jboss.org/jbossesb/">JBoss <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://www.oracle.com/products/middleware/index.html">Fusion Middleware</a></li>
<li><a href="http://www.tibco.com/software/soa/activematrix_service_bus/default.jsp">ActiveMatrix Service Bus</a></li>
</ul>
<h3>Service Mix od środka</h3>
<p>Wewnątrz Service Mix jest spięciem kilku potężnych projektów, rozwijanych od dłuższego czasu, które zdobyły już renomę i popularność. Między innymi można wyróżnić:</p>
<ul>
<li>Pierwszy z tych projektów to <a href="http://springframework.org/">Spring Framework</a>, rozwijany od bodajże 2000 roku, z powodzeniem rywalizujący z architekturami opartymi o EJB. Spring jest nie tylko mechanizmem konfiguracyjnym ale również zbiorem bardzo dobrych komponentów umożliwiających szereg operacji (bazy danych, JMS, przetwarzanie wsadowe, Web Services etc).</li>
<li>Drugi, bardzo ważny projekt to <a href="http://activemq.apache.org/">Active MQ</a>. Największa i najpopularniejsza otwarta implementacja standardu JMS. Jest on używany wewnątrz Service Mix-a jako transporter komunikatów w Normalized Message Router jak i do obsługi końcówek JMS.<br />
        &#8211; Wymieniony nieco niżej pod-projekt Active MQ to <a href="http://activemq.apache.org/camel/">Camel</a>. Jest to szkielet przeznaczony do tworzenia reguł routingu. Wspiera różnorakie transporty (<acronym title="HyperText Transfer Protocol">HTTP</acronym>, JMS, JBI, <acronym title="Microsoft">MS</acronym> MQ itp.).</li>
<li><a href="http://geronimo.apache.org/xbean/">XBean</a> jest fragmentem projektu Apache Geronimo (serwer aplikacyjny ze stajni Apache) przeznaczonym do tworzenia konfiguracji i zarządzania komponentami. Jest zbudowany w oparciu o Springa.</li>
<li><a href="http://cxf.apache.org/">Apache CXF</a> jest stosunkowo nowym projektem, który jest używany poprzez Service Mix w celu obsługi zapytań <acronym title="Simple Object Access Protocol">SOAP</acronym> (chociaż możliwe jest użycie innego komponentu).</li>
<li><a href="http://ode.apache.org/">Apache ODE</a> jest silnikiem reguł biznesowych w oparciu o WS-BPEL.</li>
<li>JBoss Drools jest kolejnym procesorem reguł biznesowych. Może być użyty do routingu. Jest dostępny plugin pozwalający na łatwą pracę z tą technologią.</li>
</ul>
<h3>Możliwości Service Mix</h3>
<p>Wyżej wymienione projekty są używane w Service Mix w celu uzyskania typowych funkcjonalności ESB:</p>
<ul>
<li><a href="http://servicemix.apache.org/servicemix-jms.html">JMS</a>, czyli obsługa kolejek</li>
<li><a href="http://servicemix.apache.org/servicemix-bpe.html">WS-BPEL</a>, obsługa reguł biznesowych</li>
<li>Web Services przy pomocy <a href="http://servicemix.apache.org/servicemix-cxf-se.html">CXF</a> jak i modułu <a href="http://servicemix.apache.org/servicemix-jsr181.html">JSR-181</a></li>
<li><a href="http://servicemix.apache.org/servicemix-saxon.html">Transformacje</a> <acronym title="eXtensible Stylesheet Language Transformations">XSLT</acronym> oraz XQuery (w oparciu o Saxona)</li>
<li><a href="http://servicemix.apache.org/servicemix-file.html">File Drop</a> to odczyt i zapis do plików dostępnych lokalnie jak i zdalnie (<a href="http://servicemix.apache.org/servicemix-ftp.html"><acronym title="File Transfer Protocol">FTP</acronym></a>)</li>
<li>Obsługa protokołu <a href="http://servicemix.apache.org/servicemix-xmpp.html">XMPP</a> pozwala na łatwą integrację z komunikatorami zbudowanymi w oparciu o Jabbera.</li>
<li>Dostęp do poczty przy pomocy modułu <a href="http://servicemix.apache.org/servicemix-mail.html">servicemix-mail</a></li>
<li>Komponenty programowe:</li>
<ul>
<li>Dają <a href="http://servicemix.apache.org/servicemix-bean.html">możliwość dopisania</a> własnych &#8220;endpointów&#8221;, czyli implementacji docelowych usług bądź pośredników.</li>
<li>Dodatkowe funkcjonalności (cache, rss, walidacja)</li>
</ul>
<li><a href="http://servicemix.apache.org/servicemix-scripting.html">Języki skryptowe</a> (min <a href="http://groovy.codehaus.org/">Groovy</a>)</li>
</ul>
<h3><acronym title="Enterprise Service Bus">ESB</acronym> – dlaczego Open Source</h3>
<p>Wybór Service Mix-a nie był podyktowany przypadkiem. Jest to bowiem najpopularniejsze tego typu rozwiązanie z otwartym kodem źródłowym. Co więcej, nie jest to projekt rozwijany przez osoby bez doświadczenia, pozostawiony bez wsparcia.<br />
Otwarty kod ułatwia przede wszystkim adaptację tego rozwiązania do potrzeb organizacji a nie odwrotnie – organizacji do potrzeb magistrali. W razie potrzeb jesteśmy w stanie dopisać własne komponenty, obsługę mniej standardowych protokołów na bazie dostarczonych interfejsów czy to w Service Mix czy to w Camelu.<br />
Przyjęte standardy gwarantują ciągłość rozwoju oraz ułatwiają integrację (<a href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/">JMX</a> umożliwia łatwe podpięcie konsoli administracyjnej), podczas gdy <a href="http://en.wikipedia.org/wiki/J2EE_Connector_Architecture">J2EE Connector Architecture</a> definiuje kontrakty (zarządzanie połączeniami, transakcjami, bezpieczeństwem).<br />
Nie bez znaczenia jest również koszt, jaki organizacja ponosi w przypadku zdecydowania się na otwarte rozwiązanie. Rozpoczęcie prac z Service Mix-em kosztuje 0 PLN. Każdy, bez rejestracji, podawania jakichkolwiek danych może pobrać źródła albo gotowe dystrybucje i uruchomić je na swoim komputerze. W chwili gdy istnieje takie zapotrzebowanie, organizacja posiada kompetencje i skromny budżet to taka konfiguracja początkowo jest optymalna. Z biegiem czasu gdy zaistnieje konieczność wsparcia czy szkoleń to są one oferowane przez firmę IONA, która jest zaangażowana w rozwój Service Mix-a.</p>
<h3>Service Mix a bezpieczeństwo</h3>
<p>Większość, jeśli nie wszystkie rozwiązania w Javie, które wiążą się z kryptografią są oparte na JCA – <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html">Java Cryptography Architecture</a>. Jest to zestaw interfejsów oraz ich implementacji zawierający implementację najpopularniejszych algorytmów kryptograficznych jak i <acronym title="Application Programming Interface">API</acronym> umożliwiające tworzenie własnych rozszerzeń (<a href="http://java.sun.com/javase/technologies/security/">JCE</a>).<br />
Standard autoryzacji i uwierzytelniania w Javie to JAAS (<a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html">Java Authentication and Authorization Service</a>). W oparciu o niego jest budowanych większość rozwiązań związanych z bezpieczeństwem. Nawet największe alternatywy takie jak <a href="http://www.acegisecurity.org/">Acegi Security</a> (obecnie Spring Security posiadają adaptery integrujące je ze standardem). Przy użyciu dostępnych interfejsów możliwe jest dostarczenie własnej implementacji usługi obsługującej autoryzację bądź uwierzytelnianie użytkowników/systemów.<br />
Bezpieczeństwo usług sieciowych jest zależne od wybranego komponentu Service Mix. Pełne wsparcie dla WS-Security oferują komponenty zbudowane w oparciu o Apache CXF (szyfrowanie, podpisywanie komunikatów). Z innych standardów CXF wspiera także WS-Policy, WS-Addressing.<br />
Szyfrowane połączenia są łatwe do uzyskania przy pomocy komponentu <a href="http://servicemix.apache.org/servicemix-http.html">servicemi-http</a>.<br />
Dostępne zabezpieczenia na poziomie wirtualnej maszyny Javy to certyfikowanie (podpisywanie) kodu modułów oraz konfiguracja Security Managera (umożliwia wyłączenie dostępu do pakietów/klas/metod).</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

