-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.json
1 lines (1 loc) · 120 KB
/
index.json
1
[{"content":"Po dłuższym czasie braku aktywności na tym blogu - postanowiłem przenieść część z postów, które zostały na nim opublikowane do nowego blogu, który tyczy się kwestii java, middleware itd. pod adresem dywicki.pl. Być może zawitają tam inne języki. :) Wszystkie pozostałe posty są i nadal będą dostępne. Zmiany są podyktowane tym, że jest mi trudno prowadzić blog jednoosobowej firmy i developerski zarazem. Stąd też decyzja o stworzeniu tylko jednego - developerskiego.\nDla osób, które jeszcze subskrybują kanały RSS z tego bloga - proszę o przepięcie na nowy adres - dywicki.pl, na pewno nie pożałujecie. Nowy blog z pewnością będzie aktualizowany częściej niż ten. :)\n","permalink":"http://localhost:1313/2011/06/przeprowadzka/","summary":"\u003cp\u003ePo dłuższym czasie braku aktywności na tym blogu - postanowiłem przenieść część z postów, które zostały na nim opublikowane do nowego blogu, który tyczy się kwestii java, middleware itd. pod adresem \u003ca href=\"http://dywicki.pl\"\u003edywicki.pl\u003c/a\u003e. Być może zawitają tam inne języki. :) Wszystkie pozostałe posty są i nadal będą dostępne. Zmiany są podyktowane tym, że jest mi trudno prowadzić blog jednoosobowej firmy i developerski zarazem. Stąd też decyzja o stworzeniu tylko jednego - developerskiego.\u003c/p\u003e","title":"Przeprowadzka"},{"content":"I work with Apache Karaf almost every day. There is a lot of commands provided by default and most of them are a bit anonymous. In this post I would like introduce these commands.\nList bundles Common command executed in Karaf shell is list. There is few switches which makes this command more usable. First of them is -l which shows bundle locations, second is -t. Second switch is available from Karaf 2.1.\nBelow example output of these commands:\n__ __ ____ / //_/____ __________ _/ __/ / ,\u0026lt; / __ `/ ___/ __ `/ /_ / /| |/ /_/ / / / /_/ / __/ /_/ |_|\\__,_/_/ \\__,_/_/ Apache Karaf (2.1.2) Hit \u0026#39;\u0026lt;tab\u0026gt;\u0026#39; for a list of available commands and \u0026#39;[cmd] --help\u0026#39; for help on a specific command. Hit \u0026#39;\u0026lt;ctrl-d\u0026gt;\u0026#39; or \u0026#39;osgi:shutdown\u0026#39; to shutdown Karaf. karaf@root\u0026gt; list -l START LEVEL 100 , List Threshold: 50 ID State Blueprint Spring Level Location [ 34] [Resolved ] [ ] [ ] [ 60] mvn:org.apache.geronimo.specs/geronimo-servlet_2.5_spec/1.1.2 [ 39] [Active ] [ ] [ ] [ 60] mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jetty/6.1.25_1 karaf@root\u0026gt; list -l -t 0 START LEVEL 100 , List Threshold: 0 ID State Blueprint Spring Level Location [ 0] [Active ] [ ] [ ] [ 0] System Bundle [ 1] [Active ] [ ] [ ] [ 5] mvn:org.ops4j.pax.url/pax-url-mvn/1.2.1 [ 2] [Active ] [ ] [ ] [ 5] mvn:org.ops4j.pax.url/pax-url-wrap/1.2.1 [ 3] [Active ] [ ] [ ] [ 8] mvn:org.ops4j.pax.logging/pax-logging-api/1.5.3 [ 4] [Active ] [ ] [ ] [ 8] mvn:org.ops4j.pax.logging/pax-logging-service/1.5.3 [ 5] [Active ] [ ] [ ] [ 10] mvn:org.apache.felix/org.apache.felix.configadmin/1.2.4 [ 6] [Active ] [ ] [ ] [ 11] mvn:org.apache.felix/org.apache.felix.fileinstall/3.0.2 [ 7] [Active ] [Created ] [ ] [ 20] mvn:org.apache.aries.blueprint/org.apache.aries.blueprint/0.2-incubating [ 8] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.config/2.1.2 [ 9] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.admin/org.apache.karaf.admin.command/2.1.2 [ 10] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf/org.apache.karaf.management/2.1.2 [ 11] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.spring/2.1.2 [ 12] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.features/org.apache.karaf.features.core/2.1.2 [ 13] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.shell/org.apache.karaf.shell.packages/2.1.2 [ 14] [Active ] [ ] [ ] [ 30] mvn:org.apache.aries.jmx/org.apache.aries.jmx.blueprint/0.2-incubating [ 15] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.modules/2.1.2 [ 16] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.shell/org.apache.karaf.shell.ssh/2.1.2 [ 17] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.features/org.apache.karaf.features.management/2.1.2 [ 18] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.features/org.apache.karaf.features.command/2.1.2 [ 19] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.shell/org.apache.karaf.shell.log/2.1.2 [ 20] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.admin/org.apache.karaf.admin.core/2.1.2 [ 21] [Active ] [ ] [ ] [ 30] mvn:org.apache.aries.jmx/org.apache.aries.jmx/0.2-incubating [ 22] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.blueprint/2.1.2 [ 23] [Active ] [ ] [ ] [ 30] mvn:org.apache.mina/mina-core/2.0.0-RC1 [ 24] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.shell/org.apache.karaf.shell.dev/2.1.2 [ 25] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.shell/org.apache.karaf.shell.osgi/2.1.2 [ 26] [Active ] [ ] [ ] [ 30] mvn:org.apache.sshd/sshd-core/0.4.0 [ 27] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.shell/org.apache.karaf.shell.commands/2.1.2 [ 28] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.features/2.1.2 [ 29] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.shell/org.apache.karaf.shell.console/2.1.2 [ 30] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.admin/org.apache.karaf.admin.management/2.1.2 [ 32] [Active ] [Created ] [ ] [ 30] mvn:org.apache.karaf.shell/org.apache.karaf.shell.config/2.1.2 [ 34] [Resolved ] [ ] [ ] [ 60] mvn:org.apache.geronimo.specs/geronimo-servlet_2.5_spec/1.1.2 [ 39] [Active ] [ ] [ ] [ 60] mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jetty/6.1.25_1 As you see first comman returns short list which contains bundles installed by me (servlet api and jetty). Second list contains bundles default installed also by Karaf. Another usefull switch is -s which shows symbolic names:\nkaraf@root\u0026gt; list -s START LEVEL 100 , List Threshold: 50 ID State Blueprint Spring Level Symbolic name [ 34] [Resolved ] [ ] [ ] [ 60] org.apache.geronimo.specs.geronimo-servlet_2.5_spec (1.1.2) [ 39] [Active ] [ ] [ ] [ 60] org.apache.servicemix.bundles.jetty (6.1.25.1) Switch -t may be mixed with both -s and -l.\nList services After first impression with OSGi and bundles as modules most of us moving to using OSGi services. That\u0026rsquo;s really cool stuff and gives a lot of fun, but without helper commands we may stuck. Karaf provides command named ls which shows services exported by given bundle.\nkaraf@root\u0026gt; ls 132 Apache Karaf :: Web Console :: Admin Plugin (132) provides: ----------------------------------------------------------- osgi.service.blueprint.compname = adminPlugin felix.webconsole.label = admin objectClass = javax.servlet.Servlet service.id = 176 ---- osgi.blueprint.container.version = 2.1.2 osgi.blueprint.container.symbolicname = org.apache.karaf.webconsole.admin objectClass = org.osgi.service.blueprint.container.BlueprintContainer service.id = 178 If we would check which services are in use by our bundle we have very usefull switch -u.\nkaraf@root\u0026gt; ls -u 21 Apache Aries JMX Bundle (21) uses: ---------------------------------- service.vendor = Apache Software Foundation service.pid = org.apache.felix.cm.ConfigurationAdmin service.description = Configuration Admin Service Specification 1.2 Implementation objectClass = org.osgi.service.cm.ConfigurationAdmin service.id = 33 List packages When you work under OSGi it\u0026rsquo;s important which packages you import and export. The two commands packages:imports and packages:exports will simply show what\u0026rsquo;s comes and goes from your bundle. I\u0026rsquo;ll not show how these commands work but I have little trick for you. When you\u0026rsquo;re unable to resolve bundle because you have missing import packages and you have ClassNotFoundException type dev:dynamic-import bundleid command. This command add DynamicImport-Package: * entry to bundle manifest. After that, when you\u0026rsquo;ll resolve bundle type packages:imports and check complete list of import you missed in your headers.\nFeatures All commands shown above are strictly related to OSGi. But Karaf is a little bigger and allow you do more than OSGi execution environment. One of tools which Karaf build on top of OSGi framework is features mechanism. You may define list of things to install and add dependencies between them instead typing install command line after line. But sometimes you would like to check what given feature contains. To do that type features:info command. This command requires feature name as argument.\nkaraf@root\u0026gt; features:info webconsole Description of webconsole 2.1.2 feature ---------------------------------------------------------------- Feature has no configuration Feature depends on: webconsole-base 2.1.2 Feature contains followed bundles: mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.admin/2.1.2 mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.features/2.1.2 mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.gogo/2.1.2 You may use few additional switches: -b, -d, -c. First shows bundles in feature, second bundle dependencies and last feature configuration. We have also another switch -t which shows all these informations plus tree of features and it\u0026rsquo;s bundles.\nkaraf@root\u0026gt; features:info -t webconsole Description of webconsole 2.1.99-SNAPSHOT feature ---------------------------------------------------------------- Feature has no configuration Feature depends on: webconsole-base 2.1.99-SNAPSHOT Feature contains followed bundles: mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.admin/2.1.99-SNAPSHOT mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.features/2.1.99-SNAPSHOT mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.gogo/2.1.99-SNAPSHOT Feature tree webconsole 2.1.99-SNAPSHOT + mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.admin/2.1.99-SNAPSHOT + mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.features/2.1.99-SNAPSHOT \\ mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.gogo/2.1.99-SNAPSHOT webconsole-base 2.1.99-SNAPSHOT + mvn:org.apache.felix/org.apache.felix.metatype/1.0.4 + mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.branding/2.1.99-SNAPSHOT \\ mvn:org.apache.felix/org.apache.felix.webconsole/3.1.6 http 2.1.99-SNAPSHOT + mvn:org.ops4j.pax.web/pax-web-api/0.8.1 + mvn:org.ops4j.pax.web/pax-web-spi/0.8.1 + mvn:org.ops4j.pax.web/pax-web-runtime/0.8.1 \\ mvn:org.ops4j.pax.web/pax-web-jetty/0.8.1 jetty [7.0,8.0) * Tree contains 1 unresolved dependencies * means that node declares dependency but the dependant feature is not available. Development commands I mentioned dev:dynamic-import command before. But Karaf have few more commands which makes development easier. First of all is dev:show-tree which shows bundles tree, for example:\nkaraf@root\u0026gt; dev:show-tree 39 Bundle dump [39] is currently ACTIVE dump [39] +- org.apache.karaf.diagnostic.core [16] +- org.apache.aries.blueprint [7] +- org.apache.felix.configadmin [5] | +- org.ops4j.pax.logging.pax-logging-api [3] +- org.ops4j.pax.logging.pax-logging-api [3] Another command you may use is dev:framework which allows you change OSGi framework used by Karaf. I don\u0026rsquo;t use this command to often.\nLast command I would introduce is dev:create-dump commited to Karaf trunk by me. This command creates zip archive which contains diagnostic stuff you may attach to JIRA or send to developers in your company to check what was wrong. By default dumps contains log entries from $KARAF_BASE/data/log, list of installed bundles and features. You may also create new diagnostic providers. Sample code is available in SVN: demo, provider class, blueprint config.\nComplete Remember that every Karaf command can be executed with \u0026ndash;help switch which shows all arguments and switches. In this post you was introduced to following commands:\nlist and switches -t -l -s ls and -u switch packages:imports, packages:exports, dev:dynamic-import features:info and switches -b -d -c and -t dev:show-tree, dev:framework, dev:create-dump ","permalink":"http://localhost:1313/2010/12/apache-karaf-commands-rediscovered/","summary":"\u003cp\u003eI work with Apache Karaf almost every day. There is a lot of commands provided by default and most of them are a bit anonymous. In this post I would like introduce these commands.\u003c/p\u003e\n\u003ch2 id=\"list-bundles\"\u003eList bundles\u003c/h2\u003e\n\u003cp\u003eCommon command executed in Karaf shell is \u003cstrong\u003elist\u003c/strong\u003e. There is few switches which makes this command more usable. First of them is \u003cstrong\u003e-l\u003c/strong\u003e which shows bundle locations, second is \u003cstrong\u003e-t\u003c/strong\u003e. Second switch is available from Karaf 2.1.\u003c/p\u003e","title":"Apache Karaf commands rediscovered"},{"content":"UiBinder jest rozszerzeniem, które pozwala nam szybko i bardzo przyjemnie stworzyć widok okienka w XML\u0026rsquo;u. Dzięki niemu możemy oddzielić widok aplikacji webowej od logiki ją obsługującej w czystym GWT. Sposób używania UiBinder\u0026rsquo;a jest bardzo dobrze opisany. Jednak już po chwili korzystania z tego narzędzia wraz z klasami dostępnymi standardowo w GWT odczujemy mały niedosyt, że potrzebujemy tworzyć własne widgety, które będą kompatybilne z UiBinder\u0026rsquo;em albo będziemy musieli zrezygnować całkowicie z tego narzędzia.\nW tym wpisie właśnie chciałbym przedstawić sposób stworzenia własnego prostego widget\u0026rsquo;u. Będzie nim pole do wpisywania hasła, wraz z labelk\u0026rsquo;ą opisującą do czego to pole służy. Naszym celem jest stworzenie widget\u0026rsquo;u który wygląda mniej więcej tak:\nPrzejdźmy do kodu, stwórzmy klasę reprezentującą widget:\n[sourcecode language=\u0026ldquo;java\u0026rdquo;] // Copyright (C) 2010 Code-House // All rights reserved package com.hqcargo.shippingstock.client.application.view.widget.form;\nimport com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.PasswordTextBox; import com.hqcargo.shippingstock.client.application.view.widget.LabelWidget;\n/\\\\ \\* Widget zawierający pole label opisu, wpisywania hasła, a także label \\* w którym będzie wyświetlany błąd. Klasa musi dziedziczyć po Widgecie, \\* w naszym wypadku dziedziczy pośrednio po FlowPanel\u0026rsquo;u, na którym są \\* rysowane elementy naszego Widget\u0026rsquo;u. \\* \\* @author Michał Rowicki */ public class PasswordWidget extends FlowPanel {\n//Wszystkie pola /\\\\ \\* Etykieta pola. */ LabelWidget label;\n/\\\\ \\* Etykieta błędu. */ Label errorLabel;\n/\\\\ \\* Pole, które musi rozszerzać klasę Widget. \\* {@link com.google.gwt.user.client.ui.Widget} */ PasswordTextBox pass;\n/\\\\ \\* Wartość id używana we wszelkich formularzach, by można było \\* cache\u0026rsquo;ować dane wpisane do ramki i później by były wczytywane \\* w przeglądarce. */ String id;\n/\\\\ \\* Należy stworzyć konstruktor bezargumentowy tak by framework \\* UiBinder\u0026rsquo;a mógł stworzyć instancję naszego obiektu i później \\* sam ją wypełnił. Jeżeli chcemy móc tworzyć widgety z danymi \\* ładowanymi w Javie musimy skorzystać z @UiFactory \\* {@link http://code.google.com/intl/pl/webtoolkit/doc/latest/DevGuideUiBinder.html#Share_resource_instances} \\* W konstruktorze musimy zainicjować wszystkie pola by móc \\* później z nich korzystać. */ public PasswordWidget() { pass = new PasswordTextBox();\nlabel = new LabelWidget(); //ustawienie atrybutu class, by móc podpiąć własne CSS\u0026rsquo;y label.setStyleName(\u0026ldquo;item_label\u0026rdquo;);\nerrorLabel = new Label(); errorLabel.setStyleName(\u0026ldquo;error_label\u0026rdquo;);\nadd(label); add(pass); add(errorLabel);\n//ustawienie atrybutu class dla całego FlowPanelu setStylePrimaryName(\u0026ldquo;item\u0026rdquo;); }\n//by nasza aplikacja działała poprawnie musimy utworzyć gettersy i settersy dla pól klasy\n/\\\\ \\* Pobranie wartości pola label. \\* \\* @return Wartość label */ public final LabelWidget getLabel() { return label; }\n/\\\\ \\* Ustawienie wartości pola label. \\* \\* @param Podaj label */ public final void setLabel(LabelWidget label) { this.label = label; }\n/\\\\ \\* Pobranie wartości pola errorLabel. \\* \\* @return Wartość errorLabel */ public final Label getErrorLabel() { return errorLabel; }\n/\\\\ \\* Ustawienie wartości pola errorLabel. \\* \\* @param Podaj errorLabel */ public final void setErrorLabel(Label errorLabel) { this.errorLabel = errorLabel; }\n/\\\\ \\* Pobranie wartości pola pass. \\* \\* @return Wartość pass */ public final PasswordTextBox getPass() { return pass; }\n/\\\\ \\* Ustawienie wartości pola pass. \\* \\* @param Podaj pass */ public final void setPass(PasswordTextBox pass) { this.pass = pass; }\n/\\\\ \\* Pobranie wartości pola id. \\* \\* @return Wartość id */ public final String getId() { return id; }\n//ustawia wartość pola id dla obiektu pass\n/\\\\ \\* Ustawienie Id pola. \\* \\* @param id Identyfikator pola. */ public final void setFieldId(final String id) { this.id = id;\npass.getElement().setId(id); label.setFor(id); } }\n[/sourcecode]\nUżycie naszego widget\u0026rsquo;u w pliku *.ui.xml jest bardzo proste należy jedynie dodać w polu UiBinder xmlns:dowolna_nazwa=\u0026quot;urn:import:nazwa_paczki\u0026quot;. A następnie w ciele HTMLPanela dodać pole dowolna_nazwa:PasswordWidget i uzupełnić odpowiednio pola, np:\n[sourcecode language=\u0026ldquo;xml\u0026rdquo;]\n\u003c!DOCTYPE ui:UiBinder SYSTEM \"http://dl.google.com/gwt/DTD/xhtml.ent\"\u003e \u0026lt;ui:UiBinder xmlns:ui=\u0026ldquo;urn:ui:com.google.gwt.uibinder\u0026rdquo; xmlns:widget=\u0026ldquo;urn:import:client.application.view.widget\u0026rdquo; xmlns:gwt=\u0026ldquo;urn:import:com.google.gwt.user.client.ui\u0026rdquo;\u0026gt;\n\u0026lt;gwt:HTMLPanel tag=\u0026ldquo;div\u0026rdquo;\u0026gt;\n\u0026lt;widget:PasswordWidget fieldId=\u0026ldquo;password\u0026rdquo; fieldLabel=\u0026ldquo;Hasło\u0026rdquo; ui:field=\u0026ldquo;password\u0026rdquo; /\u0026gt;\n\u0026lt;/gwt:HTMLPanel\u0026gt; \u0026lt;/ui:UiBinder\u0026gt; [/sourcecode]\nW ten oto sposób stworzyliśmy najprostszy własny widget który możemy użyć w UiBinderze.\nTutaj załączam cały działający projekt Eclipse\u0026rsquo;a z naszym własnym widgetem (należy przed uruchomieniem zainstalować SDK GWT).\n","permalink":"http://localhost:1313/2010/10/wlasny-widget-w-uibinderze/","summary":"\u003cp\u003e\u003ca href=\"http://code.google.com/intl/pl/webtoolkit/doc/latest/DevGuideUiBinder.html\" title=\"UiBinder\"\u003eUiBinder\u003c/a\u003e jest rozszerzeniem, które pozwala nam szybko i bardzo przyjemnie stworzyć widok okienka w XML\u0026rsquo;u. Dzięki niemu możemy oddzielić widok aplikacji webowej od logiki ją obsługującej w czystym \u003ca href=\"http://code.google.com/intl/pl/webtoolkit/\" title=\"GWT\"\u003eGWT\u003c/a\u003e. Sposób używania UiBinder\u0026rsquo;a jest bardzo dobrze opisany. Jednak już po chwili korzystania z tego narzędzia wraz z klasami dostępnymi standardowo w GWT odczujemy mały niedosyt, że potrzebujemy tworzyć własne widgety, które będą kompatybilne z UiBinder\u0026rsquo;em albo będziemy musieli zrezygnować całkowicie z tego narzędzia.\u003c/p\u003e","title":"Własny widget w UiBinderze"},{"content":"Tegoroczna edycja konferencji Javarsovia jest bez wątpienia największym wydarzeniem tej kategorii w Polsce. Grono sponsorów i partnerów nafaszerowane gigantycznymi korporacjami ( IBM, Oracle, Microsoft, Adobe, Google). Pomyśleć, że Code-House w zeszłym roku był sponsorem tej niewielkiej konferencji a w tym roku nie przyszło by nam rywalizować nawet o ławkę sponsorów rezerwowych. :-) Moje gratulacje dla kapituły przekazuję już teraz.\nWróćmy jednak do meritum - a mianowicie czego brakuje na Javarsovii. :-) Brakuje prelekcji o OSGi, które mimo porządnego wieku (10 lat) jest w dalszym ciągu nowością dla wielu developerów. Szczęśliwie, w ramach spotkań Warszawa JUG było zaplanowane spotkanie pt. Springowe spojrzenie na OSGi - Spring Dynamic Modules for OSGi(tm) - które miał poprowadzić Jacek Lis. Niestety, Jacek w planowanym terminie (15 czerwiec) będzie poza Warszawą. Aby obronić OSGi i załatać deficyt tego tematu na Javarsovii (zgłaszałem się z OSGi R4.2 Enterprise do C4P), postanowiłem zastąpić Jacka i poprowadzić prezentację - której temat również ewoluował na Spring Dynamic Modules, Blueprint, OSGi - deklaratywne.\nPodsumowując, czego można się spodziewać w najbliższy wtorek:\nCelem prezentacji jest przedstawienie OSGi. Tradycyjne podejście do usług w OSGi. Co dodaje Spring DM/Blueprint. Jak to uruchomić na Karafie 1 Serdecznie zapraszam wszystkich zainteresowanych jak i zawiedzionych tym, że OSGi nie będzie na Javarsovii. :-)\n1 Trwają negocjacje, czy Apache Felix Karaf zostanie projektem wysokiego poziomu (TLP) fundacji Apache.\n","permalink":"http://localhost:1313/2010/06/brakujacy-element-javarsovii/","summary":"\u003cp\u003eTegoroczna edycja konferencji Javarsovia jest bez wątpienia największym wydarzeniem tej kategorii w Polsce. Grono sponsorów i partnerów nafaszerowane gigantycznymi korporacjami ( \u003ca href=\"http://www.javarsovia.pl/news/33/72/IBM-partnerem-konferencji.html\"\u003eIBM\u003c/a\u003e, \u003ca href=\"http://www.javarsovia.pl/news/32/72/Oracle-Zlotym-Sponsorem.html\"\u003eOracle\u003c/a\u003e, \u003ca href=\"http://www.javarsovia.pl/news/27/72/Microsoft-Zlotym-Sponsorem-Javarsovii-2010.html\"\u003eMicrosoft\u003c/a\u003e, \u003ca href=\"http://www.javarsovia.pl/news/16/72/Adobe-sponsorem-Javarsovii-2010.html\"\u003eAdobe\u003c/a\u003e, \u003ca href=\"http://www.javarsovia.pl/news/20/72/Google-zlotym-sponsorem-Javarsovia-2010.html\"\u003eGoogle\u003c/a\u003e). Pomyśleć, że Code-House w zeszłym roku był sponsorem tej niewielkiej konferencji a w tym roku nie przyszło by nam rywalizować nawet o ławkę sponsorów rezerwowych. :-) Moje gratulacje dla kapituły przekazuję już teraz.\u003c/p\u003e\n\u003cp\u003eWróćmy jednak do meritum - a mianowicie czego brakuje na Javarsovii. :-) Brakuje prelekcji o OSGi, które mimo porządnego wieku (10 lat) jest w dalszym ciągu nowością dla wielu developerów. Szczęśliwie, w ramach spotkań \u003ca href=\"http://groups.google.com/group/warszawa-jug/\"\u003eWarszawa JUG\u003c/a\u003e było zaplanowane spotkanie pt. \u003cstrong\u003eSpringowe spojrzenie na OSGi - Spring Dynamic Modules for OSGi(tm)\u003c/strong\u003e - które miał poprowadzić Jacek Lis. Niestety, Jacek w planowanym terminie (15 czerwiec) będzie poza Warszawą. Aby obronić OSGi i załatać deficyt tego tematu na Javarsovii (zgłaszałem się z OSGi R4.2 Enterprise do C4P), postanowiłem zastąpić Jacka i poprowadzić prezentację - której temat również ewoluował na \u003cstrong\u003eSpring Dynamic Modules, Blueprint, OSGi - deklaratywne\u003c/strong\u003e.\u003c/p\u003e","title":"Brakujący element Javarsovii"},{"content":"Jakiś czas temu Jacek Laskowski wspominał o praktykach studenckich w IBM.\nCelem praktyk w IBM jest zapoznanie się z produktami korporacji, praktyki w Code-House mają nieco inny wymiar - przede wszystkim technologiczny. Część z dziedzin, w których obracamy się obecnie przy okazji ServiceMixa jest nieco futurystyczna (OSGi R 4.2, dOSGi), część za to bardzo praktyczna np. szerokie użycie Mavena oraz Spring Framework czy JAX-WS/JAX-RS. Cały kod, który powstanie w wyniku praktyk będzie opublikowany na licencji Apache 2.0 i udostępniony publicznie.\nPula tematów dla praktykantów obejmuje następujące projekty fundacji Apache:\nApache ServiceMix 4 Apache Ode Apache ActiveMQ Apache Camel Apache Karaf Organizacja praktyk Praktyki są bezpłatne (niestety), odbywają się w trybie zdalnym i trwają do 3 miesięcy - termin rozpoczęcia praktyk jest uzgadniany ze studentem. Nie ma konieczności przebywania w naszym biurze - cały proces naboru aplikacji odbywa się przy pomocy Internetu i dopiero ostatni etap - rozmowa kwalifikacyjna - wymaga spotkania. Na co dzień konsultacje będziemy odbywać przy pomocy komunikatorów - Skype, GTalk, w skrajnym wypadku Gadu-Gadu. ;-) Co dwa tygodnie podsumowujemy minioną \u0026ldquo;iterację\u0026rdquo; oraz planujemy następną. Po wprowadzeniu do narzędzi i projektów studenci będą wypływać na głębokie wody - czyli samodzielną realizację zadań.\nDo zarządzania, koordynacji zadań oraz dokumentacji i weryfikacji kodu wykorzystujemy narzędzia Atlassian:\nJIRA Green Hopper Confluence Bamboo Fisheye Jak aplikować? Jedyną wymaganą cechą jest znajomość języka Java - która zostanie zweryfikowana testem. Jeśli dysponujesz tą cechą i jesteś miłośnikiem technologii zapraszamy do wysyłania aplikacji pod adres [email protected] z tematem Praktyki 2010. Nabór aplikacji na najbliższą edycję praktyk prowadzimy do 20 kwietnia. W zależności od rezultatów będą organizowane kolejne. Nieco więcej informacji znajdziecie na stronie Praktyki Studenckie 2010.\n","permalink":"http://localhost:1313/2010/04/praktyki-studenckie-w-code-house/","summary":"\u003cp\u003eJakiś czas temu \u003ca href=\"http://jaceklaskowski.pl/\"\u003eJacek Laskowski\u003c/a\u003e wspominał o \u003ca href=\"http://jlaskowski.blogspot.com/2010/03/praktyki-studenckie-w-ibm-ta-edycja.html\"\u003epraktykach studenckich w IBM\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eCelem praktyk w IBM jest zapoznanie się z produktami korporacji, praktyki w Code-House mają nieco inny wymiar - przede wszystkim technologiczny. Część z dziedzin, w których obracamy się obecnie przy okazji ServiceMixa jest nieco futurystyczna (OSGi R 4.2, dOSGi), część za to bardzo praktyczna np. szerokie użycie Mavena oraz Spring Framework czy JAX-WS/JAX-RS. \u003cstrong\u003eCały kod, który powstanie w wyniku praktyk będzie opublikowany na licencji Apache 2.0 i udostępniony publicznie\u003c/strong\u003e.\u003c/p\u003e","title":"Praktyki studenckie w Code-House"},{"content":"W tym wpisie zostanie omówiony proces OSGi-fikacji artefaktów, który przechodziłem gdy uruchamiałem prostą usługę na ServiceMix, która miała śledzić zewnętrzny RSS i pobierać z niego wpisy. Postanowiłem skorzystać z camel-rss. Przykłady które były do niego załączone są wystarczające by stworzyć odpowiedniego konsumenta\u0026hellip;\nProblem zaczął się gdy usiłowałem uruchomić endpoint camela w OSGi. Mimo poprawnej konfiguracji, rozwiązanych zależności otrzymywałem wyjątek: [code]java.lang.NoClassDefFoundError: Could not initialize class com.sun.syndication.feed.synd.SyndFeedImpl at com.sun.syndication.io.SyndFeedInput.build(SyndFeedInput.java:123) at org.apache.camel.component.rss.RssUtils.createFeed(RssUtils.java:34) at org.apache.camel.component.rss.RssEntryPollingConsumer.createFeed(RssEntryPollingConsumer.java:54) at org.apache.camel.component.feed.FeedEntryPollingConsumer.poll(FeedEntryPollingConsumer.java:42) at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:106) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) [/code] Naturalnie, strasznie zirytowany, wziąłem się za dochodzenie - początkowo byłem przekonany że brakuje importów w camel-rss jednakże krótkie googlowanie wskazało rozwiązanie. Winne było kilka linii w klasie PluginManager: [code language=\u0026ldquo;java\u0026rdquo;] private Class[] getClasses() throws ClassNotFoundException { // Ten ClassLoader wskazuje na bundle w którym jest zdefiniowany endpoint! ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); List classes = new ArrayList(); boolean useLoadClass = Boolean.valueOf(System.getProperty(\u0026ldquo;rome.pluginmanager.useloadclass\u0026rdquo;, \u0026ldquo;false\u0026rdquo;)).booleanValue(); for (int i = 0; i \u0026lt;_propertyValues.length; i++) { // Naturalnie tutaj leciał ClassNotFoundException Class mClass = (useLoadClass ? classLoader.loadClass(_propertyValues[i]) : Class.forName(_propertyValues[i], true, classLoader)); classes.add(mClass); } Class[] array = new Class[classes.size()]; classes.toArray(array); return array; } [/code]\nPo przeróbce metoda wygląda następująco. [code language=\u0026ldquo;java\u0026rdquo;] private Class[] getClasses() throws ClassNotFoundException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); List classes = new ArrayList(); boolean useLoadClass = Boolean.valueOf(System.getProperty(\u0026ldquo;rome.pluginmanager.useloadclass\u0026rdquo;, \u0026ldquo;false\u0026rdquo;)).booleanValue(); for (int i = 0; i \u0026lt;_propertyValues.length; i++) { Class mClass = null; try { if (useLoadClass) { mClass = classLoader.loadClass(_propertyValues[i]); } else { mClass = Class.forName(_propertyValues[i], true, classLoader); } } catch (ClassNotFoundException e) { // Jeśli zewnętrzny class loader zgłosi wyjątek usiłujemy załadować klasę // z bieżącej paczki mClass = getClass().getClassLoader().loadClass(_propertyValues[i]); } classes.add(mClass); } Class[] array = new Class[classes.size()]; classes.toArray(array); return array; } [/code]\nNaturalnie, można się zastanawiać po co bibliotece do obsługi RSS zabiegi z ClassLoaderami. Otóż ROME wykorzystuje plik .properties do konfiguracji \u0026ldquo;pluginów\u0026rdquo; (poors man DI). W określonych miejscach możemy dodać własne klasy które obsłużą jakiś niestandardowy format. Problem w tym, że \u0026ldquo;patent\u0026rdquo; z plikiem properties świetnie sprawdza się przy płaskim classloaderze, niestety zawodzi w OSGi. Należy pamiętać o tym, że w OSGi nasz class loader ma dostęp do tego, do czego mu pozwalają importy i nie wszystko to, co widzi nasze oko w archiwum musi być dostępne dla naszego programu.\nPrzy okazji stworzenia bundle z ROME 1.0 postanowiłem również stworzyć bundle dla Apache POI 3.6. Bibliotekę tą wykorzystywałem wspólnie z Tomkiem Nurkiewiczem podczas prezentacji \u0026ldquo;Mule ESB vs ServiceMix\u0026rdquo;.\nOSGi-fikacja Bardzo swobodna definicja:\nOSGi-fikacja to proces mający na celu stworzenie działającego bundle z istniejącej już biblioteki. Wiele z projektów nie dostarczają poprawnych z punktu widzenia frameworku OSGi manifestów, czasami są budowane poprzez Ant bądź w ogóle są dostępne tylko ich binarne wersje co utrudnia analizę. Proces ten w większości przypadków sprowadza się do analizy zależności klas (importów) oraz zadeklarowanych klas (eksportów). W skrajnych wypadkach konieczna jest dodanie kodu bądź podmiana jego fragmentów tak by nie powodowały problemów po uruchomieniu. W celu zachowania porządku w publicznych repozytoriach Mavena stworzone w ten sposób archiwa są zapisywane z innym ArtifactId bądź GroupId, natomiast z zachowaniem oryginalnej wersji.\nNie aspiruję do miana człowieka który tworzy nowe pojęcia. Ten nieco przydługi wywód ma na celu jedynie przybliżenie działań które czasami są konieczne do uzyskania biblioteki działającej w OSGi.\nNa potrzeby przykładu OSGi-fikacji wybrałem log4j, jako popularną bibliotekę z małym zbiorem zależności. Wersja 1.2.12 nie zawiera poprawnego manifestu OSGi przez co nie można jej użyć pod Equinoxem czy Felixem. Zależności które ma log4j takie jak:\njavax.mail javax.swing javax.naming javax.activation javax.management com.sun.jdmk.comm Są opcjonalne, co znaczy że biblioteka bez problemów uruchomi się jeśli nie uda się zaimportować wyżej wymienionych paczek. Określimy zatem ich resolution na optional.\nPozostałe zależności wymienione poniżej są wymagane by móc odczytać plik log4j.xml:\norg.w3c.dom javax.xml.parsers org.xml.sax Poniżej znajduje się pom.xml który przygotowałem po to by zaprezentować użycie wcześniej wspomnianych pluginów. Pom ten ma skutkować stworzeniem artefaktu OSGi gotowego do uruchomienia pod Kara-fem. [code language=\u0026ldquo;xml\u0026rdquo;] 4.0.0\norg.apache.servicemix.bundles bundles-pom 4 org.apache.servicemix.bundles org.apache.servicemix.bundles.log4j 1.2.12-SNAPSHOT bundle Apache ServiceMix Bundles: ${pkgArtifactId}-${pkgVersion} This bundle simply wraps ${pkgArtifactId}-${pkgVersion}.jar. \u003c!\\-\\- Zmienne dla maven-bundle-plugin --\u003e org.apache.log4j\\*;version=${pkgVersion} \u003c!\\-\\- Zależności opcjonalne --\u003e com.sun.jdmk.comm;resolution:=optional, javax.jms;resolution:=optional, javax.mail\\*;resolution:=optional, javax.management;resolution:=optional, javax.naming;resolution:=optional, javax.swing\\*;resolution:=optional, \\\\* \u003c!\\-\\- Wszystkie inne zależności jakie doda analizator --\u003e \u003c!\\-\\- Zmienne artefaktu --\u003e log4j log4j 1.2.12 \u003c!\\-\\- zależność do log4j --\u003e ${pkgGroupId} ${pkgArtifactId} ${pkgVersion} true \u003c!\\-\\- Kopiowanie plików .class --\u003e org.apache.maven.plugins maven-shade-plugin package shade ${pkgGroupId}:${pkgArtifactId} ${pkgGroupId}:${pkgArtifactId} \\*\\* true true \\[/code\\] Teraz pora na instalację bundla na szynie:\n____ _ __ __ _ / ___| ___ _ ____ _(_) ___ ___| \\/ (_)_ __ \\___ \\ / _ \\ \u0026#39;__\\ \\ / / |/ __/ _ \\ |\\/| | \\ \\/ / ___) | __/ | \\ V /| | (_| __/ | | | |\u0026gt; \u0026lt; |____/ \\___|_| \\_/ |_|\\___\\___|_| |_|_/_/\\_\\ Apache ServiceMix (4.2.0-fuse-01-00) Hit \u0026#39;\u0026lt;tab\u0026gt;\u0026#39; for a list of available commands and \u0026#39;[cmd] --help\u0026#39; for help on a specific command. karaf@root\u0026gt; karaf@root\u0026gt; install mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.log4j/1.2.12-SNAPSHOT Bundle ID: 186 karaf@root\u0026gt; list|grep log4j [ 186] [Resolved ] [ ] [ ] [ 60] Apache ServiceMix Bundles: log4j-1.2.12 (1.2.12.SNAPSHOT) karaf@root\u0026gt; start 186 karaf@root\u0026gt; list|grep log4j [ 186] [Active ] [ ] [ ] [ 60] Apache ServiceMix Bundles: log4j-1.2.12 (1.2.12.SNAPSHOT) karaf@root\u0026gt; packages:imports 186 OSGi System Bundle (0): javax.management; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): javax.naming; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): javax.swing; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): javax.swing.border; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): javax.swing.event; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): javax.swing.table; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): javax.swing.text; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): javax.swing.tree; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): javax.xml.parsers; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): org.w3c.dom; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): org.xml.sax; version=\u0026#34;0.0.0\u0026#34; OSGi System Bundle (0): org.xml.sax.helpers; version=\u0026#34;0.0.0\u0026#34; OPS4J Pax Logging - API (3): org.apache.log4j.spi; version=\u0026#34;1.2.15\u0026#34; OPS4J Pax Logging - API (3): org.apache.log4j.xml; version=\u0026#34;1.2.15\u0026#34; OPS4J Pax Logging - API (3): org.apache.log4j; version=\u0026#34;1.2.15\u0026#34; geronimo-jms_1.1_spec (64): javax.jms; version=\u0026#34;1.1.0\u0026#34; Apache ServiceMix Bundles: mail-1.4.1 (86): javax.mail.internet; version=\u0026#34;1.4.1\u0026#34; Apache ServiceMix Bundles: mail-1.4.1 (86): javax.mail; version=\u0026#34;1.4.1\u0026#34; karaf@root\u0026gt; packages:exports 186 Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.util; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.net; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.viewer; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.jmx; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.jdbc; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.config; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.helpers; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.config; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.or.jms; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.nt; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.or.sax; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.viewer.categoryexplorer; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.or; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.chainsaw; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.varia; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.viewer.configure; version=\u0026#34;1.2.12\u0026#34; Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.viewer.images; version=\u0026#34;1.2.12\u0026#34; karaf@root\u0026gt; Jak widać wszystko działa i ma się dobrze. :) Jedyna uwaga jaką mam to by nie używać tak spreparowanego log4j. W specyfikacji OSGi R4 V4.2 Enterprise jest opisana usługa logująca. Oprócz niej jest jeszcze Pax Logging (używany przez Karafa) wspierająca kilka różnych bibliotek od log4j poprzez slf4j po wspomnianą usługę OSGi.\nPozdrawiam i życzę miłej OSGi-fikacji! :)\n","permalink":"http://localhost:1313/2010/03/osgi-new-bundles-servicemix-repository/","summary":"\u003cp\u003eW tym wpisie zostanie omówiony proces OSGi-fikacji artefaktów, który przechodziłem gdy uruchamiałem prostą usługę na ServiceMix, która miała śledzić zewnętrzny RSS i pobierać z niego wpisy. Postanowiłem skorzystać z camel-rss. Przykłady które były do niego załączone są wystarczające by stworzyć odpowiedniego konsumenta\u0026hellip;\u003c/p\u003e\n\u003cp\u003eProblem zaczął się gdy usiłowałem uruchomić endpoint camela w OSGi. Mimo poprawnej konfiguracji, rozwiązanych zależności otrzymywałem wyjątek:\n[code]java.lang.NoClassDefFoundError: Could not initialize class com.sun.syndication.feed.synd.SyndFeedImpl\nat com.sun.syndication.io.SyndFeedInput.build(SyndFeedInput.java:123)\nat org.apache.camel.component.rss.RssUtils.createFeed(RssUtils.java:34)\nat org.apache.camel.component.rss.RssEntryPollingConsumer.createFeed(RssEntryPollingConsumer.java:54)\nat org.apache.camel.component.feed.FeedEntryPollingConsumer.poll(FeedEntryPollingConsumer.java:42)\nat org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:106)\nat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)\nat java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)\nat java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)\nat java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)\nat java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)\nat java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)\nat java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)\nat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)\nat java.lang.Thread.run(Thread.java:619)\n[/code]\nNaturalnie, strasznie zirytowany, wziąłem się za dochodzenie - początkowo byłem przekonany że brakuje importów w camel-rss jednakże krótkie googlowanie \u003ca href=\"http://js.jipiju.com/2009/08/04/osgi-jumping-through-classoading-hoops/\"\u003ewskazało rozwiązanie\u003c/a\u003e. Winne było kilka linii w klasie PluginManager:\n[code language=\u0026ldquo;java\u0026rdquo;]\nprivate Class[] getClasses() throws ClassNotFoundException {\n// Ten ClassLoader wskazuje na bundle w którym jest zdefiniowany endpoint!\nClassLoader classLoader = Thread.currentThread().getContextClassLoader();\nList classes = new ArrayList();\nboolean useLoadClass = Boolean.valueOf(System.getProperty(\u0026ldquo;rome.pluginmanager.useloadclass\u0026rdquo;, \u0026ldquo;false\u0026rdquo;)).booleanValue();\nfor (int i = 0; i \u0026lt;_propertyValues.length; i++) {\n// Naturalnie tutaj leciał ClassNotFoundException\nClass mClass = (useLoadClass ? classLoader.loadClass(_propertyValues[i]) :\nClass.forName(_propertyValues[i], true, classLoader));\nclasses.add(mClass);\n}\nClass[] array = new Class[classes.size()];\nclasses.toArray(array);\nreturn array;\n}\n[/code]\u003c/p\u003e","title":"OSGi-fikacja oraz nowe bundle w repozytorium ServiceMix"},{"content":"Dnia dzisiejszego została wydana finalna wersja specyfikacji OSGi R4 V4.2 Enterprise. Wersja jest gotowa do pobrania pod adresem http://www.osgi.org/Download/Release4V42. Dokument ma 483 strony. :-)\n","permalink":"http://localhost:1313/2010/03/enterprise-osgi-released/","summary":"\u003cp\u003eDnia dzisiejszego została wydana finalna wersja specyfikacji OSGi R4 V4.2 Enterprise. Wersja jest gotowa do pobrania pod adresem \u003ca href=\"http://www.osgi.org/Download/Release4V42\"\u003ehttp://www.osgi.org/Download/Release4V42\u003c/a\u003e. Dokument ma 483 strony. :-)\u003c/p\u003e","title":"Specyfikacja Enterprise OSGi została opublikowana"},{"content":"Do opublikowania tego postu zachęcił mnie Jacek Laskowski swym postem pod tytułem W piątek 4Developers ze mną z Enterprise OSGi i in.\nBardzo się cieszę że na 4Developers (na którym niestety mnie nie będzie) temat Enterprise OSGi będzie poruszony, ponieważ jak się zdaje jest to nieuchronny kierunek rozwoju Javy. Pod wpływem słów Jacka zacząłem się zastanawiać nad długofalowymi efektami jakie OSGi ma wnieść do developmentu.\nHałas który obecnie jest wokół OSGi w przybiera konkretne kształty w postaci projektów takich jak Aries czy Gemini. Obydwa projekty skupiają się nad ostatnimi draftami OSGi R4 V4.2 i mają na celu udostępnienie technologii takich jak JNDI, JPA i JMX wewnątrz kontenerów OSGi. Zacznijmy jednak od początku..\nOSGi a jarhell JAR-hell occurs when software is deployed into a runtime environment which is unsuitable, but nothing other than full integration testing would detect this. Having multiple software packages dependent upon the same piece of software, with unpredictable incompatibilities, is pure hell. Ensuring the compatibility of a variety of dependent packages is duanting, doing it amongst the variety supported by a hierarchy of complex class loaders, is inhuman.\nŹródło Apache Depot\nCzyli w skrócie - piekło zaczyna się robić gdy pojawiają się niekompatybilności między bibliotekami w poprawnym środowisku. Co więcej owe niekompatybilności można wykryć dopiero po dogłębnych testach we wszystkich środowiskach w których ma działać aplikacja.\nW przypadku OSGi wszystkie zależności są przewidywalne, co więcej nie uda się nam uruchomić paczki bez jej zależności - stąd teoretycznie nigdy nie powinniśmy widzieć ClassNotFoundException. Nie uda nam się również uruchomić naszego bundle jeśli powstanie konflikt w używanych zależnościach. Przykład z życia wzięty - mamy bundle zależące od camel-activemq oraz activemq-core. Pierwszy z nich pozwala na import spring-jms w wersji \u0026lt; 4.0, natomiast drugi w wersji \u0026lt; 2.6. Jeśli do tego mamy dwie wersje bundle spring-jms: 2.5.6 oraz 3.0.0 to mamy klapę. Naszej paczki nie da się wystartować ponieważ otrzymamy \u0026ldquo;Packages usage conflict\u0026rdquo;. Zostaliśmy ochronieni przed JAR Hellem kosztem zablokowania kodu nawet jeśli zależność była opcjonalna.\nRozwiązanie zagadki packages usage. Problem wydaje się trywialny - teoretycznie to są dwie różne wersje Springa, nie da się zaprzeczyć że 2.5.6 != 3.0.0. W praktyce jednak zmiany w spring-jms były tak niewielkie że można bez problemu uruchomić activemq-core z nową wersją. W takim wypadku jesteśmy zmuszeni do czekania na nową wersję ActiveMQ, która będzie pozwalała na korzystanie ze Springa 3.0 bądź samodzielnie zmodyfikować manifesty. Obydwa rozwiązania są równie złe - jedno to czekanie, drugie to tworzenie nowej dystrybucji ActiveMQ.\nCo w takim wypadku możemy zrobić? Możemy użyć serwisów OSGi, które pozwalają na oddzielenie implementacji od interfejsu, dzięki czemu możemy połączyć dwie wersje bibliotek za fasadą w postaci ServiceReference. Tutaj jednak może pojawić się inny problem - mianowicie część bibliotek które lubią dostęp do ClassLoaderów może skutecznie protestować - na przykład Hibernate czy Open JPA. Dla przykładu diagram obrazujący kolejny z życia wzięty przypadek:\nW tym przypadku usiłowałem stworzyć działającą usługę która zapisywała by przychodzące komunikaty w bazie danych. Może parę słów o tym, który bundle co robi:\ndatasource otwiera połączenie do bazy danych, tworzy ConnectionFactory dla JMS a także EntityManagera. binding bramka do przyjmowania komunikatów - w tym przypadku był to web service. engine definicja routingu z użyciem Camela. persistence użycie EntityManagera do zapisywania komunikatów domain POJO, klasy domenowe Całość komunikacji odbywała się z JMS w trybie request-reply dzięki Apache Camel. Po bardzo długich \u0026ldquo;walkach\u0026rdquo; poniższą strukturę udało się uruchomić pod OSGi. Ostatecznie całość działa z Hibernate w układzie takim jak poniżej.\nZ diagramu wyrzuciłem paczki które nie są istotne takie jak driver JDBC czy Commons ConnectionPool. Jedyny mankament na jaki trafiłem wiąże się z DAO Service, mianowicie bundle który go eksportuje poprzez Spring-DM musi zadeklarować widoczność wszystkich swoich klas dla paczki która będzie korzystać z usługi co jak by nie patrzeć jest drobnym wypaczeniem fasady jaką ma być ServiceReference. Niestety po 2 tygodniach poświęconych na uruchomienie JPA w OSGi nie siliłem się na elegancję.\n[code language=\u0026ldquo;xml\u0026rdquo;]\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e \u0026lt;osgi:reference id=\u0026ldquo;dataSource\u0026rdquo; interface=\u0026ldquo;javax.sql.DataSource\u0026rdquo; /\u0026gt;\n\u0026lt;osgi:service id=\u0026ldquo;exchangeDAOExporter\u0026rdquo; ref=\u0026ldquo;exchangeDAO\u0026rdquo; context-class-loader=\u0026ldquo;service-provider\u0026rdquo; interface=\u0026ldquo;org.code_house.dataaccess.ExchangeDAO\u0026rdquo; /\u0026gt; [/code]\nKolejne metadane Problem jaki powstaje z OSGi to metadane. Do tej pory - jeśli zarządzałem zależnościami do bibliotek robiłem to przez dependencyManagement Mavena, dzięki któremu rozwiązywałem wszystkie konflikty. OSGi jednak nie wiąże się z Mavenem ponieważ są to dwa różne obszary o zgoła innym funkcjonowaniu - OSGi to runtime, Maven to build time. Dopóki nie zapanuje harmonia pomiędzy tymi dwoma uruchamianie czegokolwiek w OSGi będzie katorgą. Należy do tego dodać jeszcze jeden element związany z OSGi - mianowicie O SGi B undle R epository (OBR), a OBR nijak się ma do repozytoriów Mavena przez co rozbieżności tylko się nasilają. Aby temu zapobiegać najpopularniejsze istniejące repozytoria SpringSource Enterprise Bundle Repository oraz ServiceMix 4 Bundles repository - publikują artefakty w repozytoriach Mavena. Problem w tym, że część artefaktów jest powielona. Tak jak kiedyś były 3 wersje Java Persistence API tak teraz dochodzą kolejne dwie - z manifestami OSGi. Czy ktoś wspominał o piekle? Należy również dodać że nie każdy JAR który ląduje w OSGi jest traktowany tak samo - oprócz standardowych bundli są również fragmenty, które są świetnym rozwiązaniem, jednakże początkowo potrafią przysporzyć wielu problemów. Cały trik sprowadza się do tego, że fragmenty mają wspólny class loader z paczką do której są przypięte.\nKorzyści z Enterprise OSGi Po całych tych wywodach na temat problemów z OSGi pora na to co ma ono nam dać - przenośność. Podobnie jak Java EE 6 z profilami tak OSGi ma zapewnić większą przenośność klocków pomiędzy środowiskami. Wyobrażacie sobie, że można przenieść aplikację z kontenera servletów na serwer aplikacyjny bez modyfikacji? Albo usługę z szyny integracyjnej na kontener servletów? Niedorzeczne, ale z OSGi możliwe do wykonania. Wystarczy zainstalować wszystkie wymagane bundle i całość będzie działać.\nOczywiście naiwna była by wiara w to, że tak będzie. Każda specyfikacja która powstaje dla Javy ma standaryzować i ujednolicać środowiska. W praktyce jednak każda z nich staje się punktem wyjściowym do rozwoju nowych produktów. Każdy dostawca oferuje zgodność ze specyfikacją plus coś. Nie twierdzę, że to złe, ponieważ polaryzacja rynku oprogramowania jest tak samo potrzebna jak wolny rynek, należy się jednak wystrzegać monopolistów a w przypadku oprogramowania również vendor locków.\nPatrzę na OSGi z nadzieją ponieważ w moim mniemaniu jest to przedłużenie idei jaką niosła specyfikacja J ava B usiness I ntegration. Propozycja JBI 2.0 spotkała się z krytyką ze strony IBM oraz BEA Systems zasłaniających się tym, że istnieje SCA. Problem w tym, że obydwie specyfikacje traktują o innych warstwach integracji - SCA gwarantuje przenośność usług, podczas gdy JBI miało zapewnić przenośność komponentów i komunikacji między nimi. SCA i JBI mogą a nawet powinny iść w parze. Teoria JBI mówiła o możliwości uruchomienia servicemix-cxf-bc (zgodnego z JBI) na Open ESB, w praktyce okazywało się to jednak bardzo trudne. Dzięki OSGi/Enterprise OSGi stanie się to łatwiejsze.\nW ciągu kilku najbliższych lat trend OSGi dzięki zainteresowaniu wielkich korporacji będzie rósł w siłę. Trzymam kciuki by Enterprise OSGI przyniosło więcej korzyści niż tylko zbawienie od JAR Hella.\n","permalink":"http://localhost:1313/2010/03/enterprise-osgi/","summary":"\u003cp\u003eDo opublikowania tego postu zachęcił mnie \u003ca href=\"http://jlaskowski.blogspot.com/\"\u003eJacek Laskowski\u003c/a\u003e swym postem pod tytułem \u003ca href=\"http://jlaskowski.blogspot.com/2010/03/w-piatek-4developers-ze-mna-z.html\"\u003eW piątek 4Developers ze mną z Enterprise OSGi i in\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eBardzo się cieszę że na 4Developers (na którym niestety mnie nie będzie) temat Enterprise OSGi będzie poruszony, ponieważ jak się zdaje jest to nieuchronny kierunek rozwoju Javy. Pod wpływem słów Jacka zacząłem się zastanawiać nad długofalowymi efektami jakie OSGi ma wnieść do developmentu.\u003c/p\u003e\n\u003cp\u003eHałas który obecnie jest wokół OSGi w przybiera konkretne kształty w postaci projektów takich jak \u003ca href=\"http://incubator.apache.org/aries/\"\u003eAries\u003c/a\u003e czy \u003ca href=\"http://www.eclipse.org/gemini/\"\u003eGemini\u003c/a\u003e. Obydwa projekty skupiają się nad ostatnimi draftami OSGi R4 V4.2 i mają na celu udostępnienie technologii takich jak JNDI, JPA i JMX wewnątrz kontenerów OSGi. Zacznijmy jednak od początku..\u003c/p\u003e","title":"Enterprise OSGi"},{"content":"Dnia 23 lutego w ramach Warszawa JUG miałem przyjemność wraz z Tomkiem Nurkiewiczem prezentować narzędzia integracyjne z otwartym kodem źródłowym. Tomek przedstawił Mule ESB, podczas gdy ja zająłem się Apache ServiceMix i Apache Camel. Ze względu na objętość przykładu ten wpis będzie jedynie wprowadzeniem do konsoli.\nNiestety podczas prezentacji nie udało mi się uruchomić przykładu na \u0026ldquo;szynie\u0026rdquo; - ponieważ uniemożliwiły to zależności do bibliotek których nie miałem zapisanych lokalnie. Drugim mym przeciwnikiem był czas - nie było wielu chętnych by słuchać po 2h tłumaczeń dlaczego się nie udało :-) Na problem z zależnościami stworzyłem rozwiązanie i zgłosiłem je do Karaf-a ( FELIX 2141). W przyszłej wersji - 1.6 - wszyscy będą mogli skorzystać z polecenia features:info -t które wyświetli całe drzewko zależności potrzebnych do zainstalowania nowych funkcjonalności.\nPrzygotowanie środowiska Do uruchomienia przykładów potrzebować będziemy dwóch paczek - pierwsza to Apache ServiceMix, druga to Apache Maven. Ze swojej strony polecam pobranie FUSE ESB 4.2, produktu który jest oparty o ServiceMix. Zgodnie z moimi zapowiedziami od tej wersji FUSE Source wprowadza pełne wsparcie produkcyjne dla ServiceMix 4. Jeśli nie masz zainstalowanego Mavena i nigdy tego nie robiłeś zajrzyj na wiki Code-House: Wprowadzenie do Maven 2\nPo pobraniu odpowiedniej wersji należy ją rozpakować do wybranego folderu. Szynę uruchamiamy skryptem servicemix.bat. Jeśli wszystko przebiegło poprawnie naszym oczom powinien ukazać się obrazek jak poniżej:\nE:\\tools\\progress\\fuse-esb\\4.2.0-b\\bin\u0026gt;servicemix.bat ____ _ __ __ _ / ___| ___ _ ____ _(_) ___ ___| \\/ (_)_ __ \\___ \\ / _ \\ \u0026#39;__\\ \\ / / |/ __/ _ \\ |\\/| | \\ \\/ / ___) | __/ | \\ V /| | (_| __/ | | | |\u0026gt; \u0026lt; |____/ \\___|_| \\_/ |_|\\___\\___|_| |_|_/_/\\_\\ Apache ServiceMix (4.2.0-fuse-01-00) Hit \u0026#39;\u0026#39; for a list of available commands and \u0026#39;[cmd] --help\u0026#39; for help on a specific command. karaf@root\u0026gt; Od tej chwili mamy do dyspozycji konsolę administracyjną. Aby zwiększyć jej użyteczność wykonujemy następujące polecenia:\nkaraf@root\u0026gt; osgi:install wrap:mvn:http://download.java.net/maven/2!net.java.dev.jna/jna/3.1.0 Bundle ID: 134 Spowoduje to pobranie z repozytorium Mavena (http://download.java.net/maven/2) biblioteki JNA w wersji 3.1.0. Nie musimy oczywiście określać za każdym razem adresu repozytoriów, ale o tym nieco później. Prefix wrap: spowoduje wygenerowanie manifestu OSGi na podstawie zawartości pobranej biblioteki. Jest on konieczny ponieważ JNA nie dostarcza potrzebnych danych do uruchomienia w środowisku OSGi.\nkaraf@root\u0026gt; osgi:install mvn:http://jansi.fusesource.org/repo/release!org.fusesource.jansi/jansi/1.2 Bundle ID: 135 Druga biblioteka wykorzystuje JNA i umożliwia kolorowanie tekstu w konsoli windowsowej zgodnie z ANSI, czyli tak jak w standardowych terminalach Unix-a. Po zainstalowaniu tych dwóch rzeczy pora zaprząc je do pracy. Poniżej filtrujemy listę zainstalowanych rzeczy po słowie Console.\nkaraf@root\u0026gt; list|grep Console [ 10] [Active ] [Created ] [ ] [ 30] Apache Felix Karaf :: Shell Console (1.4.0.fuse-01-00) karaf@root\u0026gt; refresh 10 Numer 10 oznacza id paczki OSGi, tekst Active to stan paczki a tekst Created informuje o stanie kontekstu blueprint, czwarty bloczek to stan kontekstu Springa, numer 30 to start level paczki a w ostatnim nawiasie mamy wersję. Sporo informacji jak na jedną linijkę, nieprawdaż? Blueprint to standaryzowanie tego czym jest Spring i Spring DM, także można korzystać zamiennie bądź z jednego bądź z drugiego rozwiązania. Ciekawe porównanie funkcjonalności obu rozwiązań - Spring DM oraz Blueprint opublikował kilka dni temu Guillaume Nodet na swoim blogu we wpisie Spring-DM, Aries Blueprint and custom namespaces. Apache Camel od wersji 2.3 będzie wspierał Blueprint ( CAMEL-2022).\n____ _ __ __ _ / ___| ___ _ ____ _(_) ___ ___| \\/ (_)_ __ \\___ \\ / _ \\ \u0026#39;__\\ \\ / / |/ __/ _ \\ |\\/| | \\ \\/ / ___) | __/ | \\ V /| | (_| __/ | | | |\u0026gt; \u0026lt; |____/ \\___|_| \\_/ |_|\\___\\___|_| |_|_/_/\\_\\ Apache ServiceMix (4.2.0-fuse-01-00) Hit \u0026#39;\u0026lt;tab\u0026gt;\u0026#39; for a list of available commands and \u0026#39;[cmd] --help\u0026#39; for help on a specific command. karaf@root\u0026gt; Teraz wykonanie poleceń z filtrem grep spowoduje podświetlenie szukanej frazy:\nkaraf@root\u0026gt; list |grep Console [ 10] [Active ] [Created ] [ ] [ 30] Apache Felix Karaf :: Shell Console (1.4.0.fuse-01-00) Takie małe udogodnienie przy przeglądaniu dłuższych rezultatów jest nieocenione.\nPodstawowe polecenia konsoli Polecenia w Apache Karaf są podzielone na kilka grup, które ułatwiają zarządzanie. Pierwszą grupą jest OSGi.\nPolecenia OSGi PoleceniePrzeznaczenielistWyświetlenie listy zainstalowanych paczekls [bundle id]Wyświetlenie usług eksportowanych przez paczkę.ls -u [bundle id]Wyświetlenie usług używanych przez paczkę.headers [bundle id]Wyświetlenie manifestu paczki.start [bundle id]Uruchomienie paczki o danym ID.stop [bundle id]Zatrzymanie paczki o danym ID.restart [bundle id]Zatrzymanie i wystartowanie paczki o danym ID.update [bundle id]Aktualizacja paczki.refresh [bundle id]Odświeżenie importów paczki a także przeładowanie kontekstu Spring-DM.install [url]Zainstalowanie nowej paczki.uninstall [bundle id]Odinstalowanie paczki.shutdownZatrzymanie kontenera.bundle-level [bundle id] [startLevel]Ustawienie start levelu dla paczki.start-level\nKiedy znamy już listę poleceń nie pozostaje nic innego jak je wypróbować. :-) Checkout przykładowego kodu z SVN pozwoli wykonać nam kilka ćwiczeń. Po wykonaniu polecenia mvn clean install w repozytorium Mavena są JARy które, naturalnie, chcemy zainstalować. Rezultat jaki powinniśmy zobaczyć w konsoli to:\n[INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] ------------------------------------------------------------------------ [INFO] Money transfer ServiceMix example ..................... SUCCESS [2.028s] [INFO] Money transfer :: API ................................. SUCCESS [3.182s] [INFO] Money transfer :: POI bundle .......................... SUCCESS [7.504s] [INFO] Money transfer :: Internal ............................ SUCCESS [0.093s] [INFO] Money transfer :: Internal :: CSV ..................... SUCCESS [4.399s] [INFO] Money transfer :: Internal :: XLS ..................... SUCCESS [2.823s] [INFO] Money transfer :: Internal :: Mail .................... SUCCESS [2.309s] [INFO] Money transfer :: Internal :: Splitter ................ SUCCESS [0.936s] [INFO] Money transfer :: Internal :: Routes .................. SUCCESS [1:21.241s] [INFO] Money transfer :: External ............................ SUCCESS [0.016s] [INFO] Money transfer :: External :: Customer ................ SUCCESS [3.182s] [INFO] Money transfer :: External :: Bank .................... SUCCESS [2.059s] [INFO] Money transfer :: External :: Validator ............... SUCCESS [2.918s] [INFO] Money transfer :: Features ............................ SUCCESS [0.171s] [INFO] ------------------------------------------------------------------------ [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1 minute 54 seconds [INFO] Finished at: Mon Mar 22 10:47:27 CET 2010 [INFO] Final Memory: 127M/341M [INFO] ------------------------------------------------------------------------ Może teraz kilka słów o modułach które są widoczne w Mavenie. ModułŚcieżka\nMaven IDPrzeznaczenieMoney transfer :: APIapi\norg.code-house.samples/apiAPI systemów zewnętrznych oraz POJO wykorzystywane do komunikacji.Money transfer :: POI bundlepoi\norg.code-house.samples/poiBundle zawierający bibliotekę Apache POI oraz wszystkie jej zależności z Manifestem OSGi pozwalającym na jej uruchomienie na szynie.Money transfer :: Internal :: CSVinternal/csv\norg.code-house.samples.internal/csvPaczka zawierająca implementację procesora przetwarzającego pliki CSV na POJO MoneyTransfer.Money transfer :: Internal :: XLSinternal/xls\norg.code-house.samples.internal/xlsPaczka zawierająca implementację procesora przetwarzającego pliki XLS na POJO MoneyTransfer.Money transfer :: Internal :: Mailinternal/mail\norg.code-house.samples.internal/mailPaczka z kodem dzielącym przychodzący mail z załącznikami na pojedyncze wiadomości które można przetworzyć jako XLS bądź CSV.Money transfer :: Internal :: Splitterinternal/splitter\norg.code-house.samples.internal/splitterPaczka z kodem odpowiedzialnym za rozdzielanie listy obiektów MoneyTransfer na listę wiadomości.Money transfer :: Internal :: Routesinternal/routes\norg.code-house.samples.internal/routesGłówna paczka z definicjami routinguMoney transfer :: External :: Customerexternal/customer\norg.code-house.samples.external/customerImplementacja WebService odpowiedzialnego za pobieranie danych klienta na podstawie numeru rachunku bankowego.Money transfer :: External :: Bankexternal/bank\norg.code-house.samples.external/bankImplementacja usługi zwracającej informację o nazwie banku na podstawie numeru rachunku.Money transfer :: External :: Validatorexternal/validator\norg.code-house.samples.external/validatorUsługa weryfikująca czy MoneyTransfer jest poprawny.Money transfer :: Featuresfeatures\norg.code-house.samples/featuresModuł zawierający opcjonalny deskryptor do uruchomienia modułów.\nJak widać dwa główne obszary projektu są skupione w katalogach internal oraz external. Ten pierwszy zawiera implementacje ściśle związaną z usługami natomiast drugi to \u0026ldquo;zatyczki\u0026rdquo; emulujące działanie systemów zewnętrznych. Drobna nota - kolumna Maven ID nie zawiera informacji o wersji - w każdym module jest to 1.0.0.SNAPSHOT.\nAby zainstalować któryś bundle przechodzimy do konsoli ServiceMix\u0026rsquo;a i wykonujemy takie polecenia:\nkaraf@root\u0026gt; install -s mvn:org.code-house.samples/api/1.0.0.SNAPSHOT Bundle ID: 210 karaf@root\u0026gt; features:install camel-jetty karaf@root\u0026gt; install -s mvn:org.code-house.samples.external/customer/1.0.0.SNAPSHOT Bundle ID: 211 Po wykonaniu tych poleceń powinien być uruchomiony Web Service którego WSDL znajduje się pod adresem http://localhost:9001/CustomerWs?wsdl. Przełącznik -s w przypadku polecenia install powoduje że po zainstalowaniu bundle zostanie wystartowany. Polecenie features-install camel-jetty jest potrzebne nie ze względu na to że kolejna paczka korzysta z Camela, dzięki jego wykonaniu zostanie zainstalowane Jetty, z którego korzysta CXF.\nKolejne paczki instalujemy analogicznie:\nkaraf@root\u0026gt; features:install camel-activemq karaf@root\u0026gt; install -s mvn:org.code-house.samples.external/validator/1.0.0.SNAPSHOT Bundle ID: 215 karaf@root\u0026gt; install -s mvn:org.code-house.samples.external/bank/1.0.0.SNAPSHOT Bundle ID: 217 Rozszerzenie camel-activemq jest rozszerzeniem modułu camel-jms które pozwala na nieco wydajniejszą pracę z ActiveMQ.\nIntegracja ServiceMix z repozytoriami Mavena Maven jako narzędzie do budowania korzysta z określonego schematu składowania bibliotek które następnie są automatycznie pobierane. Karaf, który jak wspomniałem podczas prezentacji, wyłonił się z projektu ServiceMix Kernel korzysta z biblioteki Pax URL. Dzięki temu z marszu mamy dostęp do standardowych repozytoriów Mavena, co jednak gdy mamy swoje repozytorium, które zawiera tylko nasze artefakty? Otwieramy plik etc/org.ops4j.pax.url.mvn.cfg i dodajemy w nim co trzeba. Moja standardowa konfiguracja wygląda następująco: [code] org.ops4j.pax.url.mvn.settings=E:/tools/maven-2.2.1/conf/settings.xml org.ops4j.pax.url.mvn.localRepository=E:/repository org.ops4j.pax.url.mvn.defaultRepositories=file:${karaf.home}/${karaf.default.repository}@snapshots org.ops4j.pax.url.mvn.repositories= http://repo1.maven.org/maven2, http://repo.fusesource.com/maven2, http://repo.fusesource.com/maven2-snapshot@snapshots@noreleases, http://repository.apache.org/content/groups/snapshots-group@snapshots@noreleases, http://repository.ops4j.org/maven2, http://svn.apache.org/repos/asf/servicemix/m2-repo, http://repository.springsource.com/maven/bundles/release, http://repository.springsource.com/maven/bundles/external, http://repository.code-house.org/content/groups/release, http://repository.code-house.org/content/groups/snapshot@snapshots@noreleases, http://jansi.fusesource.org/repo/release [/code] Dzięki temu PAX w pierwszej kolejności będzie skanował katalog E:/repository zamiast standardowego ~/.m2/repository. Jeśli któreś z repozytoriów wymaga autoryzacji adres powinien wyglądać następująco: [code]http://user:[email protected]/repo/release[/code]\nPodsumowanie Mam nadzieję że wpis ten przybliży chociaż w niewielkim stopniu ServiceMix 4 oraz Karafa. W przyszłym wpisie, którego daty publikacji nie sposób przewidzieć zostaną dokładniej omówione polecenia z grupy features. Póki co życzę miłej zabawy z konsolą. :-) W razie pytań, niejasności i problemów - proszę o komentarze.\n","permalink":"http://localhost:1313/2010/03/introduction-to-apache-servicemix4-part-1/","summary":"\u003cp\u003eDnia 23 lutego w ramach Warszawa JUG miałem przyjemność wraz z \u003ca href=\"http://nurkiewicz.blogspot.com/\"\u003eTomkiem Nurkiewiczem\u003c/a\u003e prezentować narzędzia integracyjne z otwartym kodem źródłowym. Tomek przedstawił Mule ESB, podczas gdy ja zająłem się Apache ServiceMix i Apache Camel. Ze względu na objętość przykładu ten wpis będzie jedynie wprowadzeniem do konsoli.\u003c/p\u003e\n\u003cp\u003eNiestety podczas prezentacji nie udało mi się uruchomić przykładu na \u0026ldquo;szynie\u0026rdquo; - ponieważ uniemożliwiły to zależności do bibliotek których nie miałem zapisanych lokalnie. Drugim mym przeciwnikiem był czas - nie było wielu chętnych by słuchać po 2h tłumaczeń dlaczego się nie udało :-) Na problem z zależnościami stworzyłem rozwiązanie i zgłosiłem je do Karaf-a ( \u003ca href=\"https://issues.apache.org/jira/browse/FELIX-2141\"\u003eFELIX 2141\u003c/a\u003e). W przyszłej wersji - 1.6 - wszyscy będą mogli skorzystać z polecenia \u003ccode\u003efeatures:info -t\u003c/code\u003e które wyświetli całe drzewko zależności potrzebnych do zainstalowania nowych funkcjonalności.\u003c/p\u003e","title":"Wprowadzenie do Apache ServiceMix 4 cz. 1"},{"content":"Od dłuższego czasu pracuję z następującymi narzędziami: Maven, Eclipse, Jetty. Nigdy nie starałem się na to by moje projekty dobrze współgrały z Eclipse ponieważ wszystko i tak uruchamiam przez Mavena. Korzyścią jest przenośność tego rozwiązania, wadą brak klikalnej wygody, tj zakładki serwerów w Eclipse i aplikacji które są na nich uruchomione.\nTuż przed nowym rokiem udało mi się skonfigurować Mavena i Eclipse oraz JRebel. Teraz po zmianie klasy czy konfiguracji Springa z poziomu Eclipse zmiany widać w Jetty uruchomionym z poziomu Mavena. Nie byłby to sukces sam w sobie gdyby nie fakt, że udało się to zrobić w z wieloma modułami. Oto przykład struktury projektu:\ndomain - model danych oraz encje security - kod związany z zabezpieczeniami oraz ich konfiguracją dataaccess api - interfejsy DAO oraz Fasad jpa -dostęp do danych przy użyciu JPA jdbc - dostęp dod anych z użyciem gołego JDBC web - końcówka webowa - kontrolery itp. distribution - tworzenie dystrybucji do środowiska testowego i produkcyjnego Ogólnie strukturę tą można coraz bardziej rozdrabniać bądź zbijać tak by odpowiadała ona naszym potrzebom, w tym przypadku pominiemy dywagacje ponieważ nie o tym ten wpis ma być. Problemem przy tego typu strukturze jest to że zmiany w modułach dao są dostępne w module web dopiero po przebudowaniu obydwu, co czasami bywa uciążliwe. Rozwiązaniem byłoby użycie OSGi i serwera który to wspiera, po zmianie robili byśmy deploy bundle który się zmienił - było by to z pewnością wygodniejsze niż dwukrotny mvn install, jest jednak rozwiązanie jeszcze wygodniejsze - JRebel.\nKonfiguracja Mavena Jak już wspomniałem całość zmian nie wymaga nic od Eclipse ze względu na to, że całość deskryptorów jest generowana z poziomu Mavena przy pomocy maven-eclipse-plugin. [xml] org.apache.maven.plugins maven-eclipse-plugin target/classes [groupId]_[artifactId] [/xml]\nDrugi krok to stworzenie bądź modyfikacja zmiennej środowiskowej MAVEN_OPTS: [source lang=\u0026ldquo;bash\u0026rdquo;] -noverify -javaagent:E:\\tools\\jrabel-2.2.1\\jrebel.jar -Xdebug -Drebel.log.stdout=true -Drebel.log=true -Xrunjdwp:transport=dt_socket,server=y,address=4000,suspend=n -Xmx768m [/source]\nTrzeci krok to konfiguracja JRebel. Oczywiście można skorzystać z javarebel-maven-plugin, ale mi nie udało się go poprawnie skonfigurować, dlatego też plik został stworzony ręcznie: [xml]\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e \\[/xml\\] Dodatkowo należy wyłączyć przeładowania Jetty tak by nie kolidowały one z agentem JRebel. Całość w dalszym ciągu działa z poziomu Mavena i jest przenośne. Po tych wszystkich zmianach możemy się cieszyć trialem przez 30 dni bądź kupić licencję za jedyne 149$. :)\n","permalink":"http://localhost:1313/2010/01/wygodne-srodowisko-dla-programisty-z-jrebel/","summary":"\u003cimg alt=\"jrebel_bigger\" loading=\"lazy\" src=\"http://blog.code-house.org/wp-content/uploads/jrebel_bigger.png\"\u003eOd dłuższego czasu pracuję z następującymi narzędziami: Maven, Eclipse, Jetty. Nigdy nie starałem się na to by moje projekty dobrze współgrały z Eclipse ponieważ wszystko i tak uruchamiam przez Mavena. Korzyścią jest przenośność tego rozwiązania, wadą brak klikalnej wygody, tj zakładki serwerów w Eclipse i aplikacji które są na nich uruchomione.","title":"Wygodne środowisko dla programisty z JRebel"},{"content":"Właśnie wyłapałem na Twitterze, że Spring 3.0 RC3 został wydany.\nDla tych, którzy chcieli by pobrać nową wersję do swojego projektu opartego o Mavena drobna informacja - repozytorium z tymi artefaktami znajduje się pod adresem http://maven.springframework.org/milestone. Miejmy nadzieję, że będzie to repozytorium które się nie zmieni po 3 miesiącach na inne.\nW razie problemów - można zawsze skorzystać z repozytorium utrzymywanego na serwerze Code-House.\n","permalink":"http://localhost:1313/2009/12/spring-3-0-rc3-maven/","summary":"\u003cp\u003eWłaśnie wyłapałem na Twitterze, że \u003ca href=\"http://www.springsource.com/download?project=Spring%20Framework\"\u003eSpring 3.0 RC3\u003c/a\u003e został wydany.\u003c/p\u003e\n\u003cp\u003eDla tych, którzy chcieli by pobrać nową wersję do swojego projektu opartego o Mavena drobna informacja - repozytorium z tymi artefaktami znajduje się pod adresem \u003ca href=\"http://maven.springframework.org/milestone\"\u003ehttp://maven.springframework.org/milestone\u003c/a\u003e. Miejmy nadzieję, że będzie to repozytorium które się nie zmieni po 3 miesiącach na inne.\u003c/p\u003e\n\u003cp\u003eW razie problemów - można zawsze skorzystać z repozytorium utrzymywanego na \u003ca href=\"http://repository.code-house.org/content/repositories/com.springsource.repository.bundles.milestone/\"\u003eserwerze Code-House\u003c/a\u003e.\u003c/p\u003e","title":"Spring 3.0 RC3 + Maven"},{"content":"GWT, czyli Google Web Toolkit to nic innego jak zbiór komponentów, które można użyć podczas tworzenia aplikacji. GWT jest łatwe, kod tworzy się szybko i łatwo uruchamia chociażby z poziomu Mavena, jednakże największym problemem nie jest to jak stworzyć okienko, ale jak zorganizować projekt. W tym poście postaram się przedstawić kilka gotowych bibliotek, z którymi się zetknąłem podczas swych bojów z budowaniem sporej aplikacji.\nIlość implementacji MVC dla GWT jest dosyć duża a temat był poruszany na zagranicznych blogach już nie jeden raz, wystarczy zajrzeć na poniższe strony:\nW marcu 2009 Matt Raible opisał swoje problemy z komponentami GXT oraz problematycznym MVC stworzonym przez autorów tejże biblioteki W kwietniu 2009 pojawiło się pierwsze zestawienie implementacji MVC na blogu Supply Chain Technology W maju 2009 na tym samym blogu pojawiła się aktualizacja z nowymi pozycjami. Również w maju 2009 odbyła się konferencja Google IO na której temat developmentu GWT był szeroko i dokładnie omówiony. Zacząłem nieśmiało, bo od stworzenia \u0026ldquo;szyny\u0026rdquo; którą mogły by się komunikować różne komponenty. Miała ona na celu zmniejszenie ilości bezpośrednich powiązań między elementami aplikacji. Pomogło, ale to nie było jeszcze to, co uporządkowało aplikację.\nDrugie podejście mimo obaw wyniesionych z pierwszego linku padło na lightweight MVC z biblioteki GXT. Udało mi się stworzyć działającą aplikację, jednakże brak jasnego podziału co, kto i jak ma robić strasznie mi doskwierał. Problematyczna okazała się również próba stworzenia hierarchii kontrolerów, a zrobienie aplikacji od zera sprowadzało się tak na prawdę do skopiowania i przerobienia przykładu z Mail App. Podobnie jak Matt nigdy też nie wyłapałem różnicy między metodami Dispatcher.dispatch() oraz Dispatcher.forwardEvent().\nTrzecie podejście do MVC zakrawało już szaleństwem. Po przejrzeniu dokumentacji GWTruts stwierdziłem, że zapowiada się ciekawie. Odseparowany widok i kontroler, API przypominające nieco Spring MVC, nieco XML do okraszenia całości wstrzykiwaniem zależności. Wszystko to jednak na nic, gdyż całość opiera się na mapowaniu adresów z przeglądarki do kontrolerów. Krzywe koniec końców okazało się też przekazywanie map z argumentami i w dalszym ciągu brak jakichkolwiek idei na zorganizowanie wszystkiego. A zapomniałbym - jeśli chcecie walidacji to musicie pogodzić się z tym że 1 kontroler to 1 klasa do sprawdzania danych. Szkoda że tego nie można \u0026ldquo;wstrzyknąć\u0026rdquo;.\nDobra, skoro nie GWTruts, nie GXT, i nie Event Bus to co? Krótki przegląd GWT-MVC skończył się odrzuceniem szkieletu. Skąd niby kontroler ma zajmować się tym gdzie ma wylądować widok? A tak właśnie się dzieje w tym szkielecie ponieważ kontroler wywołuje DOMPlacera by gdzieś umieścić widok. Jak by tych fanaberii było mało doszedł jeszcze interfejs Maskable który ma przykrywać elementy w trakcie renderowania. Dodajmy do tego przykłady które się sprowadzały do przycisków +2, -2 i inputa. Pytanie - co to ma do klasycznego MVC?\nTym oto sposobem dotarłem do ostatniego projektu, który mi zaimponował rozmiarem dokumentacji, spójną koncepcją i masą ograniczeń - Pure MVC. Projekt, który pierwotnie miał sporo do czynienia z Flashem, a który dzięki swojemu porządkowi został przepisany również na inne języki - min. PHP, Javę. Wśród portów nie zabrakło również wersji dla GWT. Nie muszę pisać jak bardzo mnie to ucieszyło, prawda? :-) Całkiem duży przykład obrazuje powiązania pomiędzy komponentami oraz to jak powinny się komunikować: Uzbrojony w ten zakres informacji stworzyłem pierwszą przykładową aplikację z ekranem logowania oraz jedną tabelką. Stopniowo go rozbudowując dotarłem do momentu w którym moja aplikacja w końcu przestała się kręcić wokół tego \u0026ldquo;które MVC\u0026rdquo; wybrać i zaczęła nabierać funkcjonalności biznesowej. Po długich bojach i masie straconego czasu, odradzam wszystkie inne implementacje Model View Controller dla GWT. Pure MVC jest po prostu najlepsze. :-)\n","permalink":"http://localhost:1313/2009/11/gwt-and-mvc-implementations/","summary":"\u003cp\u003eGWT, czyli Google Web Toolkit to nic innego jak zbiór komponentów, które można użyć podczas tworzenia aplikacji. GWT jest łatwe, kod tworzy się szybko i łatwo uruchamia chociażby z poziomu Mavena, jednakże największym problemem nie jest to jak stworzyć okienko, ale jak zorganizować projekt. W tym poście postaram się przedstawić kilka gotowych bibliotek, z którymi się zetknąłem podczas swych bojów z budowaniem sporej aplikacji.\u003c/p\u003e\n\u003cp\u003eIlość implementacji MVC dla GWT jest dosyć duża a temat był poruszany na zagranicznych blogach już nie jeden raz, wystarczy zajrzeć na poniższe strony:\u003c/p\u003e","title":"GWT oraz implementacje MVC"},{"content":"Kilka dni temu trafiłem na informacje o tym, że firma Atlassian uruchomiła \u0026ldquo;promocję\u0026rdquo; w której wyprzedaje licencje startowe na swoje produkty za 10$. Tym oto sposobem za równowartość dobrego obuwia (niecałe 175 zł) wszedłem w posiadanie sześciu licencji na Crowd, Jira, GreenHopper, Confluence, Fisheye i Bamboo. W poście tym krótki opis instalacji na Tomcat 6.x pierwszych czterech.\nPrzygotowania Uprzedzam, że instrukcja jest pisana z pamięci więc mogą pojawić się jakieś braki. W przypadku gdy instrukcja nie zadziała proszę o komentarz, a postaram się pomóc i uzupełnić wpis tak by był kompletny. Aby ułatwić sobie życie i zaoszczędzić pamięć na serwerze wszystkie produkty będzie obsługiwała jedna instancja Tomcat i PostgreSQL. Niestety Fisheye i Bamboo są dostępne tylko w wersji standalone, stąd proces ich instalacji będzie nieco inny. Zanim ruszymy z całością pobieramy od producenta oprogramowanie. Przeskakujemy na zakładkę Linux i następnie klikamy w prawym górnym rogu i pobieramy wersję standalone. Wykonujemy polecenie [bash]tar -xvzf atlassian-crowd-2.0.2.tar.gz[/bash]\nPo rozpakowaniu pojawią się następujące katalogi\napache-tomcat client crowd-openidclient-webapp crowd-openidserver-webapp crowd-webapp demo-src demo-webapp etc Będziemy potrzebować tylko dwóch - crowd-webapp oraz opcjonalnie openidserver. Dystrybucja standalone zawiera już Tomcata, zatem najpotrzebniejsze biblioteki weźmiemy już stąd. :) Kopiujemy biblioteki:\nactivation-1.1.jar mail-1.4.jar jta-1.0.1B.jar Do katalogu lib naszego tomcata. Na Gentoo jest to /usr/share/tomcat-6/lib. Pierwsze dwie biblioteki będą potrzebne do używania obiektu javax.mail.Session zapisanego w drzewie JNDI. Dodatkowo pobieramy driver JDBC dla bazy PostgreSQL. Należy pamiętać że wersja JDBC 4 jest przeznaczona do uruchamiania na Java 1.6. Ja ściągnąłem wersję 8.4-701.jdbc4. Mając te biblioteki przystępujemy do konfiguracji kontekstu Tomcata. W pierwszym kroku dodajemy globalną sesję mailową którą będziemy współdzielić między aplikacjami. W ten sposób zmiana w jednym miejscu będzie skutkować \u0026ldquo;aktualizacją\u0026rdquo; konfiguracji wszystkich aplikacji. Edytujemy plik $TOMCAT_HOME/conf/server.xml. W sekcji GlobalNaminResources umieszczamy dodatkowy fragment: [xml class=\u0026ldquo;xml\u0026rdquo; classname=\u0026ldquo;xml\u0026rdquo;] \u0026lt;!-- Ten wpis jest domyślnie dostępny \u0026ndash;\u0026gt; [/xml] Konieczna będzie również zmiana sekcji Server: [xml classname=\u0026ldquo;xml\u0026rdquo;] [/xml] Atrybut URIEncoding będzie wymagany przez min. confluence i umożliwia przesyłanie krzaczków w adresie. Warto również zwiększyć limity pamięci Tomcata ponieważ na domyślnych długo nie pociągnie i prawdopodobnie już przy instalacji JIRA albo Confluence poleci OutOfMemory.\nDrugi krok to ustawienie zmiennej crowd-home. W tym celu należy wyedytować plik crowd-webapp/WEB-INF/classes/crowd-init.properties. [plain]crowd.home=/var/lib/tomcat-6/atlassian/crowd-home[/plain] W razie problemów można \u0026ldquo;zresetować\u0026rdquo; instalację usuwając folder home, czego oczywiście nie radzę robić. :) Trzeci krok to konfiguracja kontekstu Crowd. [xml classname=\u0026ldquo;xml\u0026rdquo;] [/xml] W miejscu docBase należy podać folder w którym znajduje się crowd. Kopiujemy plik crowd.xml do katalogu $TOMCAT_HOME/conf/Catalina/localhost. Ok wygląda na to, że to wszystko co było potrzebne, zatem teraz restart Tomcata i powinno działać.. Powinno, ale nie działa. Problem, z którym męczyłem się bardzo długo to niewidoczny zasób jdbc/CrowdDS w procesie instalacji. O dziwo mail/Session był widoczny. Przy pierwszym podejściu poddałem się i skonfigurowałem połączenie w instalatorze podając te same dane co w konfiguracji kontekstu. Jednakże, po chwili zastanowienia i tych samych problemach z JIRA postanowiłem powtórzyć proces. Logi wskazywały że data source nie uruchamia się, ponieważ pojawiały się wpisy WARN o nieodnalezionej klasie. Poszperałem i dowiedziałem się że potrzebuję biblioteki tomcat-dbcp.jar, której oczywiście nie ma w dystrybucji. Całe szczęście znalazłem w serwisie Java2S. Po ściągnięciu zipa, należy go rozpakować i skopiować tomcat-dbcp.jar do $TOMCAT_HOME/lib.\nInstalacja CROWD Status aplikacji powinien być widoczny w managerze Tomcata. Jeśli wszystko jest w porządku, przechodzimy do instalatora. W pierwszej kolejności zostaniemy zapytani o licencję, następnie o połączenie z bazą danych i sesję mailową. Podajemy zatem co trzeba - ścieżka do data source to java:comp/env/jdbc/CrowdDS a do maila java:comp/env/mail/Session. Konfigurację grup i tak dalej pominę i odeślę do oficjalnej dokumentacji.\nInstalacja JIRA JIRA jako oprogramowanie bardziej wymagające będzie wymagała kilku dodatkowych bilbiotek. Przede wszystkim pobieramy jira-tomcat6-jars.zip. Całość należy wpakować do $TOMCAT_HOME/lib. Następnie pobieramy wersję WAR/EAR: Po rozpakowaniu [bash]unzip atlassian-jira-enterprise-4.0.zip[/bash] przechodzimy do katalogu atlassian-jira-enterprise-4.0/edit-webapp/WEB-INF/classes. Musimy tutaj zmienić końcówkę pliku entityengine.xml: [xml classname=\u0026ldquo;xml\u0026rdquo;] \u0026lt;!-- Orion format: \u0026ndash;\u0026gt; \u0026lt;!-- JBoss format: \u0026ndash;\u0026gt; \u0026lt;!-- Weblogic format: \u0026ndash;\u0026gt; [/xml] Poszczególne atrybuty oznaczają:\nfield-type-name - rodzaj bazy danych, wartość postgres72 oznacza PostgreSQL 7.2 i nowsze. schema-name - nazwa domyślnego schematu, trzeba przepisać z PUBLIC, które akceptuje HSQL na public jndi-jdbc/jndi-name - pozostawiamy bez zmian, nasz data source będzie w lokalizacji java:comp/env/jdbc/JiraDS Pozostaje ustawienie jira.home w pliku jira-application.properties i uruchomienie polecenia build.sh. Po tych krokach tworzymy plik jira.xml w którym zdefiniujemy kontekst tej aplikacji. [xml classname=\u0026ldquo;xml\u0026rdquo;] [/xml] Plik kopiujemy do $TOMCAT_HOME/conf/Catalina/localhost. Procedura instalacji powinna przebiegać podobnie jak w przypadku Crowd, czyli podajemy licencję, określamy bazę danych (java:comp/env/jdbc/JiraDS) i kilka kolejnych parametrów.\nInstalacja GreenHopper GreenHopper jako dodatek do JIRA nie wymaga konfiguracji bazy danych. Jedyne co robimy po jego pobraniu to kopiujemy go do $JIRA_HOME/plugins/installed-plugins. Reload kontekstu z managera Tomcata, i przechodzimy do administracji naszym bugtrackerem. W lewym menu szukamy sekcji System/GreenHopper Licence. Po podaniu klucza należy stworzyć projekt. Bez niego nie zobaczymy GreenHoppera w akcji.\nInstalacja Confluence Ostatni krok to instalacja Confluence. Pobieramy dystrybucję WAR/EAR: Tutaj też czeka nas nieco zabawy, ale nie tak dużo. Po rozpakowaniu [bash]unzip confluence-3.0.2.zip[/bash] edytujemy plik confluence-3.0.2/confluence/WEB-INF/classes/confluence-init.properties: [plain]confluence.home=/var/lib/tomcat-6/atlassian/confluence-home[/plain]\nMając to wszystko, możemy spokojnie zająć kontekstem confluence.xml: [xml classname=\u0026ldquo;xml\u0026rdquo;] [/xml] Plik podobnie jak poprzednie zapisujemy w $TOMCAT_HOME/conf/Catalina/localhost. Po tym wszystkim instalujemy.\nKonfiguracja Apache Skakanie po portach i kontekstach nie jest bardzo wygodne, dlatego też warto skonfigurować Apache i mod_proxy aby wszystko było dostępne z poziomu portu 80, a nie 8080. W ten oto sposób Nexus którego używamy jest widoczny pod adresem repository.code-house.org, a nie localhost:8080. W konfiguracji vhosta umieszczamy: [plain]\u0026lt;IfModule mod_proxy.c\u0026gt; ProxyRequests On\nProxyPass /jira http://localhost:8080/jira ProxyPassReverse /jira http://localhost:8080/jira ProxyPreserveHost On\nProxyPass /confluence http://localhost:8080/confluence ProxyPassReverse /confluence http://localhost:8080/confluence ProxyPreserveHost On\nProxyPass /crowd http://localhost:8080/crowd ProxyPassReverse /crowd http://localhost:8080/crowd ProxyPreserveHost On\n[/plain]\nPodsumowanie Instalacja tych 3 aplikacji (nie licząc GreenHoppera) zajęła mi praktycznie cały dzień. Przyczyną największych problemów był Tomcat i wszystko inne - czyli np. źle wypakowane archiwum. Diagnostyka z logów Tomcata jest trudna, nie uświadczyłem w nich stack trace z wyjątkiem że nie może połączyć się do bazy. Nie mogłem zestawić również log4j na poziomie kontenera - który kłócił się później z Nexusem, a konfiguracja commons-logging jest jak na moje oko pokręcona. Po tym jak już dowiedziałem się co Tomcat powinien mieć w lib/ poszło z górki. Jeszcze nie zdecydowałem się na integrację JIRA i Confluence z Crowd ponieważ pierwsze podejście było nieudane i JIRA odmówiła uruchomienia się grzecznie zgłaszając java.lang.NullPointerException. :) Mam nadzieję, że dzięki tej krótkiej instrukcji Wy drodzy czytelnicy nie będziecie mieli tylu problemów.\n","permalink":"http://localhost:1313/2009/10/instalowanie-oprogramowania-atlassian-cz-1/","summary":"\u003cp\u003eKilka dni temu trafiłem na informacje o tym, że firma Atlassian uruchomiła \u0026ldquo;promocję\u0026rdquo; w której wyprzedaje licencje startowe na swoje produkty za 10$. Tym oto sposobem za równowartość dobrego obuwia (niecałe 175 zł) wszedłem w posiadanie sześciu licencji na Crowd, Jira, GreenHopper, Confluence, Fisheye i Bamboo. W poście tym krótki opis instalacji na Tomcat 6.x pierwszych czterech.\u003c/p\u003e\n\u003ch2 id=\"przygotowania\"\u003ePrzygotowania\u003c/h2\u003e\n\u003cp\u003eUprzedzam, że instrukcja jest pisana z pamięci więc mogą pojawić się jakieś braki. W przypadku gdy instrukcja nie zadziała proszę o komentarz, a postaram się pomóc i uzupełnić wpis tak by był kompletny.\nAby ułatwić sobie życie i zaoszczędzić pamięć na serwerze wszystkie produkty będzie obsługiwała jedna instancja Tomcat i PostgreSQL. Niestety Fisheye i Bamboo są dostępne tylko w wersji standalone, stąd proces ich instalacji będzie nieco inny. Zanim ruszymy z całością pobieramy od producenta oprogramowanie.\n\u003cimg alt=\"Pobieranie Crowd\" loading=\"lazy\" src=\"/wp-content/uploads/crowd.jpg\"\u003e\nPrzeskakujemy na zakładkę Linux i następnie klikamy w prawym górnym rogu i pobieramy wersję standalone. Wykonujemy polecenie\n[bash]tar -xvzf atlassian-crowd-2.0.2.tar.gz[/bash]\u003c/p\u003e","title":"Instalowanie oprogramowania Atlassian cz. 1"},{"content":"Do tej pory tworząc kod z użyciem typów generycznych zawsze borykałem się z problemem - jak dobrać się do klasy na podstawie któregoś parametru. Rozwiązanie znalazłem przeglądając w internecie kod jakieś przykładowej aplikacji. Ot znowu kilka linii które uporządkują kod i zmniejszą ilość powtórzeń. :-)\nDbanie o porządek w kodzie to obowiązek każdego programisty. Stąd podział aplikacji na warstwy, wyodrębnianie wspólnego kodu do typów abstrakcyjnych i tak dalej. Są jednak miejsca, których do tej pory nie potrafiłem uporządkować dobrze - były to wszelkiego rodzaju DAO, które zawsze wyglądały podobnie. Interfejs, klasa abstrakcyjna, pochodna wywołująca chroniony konstruktor. Wszystko po to by w klasie abstrakcyjnej móc zdefiniować metodę readById. Oto przykład takiego kodu: [java]// Ogólny interfejs dostępu do danych // T to typ encji, K to typ klucza w danej encji. public interface GenericDAO\u0026lt;T, K\u0026gt; { void save(T instance); void create(T newInstance); void update(T existingInstance); boolean delete(T instance); T readById(K id); List getAll(); } // Implementacja oparta o mechanizmy Springa public abstract class AbstractDAO\u0026lt;T extends BaseEntity, K\u0026gt; extends JpaDaoSupport implements GenericDAO\u0026lt;T, K\u0026gt; { private Class typeClass; protected AbstractDAO(Class typeClass) { this.typeClass = typeClass; } // pobranie obiektu na bazie id public T readById(K id) { return getJpaTemplate().find(typeClass, id); } }\n// Przekazanie User.class do AbstractDAO by te mogło // użyć go do odpytywania bazy danych public class UserJpaDAO extends AbstractDAO\u0026lt;User, Long\u0026gt; implements UserDAO { public UserJpaDAO() { super(User.class); } } [/java] W tym wypadku typ generyczny zamiast uprościć życie nieco je komplikuje - w ostatniej klasie musimy pisać dwa razy User - raz jako parametr typu, dwa przekazując go do konstruktora klasy abstrakcyjnej. Logicznie rzecz biorąc. Znany jest typ generyczny zatem to nazwa klasy też powinna być do wykrycia. I tak rzeczywiście jest. Od JDK 1.5 istnieje interfejs ParameterizedType, który zawiera metodę getActualTypeArguments, Wystarczy dobrać się do tego obiektu i będzie z górki. Oto jak ja to rozwiązałem: [java] // Copyright (C) 2009 Code-House // All rights reserved package org.code_house.manager.dataaccess.jpa.util;\nimport java.lang.reflect.ParameterizedType; import java.lang.reflect.Type;\n/\\\\ \\* Klasa pomocnicza do operowania na typach generycznych. \\* \\* @author Łukasz Dywicki [email protected] \\* \\* $Id$ */ public class GenericTypeUtil {\n/\\\\ \\* Konstruktor prywatny, na wypadek gdyby ktoś chciał stworzyć instancję \\* utila. :) */ private GenericTypeUtil() {}\n/\\\\ \\* Pobranie argumentów dla danego typu na bazie klasy. */ public static Class[] getGenericTypes(Class type) { Type superclass = type.getGenericSuperclass(); if (superclass instanceof ParameterizedType) { ParameterizedType genericTypeClass = (ParameterizedType) superclass; return cast(genericTypeClass.getActualTypeArguments()); } return new Class[0]; }\n// Rzutowanie w dół z Type do Class. public static Class[] cast(Type[] types) { Class[] classTypes = new Class[types.length]; for (int i = 0, j = types.length; i \u0026lt; j; i++) { classTypes[i] = (Class) types[i]; } return classTypes; } } [/java]\nCo zwróci nam wywołanie GenericTypeUtil.getGenericTypes(UserJpaDAO.class)? To czego potrzebujemy! :) [plain] [class org.code_house.manager.domain.User, class java.lang.Long] [/plain] Czy znaliście ten sposób? A może tylko ja byłem nieświadom tego rozwiązania?\n","permalink":"http://localhost:1313/2009/10/typy-generyczne-od-teraz-sa-mniej-anonimowe/","summary":"\u003cp\u003eDo tej pory tworząc kod z użyciem typów generycznych zawsze borykałem się z problemem - jak dobrać się do klasy na podstawie któregoś parametru. Rozwiązanie znalazłem przeglądając w internecie kod jakieś przykładowej aplikacji. Ot znowu kilka linii które uporządkują kod i zmniejszą ilość powtórzeń. :-)\u003c/p\u003e\n\u003cp\u003eDbanie o porządek w kodzie to obowiązek każdego programisty. Stąd podział aplikacji na warstwy, wyodrębnianie wspólnego kodu do typów abstrakcyjnych i tak dalej. Są jednak miejsca, których do tej pory nie potrafiłem uporządkować dobrze - były to wszelkiego rodzaju DAO, które zawsze wyglądały podobnie. Interfejs, klasa abstrakcyjna, pochodna wywołująca chroniony konstruktor. Wszystko po to by w klasie abstrakcyjnej móc zdefiniować metodę \u003cstrong\u003ereadById\u003c/strong\u003e. Oto przykład takiego kodu:\n[java]// Ogólny interfejs dostępu do danych\n// T to typ encji, K to typ klucza w danej encji.\npublic interface GenericDAO\u0026lt;T, K\u0026gt; {\nvoid save(T instance);\nvoid create(T newInstance);\nvoid update(T existingInstance);\nboolean delete(T instance);\nT readById(K id);\nList\u003cT\u003e getAll();\n}\n// Implementacja oparta o mechanizmy Springa\npublic abstract class AbstractDAO\u0026lt;T extends BaseEntity, K\u0026gt; extends\nJpaDaoSupport implements GenericDAO\u0026lt;T, K\u0026gt; {\nprivate Class\u003cT\u003e typeClass;\nprotected AbstractDAO(Class typeClass) {\nthis.typeClass = typeClass;\n}\n// pobranie obiektu na bazie id\npublic T readById(K id) {\nreturn getJpaTemplate().find(typeClass, id);\n}\n}\u003c/p\u003e","title":"Typy generyczne od teraz są mniej anonimowe"},{"content":"W poprzednim wpisie przedstawiłem sposób na redukcję kodu w encjach przy pomocy dziedziczenia i adnotacji @MappedSuperclass. Rozwiązanie to możemy również stosować aby tworzyć kod bardziej przenośny, który niewielkim kosztem można użyć w innych projektach.\nWiększość aplikacji webowych stosuje autoryzację opartą o role (ang. Role Based Access Control), w takich wypadkach mamy zazwyczaj encję User oraz Role, pierwszą odpowiedzialną za przetrzymywanie informacji o użytkowniku a druga nazwy ról. O ile role są obszarem stałym - zawsze mają nazwę - o tyle użytkownicy często mają różne wariacje i relacje. Ot choćby powiązanie konta użytkownika z firmą. [sourcecode lang=\u0026ldquo;java\u0026rdquo;] // Copyright (C) 2009 Code-House // All rights reserved package org.code_house.security.domain;\nimport java.util.Calendar; import java.util.HashSet; import java.util.Set;\nimport javax.persistence.Column; import javax.persistence.ManyToMany; import javax.persistence.MappedSuperclass; import javax.persistence.Temporal; import javax.persistence.TemporalType;\nimport org.code_house.domain.BaseEntity;\n/\\\\ \\* Klasa reprezentująca użytkownika. Powinna ona zostać nadpisana w docelowym \\* systemie poprzez plik orm.xml. \\* \\* @author Łukasz Dywicki. */ @MappedSuperclass public class SecurityUser extends BaseEntity {\n/\\\\ \\* Hasło użytkownika. */ @Column private String password;\n/\\\\ \\* Login użytkownika. */ @Column private String username;\n/\\\\ \\* Konto wygasło. */ @Column @Temporal(TemporalType.TIMESTAMP) private Calendar expire;\n/\\\\ \\* Grupy do których przynależy użytkownik. */ @ManyToMany(mappedBy = \u0026ldquo;users\u0026rdquo;) private Set roles;\n/\\\\ \\* Konto zablokowane np. po 3 nieudanych próbach logowania. */ @Column private boolean locked;\n/\\\\ \\* Konto wyłączone np. przez administratora. */ @Column private boolean enabled;\n// Dalej gettery i settery } [/sourcecode] Rola ma niekompletną definicję relacji do klasy SecurityUser, którą należy uzupełnić o informacje na temat encji docelowej i definicji tabeli pośredniczącej. [sourcecode lang=\u0026ldquo;java\u0026rdquo;] // Copyright (C) 2009 Code-House // All rights reserved package org.code_house.security.domain;\nimport javax.persistence.Entity; import javax.persistence.ManyToMany; import javax.persistence.Table;\nimport org.code_house.domain.NamedEntity;\n/\\\\ \\* Klasa reprezentująca rolę. Może to być np ADMIN, USER bądź cokolwiek innego. \\* \\* @author Łukasz Dywicki [email protected] */ @Entity @Table(name = \u0026ldquo;roles\u0026rdquo;) public class Role extends NamedEntity {\n@ManyToMany @JoinTable(name = \u0026ldquo;users_roles\u0026rdquo;, joinColumns = @JoinColumn(name = \u0026ldquo;role_id\u0026rdquo;, referencedColumnName = \u0026ldquo;id\u0026rdquo;) ) private Set users;\n// gettery i settery } [/sourcecode] Oto kawałek konfiguracji XML, która uzupełni metadane i pozwoli na uruchomienie kodu. Atrybut target-entity pozwala na określenie tabeli docelowej relacji podczas gdy element inverse-join-column uzupełnia definicję tabeli pośredniczącej. [sourcecode lang=\u0026ldquo;xml\u0026rdquo; classname=\u0026ldquo;xml\u0026rdquo;]\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e org.code_house.security.domain\n\\[/sourcecode\\] Przykład ten można wykorzystać by uzupełniać relacje, których nie sposób odzwierciedlić w kodzie.\n","permalink":"http://localhost:1313/2009/10/xml-i-adnotacje-kod-ogolnego-przeznaczenia-i-jpa/","summary":"\u003cp\u003eW \u003ca href=\"/2009/09/dwie-klasy-redukujace-ilosc-kodu-w-encjach-jpa/\"\u003epoprzednim wpisie\u003c/a\u003e przedstawiłem sposób na redukcję kodu w encjach przy pomocy dziedziczenia i adnotacji @MappedSuperclass. Rozwiązanie to możemy również stosować aby tworzyć kod bardziej przenośny, który niewielkim kosztem można użyć w innych projektach.\u003c/p\u003e\n\u003cp\u003eWiększość aplikacji webowych stosuje autoryzację opartą o role (ang. \u003cem\u003eRole Based Access Control\u003c/em\u003e), w takich wypadkach mamy zazwyczaj encję User oraz Role, pierwszą odpowiedzialną za przetrzymywanie informacji o użytkowniku a druga nazwy ról. O ile role są obszarem stałym - zawsze mają nazwę - o tyle użytkownicy często mają różne wariacje i relacje. Ot choćby powiązanie konta użytkownika z firmą.\n[sourcecode lang=\u0026ldquo;java\u0026rdquo;]\n// Copyright (C) 2009 Code-House\n// All rights reserved\npackage org.code_house.security.domain;\u003c/p\u003e","title":"XML i Adnotacje - kod ogólnego przeznaczenia i JPA"},{"content":"Z pewnością nie jest to odkrycie godne podziwu czy też coś, co może realizować z nowinkami JPA 2.0, nie mniej jest to kod bez którego żaden projekt obejść się nie może - mianowicie identyfikacja encji.\nBorykałem się z problemem dosyć pospolitym, mianowicie pozbyciem się z każdej encji kodu: [sourcecode lang=\u0026ldquo;java\u0026rdquo;]@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; [/sourcecode] Nic dziwnego, 40 encji to aż 120 powtórzonych, niepotrzebnie powielonych linii. Nie są obce mi wzorce dziedziczenia, które Martin Fowler opisywał w swojej książce, w tym przypadku chodzi o dziedziczenie mapowanych pól a nie fizyczne odwzorowanie tej hierarchii, czyli zagrywka czysto techniczna.\nOdpowiedni kod znalazłem w przykładowej aplikacji z dystrybucji Spring Framework 3. Jedyny szkopuł to że całość spisana w XML. W mapowaniu jest jednak rozwiązanie zagadki - mianowicie element mapped-superclass. Po nitce do kłębka - trafiłem na adnotację @MappedSuperclass. Kilka linii które uprościły mój kod to: [sourcecode lang=\u0026ldquo;java\u0026rdquo;]// Copyright (C) 2009 Code-House // All rights reserved package org.code_house.domain;\nimport javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.MappedSuperclass;\n/\\\\ \\* Klasa bazowa dla encji. \\* \\* @author Łukasz Dywicki [email protected] */ @MappedSuperclass public class BaseEntity {\n/\\\\ \\* Identyfikator encji. */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;\n/\\\\ \\* Pobranie wartości pola id. \\* \\* @return Wartość id. */ public Long getId() { return id; }\n/\\\\ \\* Ustawienie wartości pola id. \\* \\* @param id Nowa wartość pola id. */ public void setId(Long id) { this.id = id; } } [/sourcecode]\nDrugi przypadek to encja nazwana, czyli coś co ma nazwę. Może to być encja reprezentująca klienta bądź firmę. Cokolwiek, co można nazwać. Ot, chociażby samochód (dla przykładu na swoje seicento zwykłem mówić ciężarówka), ilość takich przypadków można naturalnie mnożyć, ale nie o to nam chodzi.\n[sourcecode lang=\u0026ldquo;java\u0026rdquo;] // Copyright (C) 2009 Code-House // All rights reserved package org.code_house.domain;\nimport javax.persistence.Column; import javax.persistence.MappedSuperclass;\n/\\\\ \\* Encja zawierająca pole z nazwą. \\* \\* @author Łukasz Dywicki [email protected] */ @MappedSuperclass public class NamedEntity extends BaseEntity {\n/\\\\ \\* Nazwa przypisana do encji. */ @Column private String name;\n/\\\\ \\* Pobranie wartości pola name. \\* \\* @return Wartość name. */ public String getName() { return name; }\n/\\\\ \\* Ustawienie wartości pola name. \\* \\* @param name Nowa wartość pola name. */ public void setName(String name) { this.name = name; }\n} [/sourcecode]\nZamierzony efekt osiągnięty - definicje encji krótsze, kod sprzątnięty. Całość projektu, razem z dokumentacją i tym podobnymi jest dostępna w repozytorium Code-House.\n","permalink":"http://localhost:1313/2009/09/dwie-klasy-redukujace-ilosc-kodu-w-encjach-jpa/","summary":"\u003cp\u003eZ pewnością nie jest to odkrycie godne podziwu czy też coś, co może realizować z nowinkami JPA 2.0, nie mniej jest to kod bez którego żaden projekt obejść się nie może - mianowicie identyfikacja encji.\u003c/p\u003e\n\u003cp\u003eBorykałem się z problemem dosyć pospolitym, mianowicie pozbyciem się z każdej encji kodu:\n[sourcecode lang=\u0026ldquo;java\u0026rdquo;]@Id\n@GeneratedValue(strategy = GenerationType.IDENTITY)\nprivate Long id;\n[/sourcecode]\nNic dziwnego, 40 encji to aż 120 powtórzonych, niepotrzebnie powielonych linii. Nie są obce mi wzorce dziedziczenia, które \u003ca href=\"http://martinfowler.com\"\u003eMartin Fowler\u003c/a\u003e opisywał w swojej książce, w tym przypadku chodzi o dziedziczenie mapowanych pól a nie fizyczne odwzorowanie tej hierarchii, czyli zagrywka czysto techniczna.\u003c/p\u003e","title":"Dwie klasy redukujące ilość kodu w encjach JPA"},{"content":"Jakiś czas temu zapraszaliśmy na tym blogu zainteresowanych na Warszawski Eclipse DemoCamp Galileo 2009. Jest nam niezmiernie miło ogłosić, że temat poruszany na tym spotkaniu przez Code-House Software został kontynuowany. Wsparcie dla Apache ServiceMix w oparciu o Spring IDE zainteresowało społeczność jak i organizacje skupione wokół projektu, między innymi FUSE Source. Nie będzie to oczywiście alternatywa dla narzędzi oferowanych przez tą firmę a raczej dopełnienie funkcjonalności, których w tej chwili trudno szukać.\nStrona projektu znajduje się na razie na wiki bug trackera Code-House i jest na nim kilka informacji odnośnie celów projektu i nawet parę zadań. :-) Na pytanie kiedy pojawi się działająca wersja ciężko nam odpowiedzieć ponieważ w obecnej chwili siły przerobowe naszej firmy oprócz zaangażowania w kontrakt muszą podołać przygotowaniu akcji marketingowej w prasie oraz internecie. Miejmy nadzieję, że przed końcem wakacji pojawi się działająca wersja. Oczywiście nie jest to jedyny sposób w jaki Code-House wspiera społeczność projektu Apache ServiceMix, w planach mamy wspomaganie paru komponentów które wzbogacą funkcjonalność magistrali.\nObecnie projekt ma przygotowaną infrastrukturę w oparciu o Apache Maven 2 tak by całość mogła być budowana automatycznie. Sporym problemem z tworzeniem rozszerzeń do Eclipse IDE jest właśnie ciągła integracja. Zazwyczja cały proces jest realizowany przy pomocy generowanych plików zgodnych z Apache Ant. Niestety by je uruchomić trzeba i tak mieć lokalną instalację Eclipse. Po kilku dniach wysiłków udało się jednak znaleźć rozwiązanie a lokalną instalację wykorzystywać tylko w przypadku konieczności. Zainteresowanych zapraszam do repozytorium ze źródłami projektu.\nOgólnie rzecz biorąc budowanie wtyczek, update site (czy repozytoriów p2), bez użycia Eclipse jest zadaniem trudnym. Mimo tego, że P2 Publisher wygląda na niezależny od samego Eclipse nie można go uruchomić poza OSGi/Equinox. Próbowaliśmy obejść ten problem dodając własne implementacje części interfejsów jednak ilość zależności w kodzie jest bardzo duża i po pół dnia walki niestety trzeba było zrezygnować by nie zabrnąć w ślepą uliczkę. Podobnie ma się kwestia z taskami ant, które są równie oporne w działaniu. Alternatywą był projekt Buckminster i adaptery do Mavena. Budowanie jednak również musiało by wówczas być takie jak zwykle w świecie Eclipse - przez Ant.\nRozwiązaniem okazało się połączenie maven-eclipse-plugin:to-maven oraz maven-bundle-plugin z projektu Apache Felix. Pierwszy zapewnił wyeksportowanie platformy Eclipse do naszego repozytorim Mavena podczas gdy drugi generuje odpowiednie manifesty zgodne z OSGi. Update site jest już końcową fazą budowania. Z użyciem maven-assembly-plugin tworzymy strukturę właściwą Eclipse. Opcjonalnym elementem, który wymaga instalacji Eclipse na komputerze jest stworzenie repozytorium P2 uruchamianym przez maven-exec-plugin:exec. Pracy było dużo ale mamy nadzieję że zaprocentuje ona w przyszłości przyśpieszając development i wprowadzanie zmian do projektu. Po więcej informacji o postępach w pracach zapraszam ponownie na blog do kategorii ServiceMix IDE.\n","permalink":"http://localhost:1313/2009/07/servicemix-ide-integration/","summary":"\u003cp\u003eJakiś czas temu \u003ca href=\"/2009/05/warszawski-eclipse-democamp-galileo-2009/\"\u003ezapraszaliśmy na tym blogu\u003c/a\u003e zainteresowanych na Warszawski Eclipse DemoCamp Galileo 2009. Jest nam niezmiernie miło ogłosić, że temat poruszany na tym spotkaniu przez Code-House Software został kontynuowany. Wsparcie dla \u003ca href=\"http://servicemix.apache.org/\"\u003eApache ServiceMix\u003c/a\u003e w oparciu o \u003ca href=\"http://springide.org\"\u003eSpring IDE\u003c/a\u003e zainteresowało społeczność jak i organizacje skupione wokół projektu, między innymi \u003ca href=\"http://fusesource.com/\"\u003eFUSE Source\u003c/a\u003e. Nie będzie to oczywiście alternatywa dla narzędzi oferowanych przez tą firmę a raczej dopełnienie funkcjonalności, których w tej chwili trudno szukać.\u003c/p\u003e\n\u003cp\u003eStrona projektu znajduje się na razie na \u003ca href=\"http://projects.code-house.org/wiki/sm-ide\"\u003ewiki\u003c/a\u003e bug trackera Code-House i jest na nim kilka informacji odnośnie celów projektu i nawet parę zadań. :-) Na pytanie kiedy pojawi się działająca wersja ciężko nam odpowiedzieć ponieważ w obecnej chwili siły przerobowe naszej firmy oprócz zaangażowania w kontrakt muszą podołać przygotowaniu akcji marketingowej w prasie oraz internecie. Miejmy nadzieję, że przed końcem wakacji pojawi się działająca wersja. Oczywiście nie jest to jedyny sposób w jaki Code-House wspiera społeczność projektu Apache ServiceMix, w planach mamy wspomaganie paru komponentów które wzbogacą funkcjonalność magistrali.\u003c/p\u003e","title":"ServiceMix IDE integration"},{"content":" W najbliższy weekend odbędzie się największa warszawska, darmowa, konferencja poświęcona Javie. Nasza firma wsparła przedsięwzięcie niewielką kwotą stąd też zapraszamy do wzięcia udziału w konferencji. :) Tematy zostały podzielone na trzy kategorie:\nJava - technologicznie, czyli o nowinkach i bibliotekach (7 prezentacji) Java - pragmatycznie, optymalizacja, testy (8 prezentacji) Java - koncepcyjnie, niezwiązane bezpośrednio z kodem (3 prezentacje) Jak widać jest wiele tematów do wyboru. Nowością jest dodatkowa ścieżka warsztatowa, podczas której odbędzie się tylko 1 prezentacja. Dla tych, którzy nie będą mogli pojawić się na konferencji niespodzianka - organizatorzy będą starać się nagrywać wszystkie sesje tak by nic nie uciekło. Całość będzie naturalnie dostępna później, najprawdopodobniej na Parleys.\nRaz jeszcze zapraszamy na konferencję. Będzie to znakomity początek lata dla programistów i nie tylko! :-)\n","permalink":"http://localhost:1313/2009/06/javarsovia-2009/","summary":"\u003cp\u003e\u003cimg alt=\"Javarsovia Logo\" loading=\"lazy\" src=\"/wp-content/uploads/javarsovia.jpg\"\u003e W najbliższy weekend odbędzie się największa warszawska, darmowa, konferencja poświęcona Javie. Nasza firma wsparła przedsięwzięcie niewielką kwotą stąd też zapraszamy do wzięcia udziału w konferencji. :) Tematy zostały podzielone na trzy kategorie:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eJava - technologicznie, czyli o nowinkach i bibliotekach (7 prezentacji)\u003c/li\u003e\n\u003cli\u003eJava - pragmatycznie, optymalizacja, testy (8 prezentacji)\u003c/li\u003e\n\u003cli\u003eJava - koncepcyjnie, niezwiązane bezpośrednio z kodem (3 prezentacje)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eJak widać jest wiele tematów do wyboru. Nowością jest dodatkowa ścieżka warsztatowa, podczas której odbędzie się tylko 1 prezentacja. Dla tych, którzy nie będą mogli pojawić się na konferencji niespodzianka - organizatorzy będą starać się nagrywać wszystkie sesje tak by nic nie uciekło. Całość będzie naturalnie dostępna później, najprawdopodobniej na \u003ca href=\"http://parleys.com/\"\u003eParleys\u003c/a\u003e.\u003c/p\u003e","title":"Javarsovia 2009"},{"content":"Zgodnie z obietnicą z poprzedniego postu zamieszczam materiały z prezentacji którą wczoraj przeprowadziłem w ramach Warszawskiego Eclipse DemoCamp Galileo 2009.\nCelem prezentacji było dodanie obsługi nowej (niestandardowej) przestrzeni nazw w Spring IDE. Jako dobry przykład rozbudowanej przestrzeni nazw wybrałem konfigurację komponentu servicemix-file. Jako że nie udało mi się przed prezentacją zmusić Apache XBean do pracy wewnątrz Eclipse musiałem stworzyć własny namespace handler. Dopiero wczoraj, późno w nocy stworzyłem patch który umożliwia podpięcie normalnego handlera. Jakkolwiek przykład dla spójności pozostał ze starym kodem.\nZapraszam do pobierania [slajdów](http://code-house.org/downloads/software/prezentacje/Spring IDE.ppsx) z prezentacji oraz kodu [kodu źródłowego](http://code-house.org/downloads/software/przyklady/Spring IDE.zip) projektu.\nNiestety nie udało mi się omówić wszystkich aspektów które chciałem, zatem możecie spodziewać się publikacji na temat rozszerzania Spring IDE. :-).\n","permalink":"http://localhost:1313/2009/06/materialy-z-eclipse-democamp/","summary":"\u003cp\u003eZgodnie z obietnicą z \u003ca href=\"/2009/05/warszawski-eclipse-democamp-galileo-2009/\"\u003epoprzedniego\u003c/a\u003e postu zamieszczam materiały z prezentacji którą wczoraj przeprowadziłem w ramach \u003ca href=\"http://groups.google.com/group/warszawa-jug/web/eclipse-democamp-2009\"\u003eWarszawskiego Eclipse DemoCamp Galileo 2009\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/wp-content/uploads/ide2.png\"\u003e\u003cimg alt=\"Spring IDE\" loading=\"lazy\" src=\"/wp-content/uploads/ide2-300x179.png\"\u003e\u003c/a\u003e Celem prezentacji było dodanie obsługi nowej (niestandardowej) przestrzeni nazw w Spring IDE. Jako dobry przykład rozbudowanej przestrzeni nazw wybrałem konfigurację komponentu \u003ca href=\"http://servicemix.apache.org/SM/servicemix-file.html\"\u003eservicemix-file\u003c/a\u003e. Jako że nie udało mi się przed prezentacją zmusić \u003ca href=\"http://geronimo.apache.org/xbean/\"\u003eApache XBean\u003c/a\u003e do pracy wewnątrz Eclipse musiałem stworzyć własny namespace handler. Dopiero wczoraj, późno w nocy stworzyłem \u003ca href=\"https://issues.apache.org/jira/browse/XBEAN-132\"\u003epatch\u003c/a\u003e który umożliwia podpięcie normalnego handlera. Jakkolwiek przykład dla spójności pozostał ze starym kodem.\u003c/p\u003e","title":"Materiały z Eclipse DemoCamp"},{"content":"W dniu 2 czerwca 2009 odbędzie się Warszawski Eclipse DemoCamp Galileo 2009, nasza firma wspiera to wydarzenie merytorycznie oraz finansowo. Głównym sponsorem jest fundacja Eclipse. Działanie to doskonale wpisuje się w profil naszej firmy, której celem jest współpraca ze społecznością oraz promowanie rozwiązań Open Source - Spring IDE - o którym będzie mowa to projekt z otwartym kodem źródłowym rozwijanym w dużej mierze przez SpringSource.\nTematy które będą prezentowane:\n18:00-18:15 Spring IDE, czyli o wsparciu dla Springa wewnątrz IDE. Łukasz Dywicki 18:20-18:35 Wyślij swoją myszę na urlop, czyli o skrótach i szablonach w Eclipse. Wojciech Erbetowski 18:40-18:55 Wtyczka do Eclipse w 5 \u0026hellip; no może 15 minut. Mateusz Zięba 19:00-19:15 Rozszerzanie JDT dzięki Equinox Aspects i AJDT weaving service. Michał \u0026ldquo;migi\u0026rdquo; Grzejszczak 19:20-19:35 Z Eclipsem w chmurach w 15 minut, czyli jak użyć GoogleApp Engine wraz z pluginem do Eclipse, aby uruchomić aplikację w 15 minut. Łukasz Lenart 19:40-19:55 Oracle JRockit Mission Control, czyli demonstracja profilowania i diagnostyki aplikacji Java przy użyciu Eclipse. Waldemar Kot Pierwsza pogrubiona prezentacja to nasza :-). Co kryje się w podtytule wsparcie dla Springa wewnątrz IDE? Głownie obszary związane z edycja kontekstu zapisanego w XML, co dokładnie? Tego dowiecie się już na prezentacji. Materiały jak i przykłady zostaną opublikowane na tym blogu po wtorku. Raz jeszcze serdecznie zapraszam na świętowanie nowego wydania. :)\n","permalink":"http://localhost:1313/2009/05/warszawski-eclipse-democamp-galileo-2009/","summary":"\u003cp\u003eW dniu 2 czerwca 2009 odbędzie się \u003ca href=\"http://groups.google.com/group/warszawa-jug/web/eclipse-democamp-2009\"\u003eWarszawski Eclipse DemoCamp Galileo 2009\u003c/a\u003e, nasza firma wspiera to wydarzenie merytorycznie oraz finansowo. Głównym sponsorem jest \u003ca href=\"http://www.eclipse.org/\"\u003efundacja Eclipse\u003c/a\u003e.\nDziałanie to doskonale wpisuje się w profil naszej firmy, której celem jest współpraca ze społecznością oraz promowanie rozwiązań Open Source - Spring IDE - o którym będzie mowa to projekt z otwartym kodem źródłowym rozwijanym w dużej mierze przez \u003ca href=\"http://springsource.com\"\u003eSpringSource\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eTematy które będą prezentowane:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e18:00-18:15 Spring IDE, czyli o wsparciu dla Springa wewnątrz IDE\u003c/strong\u003e. \u003cem\u003eŁukasz Dywicki\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003e18:20-18:35 Wyślij swoją myszę na urlop, czyli o skrótach i szablonach w Eclipse. \u003cem\u003eWojciech Erbetowski\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003e18:40-18:55 Wtyczka do Eclipse w 5 \u0026hellip; no może 15 minut. \u003cem\u003eMateusz Zięba\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003e19:00-19:15 Rozszerzanie JDT dzięki Equinox Aspects i AJDT weaving service. \u003cem\u003eMichał \u0026ldquo;migi\u0026rdquo; Grzejszczak\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003e19:20-19:35 Z Eclipsem w chmurach w 15 minut, czyli jak użyć GoogleApp Engine wraz z pluginem do Eclipse, aby uruchomić aplikację w 15 minut. \u003cem\u003eŁukasz Lenart\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003e19:40-19:55 Oracle JRockit Mission Control, czyli demonstracja profilowania i diagnostyki aplikacji Java przy użyciu Eclipse. \u003cem\u003eWaldemar Kot\u003c/em\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003ePierwsza pogrubiona prezentacja to nasza :-). Co kryje się w podtytule \u003cem\u003ewsparcie dla Springa wewnątrz IDE\u003c/em\u003e? Głownie obszary związane z edycja kontekstu zapisanego w XML, co dokładnie? Tego dowiecie się już na prezentacji. Materiały jak i przykłady zostaną opublikowane na tym blogu po wtorku. Raz jeszcze serdecznie zapraszam na świętowanie nowego wydania. :)\u003c/p\u003e","title":"Warszawski Eclipse DemoCamp Galileo 2009"},{"content":"Z ogromną przyjemnością pragniemy poinformować, że od 2 dni z naszego serwera można pobrać wszystkie projekty rozwijane w ramach fundacji Eclipse. Dołączyliśmy tym samym do grona 2 innych polskich mirrorów.\nOd strony technicznej mirror jest uruchomiony na lighthttpd, oddzielnym IP oraz dedykowanym dysku USB 600 GB. Serwer stoi na łączu 100 mbps, stąd osiągane transfery powinny być zadowalające i użytkownicy szerokopasmowych łączy nie powinni odczuwać żadnego spowolnienia. Na naszym firmowym łączu - 10 mbps - udało się osiągnąć ponad 1M/s, czyli tyle ile fabryka dała! :-)\nRuch który generuje mirror to około 20MB/s, czyli od samego początku zaczął być używany w miarę intensywnie. Synchronizacja przy transferze 12 MB/s trwa nieco ponad godzinę. Rozmiar wszystkich plików to niecałe 260 GB, najwięcej miejsca zajmuje:\nTechnology, 51 GB Eclipse tools, 32 GB (AJDT, PDT itp) BIRT, 32 GB Platform, 28 GB TPTP, 27 GB Web tools, 16 GB Przyznacie, że WebTools które wydaje się dosyć duże jest nisko w rankingu a TPTP, które używa się sporadycznie jest objętościowo niewiele mniejsze od platformy. Nie dziwi natomiast wysoka pozycja BIRT i Tools.\nMamy nadzieję że nowa usługa przyda się użytkownikom Eclipse, zapraszamy do korzystania. Pobranie Eclipse z Code-House to tylko kilka minut :).\n","permalink":"http://localhost:1313/2009/05/szukasz-eclipse-jest-code-house/","summary":"\u003cp\u003eZ ogromną przyjemnością pragniemy poinformować, że od 2 dni z naszego serwera można pobrać wszystkie projekty rozwijane w ramach fundacji \u003ca href=\"http://eclipse.org\"\u003eEclipse\u003c/a\u003e. Dołączyliśmy tym samym do grona 2 innych polskich mirrorów.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/wp-content/uploads/eclipse-mirror1.png\"\u003e\u003cimg alt=\"Pobieramy z Code-House\" loading=\"lazy\" src=\"/wp-content/uploads/eclipse-mirror1.png\"\u003e\u003c/a\u003e Od strony technicznej mirror jest uruchomiony na \u003ca href=\"http://www.lighttpd.net/\"\u003elighthttpd\u003c/a\u003e, oddzielnym IP oraz dedykowanym dysku USB 600 GB. Serwer stoi na łączu 100 mbps, stąd osiągane transfery powinny być zadowalające i użytkownicy szerokopasmowych łączy nie powinni odczuwać żadnego spowolnienia. Na naszym firmowym łączu - 10 mbps - udało się osiągnąć ponad 1M/s, czyli tyle ile fabryka dała! :-)\u003c/p\u003e","title":"Szukasz Eclipse? Jest na Code-House!"},{"content":"Branża IT ostatnimi czasy jest targana coraz to nowymi wiadomościami o łączeniu się firm. Początkowe spekulacje o tym, że IBM chcę przejąć Javę zakończyły się tym, że Oracle kupiło Sun Microsystems. Wywołało to nie lada falę w społeczności z pytaniami co dalej z Javą i bazą MySQL?\nNie będziemy jednak roztrząsać strategii takiego giganta jak Oracle, ponieważ jest już świeższy news. :) Dwa dni temu, dokładnie 4 maja 2009 SpringSource przejęło Hyperic. O ile pierwsza nazwa jest zapewne znana większości z Was o tyle druga może być niejasna.\nHyperic jest producentem oprogramowania do monitoringu IT, jego czołowym produktem jest Hyperic HQ w wersji Enterprise oraz Open Source. HQ jest również przygotowane do tego by je rozszerzać. W oparciu o nie FUSE Source dostarcza FUSE HQ a samo SpringSource narzędzie nazwane Application Management Suite (w skrócie AMS). O popularności samego HQ może świadczyć fakt, że jego darmowa wersja jest uruchomiona w liczbie 5 000 instancji.\nNa czym jest zbudowane Hyperic HQ? Otóż w HQ jest wydzielony agent oraz serwer. Agent to niewielki program uruchomiony na monitorowanej maszynie który wykrywa usługi. Serwer do którego się łączy agent agreguje przesłane dane i w oparciu o nie może wysyłać powiadomienia o wyczerpującym się miejscu na dysku, zbyt dużym obciążeniu bazy danych. Serwer jest oparty o JBoss AS (wyobrażacie sobie klaster monitoringu). Kod aplikacji to typowe J2EE z Hibernate, Quartzem i innymi dobrze znanymi rozwiązaniami pod spodem.\nCo przemawiało za tym zakupem? SpringSource już przy przejmowaniu G2One mówił o zainteresowaniu czymś związanym z wirtualizacją i hardware - Hyperic w tym wypadku jest bardzo dobrym zakupem dzięki któremu firma stojąca za Springiem będzie mogło zaoferować wsparcie od najwcześniejszych faz projektu po wdrożenie go na dziesiątki serwerów. Nikt nie spekulował o tym że celem może być Hyperic, i jest to miła niespodzianka. Pytanie czy do wykupu ma się przygotowywać GridGain i Terracota? Na odpowiedź w Code-House czekamy z wypiekami na twarzy. :) Rod Johnson na oficjalnym blogu podkreśla że ten zakup będzie procentował łatwością monitorowania aplikacji opartych o Springa i serwerów które produkuje SpringSource. Nie pomija on również faktu że obie firmy rozwijały się w podobny sposób, z tym że w nieco innych obszarach.\nZ perspektywy Code-House zakup ten jest powodem do radości ponieważ zarówno z pierwszą jak i drugą firmą prowadziliśmy rozmowy o możliwości współpracy. Połączenie tych dwóch kompanii z pewnością uprości przystępowanie do programów partnerskich i miejmy nadzieję obniży koszty. SpringSource realizuje jasną wizję, co bardzo się nam podoba.\nWięcej w sieci:\nOficjalna informacja na stronie Hyperic. Wpis na blogu Hyperic. Wypowiedź Roda Johnson ze SpringSource. ","permalink":"http://localhost:1313/2009/05/springsource-kupuje-hyperic/","summary":"\u003cp\u003eBranża IT ostatnimi czasy jest targana coraz to nowymi wiadomościami o łączeniu się firm. Początkowe spekulacje o tym, że \u003ca href=\"http://ibm.com\"\u003eIBM\u003c/a\u003e chcę przejąć Javę zakończyły się tym, że \u003ca href=\"http://oracle.com\"\u003eOracle\u003c/a\u003e kupiło \u003ca href=\"http://sun.com\"\u003eSun Microsystems\u003c/a\u003e. Wywołało to nie lada falę w społeczności z pytaniami co dalej z Javą i bazą \u003ca href=\"http://mysql.com\"\u003eMySQL\u003c/a\u003e?\u003c/p\u003e\n\u003cp\u003eNie będziemy jednak roztrząsać strategii takiego giganta jak Oracle, ponieważ jest już świeższy news. :) Dwa dni temu, dokładnie 4 maja 2009 \u003ca href=\"http://springsource.com/\"\u003eSpringSource\u003c/a\u003e przejęło \u003ca href=\"http://hyperic.com\"\u003eHyperic\u003c/a\u003e. O ile pierwsza nazwa jest zapewne znana większości z Was o tyle druga może być niejasna.\u003c/p\u003e","title":"SpringSource kupuje Hyperic"}]