Some of posts from this blog has been moved to dywicki.pl. You will be automatically redirected to new blog if you would submit comment.
New posts are published on dywicki.pl, this blog contains old content related to Code-House company.


Niektóre posty z tego bloga zostały przeniesione do dywicki.pl. Zostaniesz automatycznie przekierowany jeśli bedzięsz chciał dodać komentarz.
Nowe posty sa publikowane na dywicki.pl, ten blog zawiera stare treści związane z firmą Code-House.

Przeprowadzka

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.

Dla 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. :)

Najnowsze wpisy

post Apache Karaf commands rediscovered

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.

List 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.

Below example output of these commands:


        __ __                  ____
       / //_/____ __________ _/ __/
      / ,<  / __ `/ ___/ __ `/ /_
     / /| |/ /_/ / /  / /_/ / __/
    /_/ |_|\__,_/_/   \__,_/_/


  Apache Karaf (2.1.2)

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or 'osgi:shutdown' to shutdown Karaf.

karaf@root> 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> 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:

karaf@root> 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.

List services

After first impression with OSGi and bundles as modules most of us moving to using OSGi services. That’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.

karaf@root> 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.

karaf@root> 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’s important which packages you import and export. The two commands packages:imports and packages:exports will simply show what’s comes and goes from your bundle. I’ll not show how these commands work but I have little trick for you. When you’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’ll resolve bundle type packages:imports and check complete list of import you missed in your headers.

Features

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.

karaf@root> 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’s bundles.

karaf@root> 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:

karaf@root> 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’t use this command to often.

Last 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.

Complete

Remember that every Karaf command can be executed with –help switch which shows all arguments and switches. In this post you was introduced to following commands:

  • list 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

post Własny widget w UiBinderze

UiBinder jest rozszerzeniem, które pozwala nam szybko i bardzo przyjemnie stworzyć widok okienka w XML’u.  Dzięki niemu możemy oddzielić widok aplikacji webowej od logiki ją obsługującej w czystym GWT. Sposób używania UiBinder’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’em albo będziemy musieli zrezygnować całkowicie z tego narzędzia.

W tym wpisie właśnie chciałbym przedstawić sposób stworzenia własnego prostego widget’u. Będzie nim pole do wpisywania hasła, wraz z labelk’ą opisującą do czego to pole służy. Naszym celem jest stworzenie widget’u który wygląda mniej więcej tak:

1

Przejdźmy do kodu, stwórzmy klasę reprezentującą widget:

// Copyright (C) 2010 Code-House
// All rights reserved
package com.hqcargo.shippingstock.client.application.view.widget.form;

import 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;

/**
 * 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'u, na którym są
 * rysowane elementy naszego Widget'u.
 *
 * @author Michał Rowicki
 */
public class PasswordWidget extends FlowPanel {

    //Wszystkie pola
    /**
     * Etykieta pola.
     */
    LabelWidget label;

    /**
     * Etykieta błędu.
     */
    Label errorLabel;

    /**
     * Pole, które musi rozszerzać klasę Widget.
     * {@link com.google.gwt.user.client.ui.Widget}
     */
    PasswordTextBox pass;

    /**
     * Wartość id używana we wszelkich formularzach, by można było
     * cache'ować dane wpisane do ramki i później by były wczytywane
     * w przeglądarce.
     */
    String id;

    /**
     * Należy stworzyć konstruktor bezargumentowy tak by framework
     * UiBinder'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();

        label = new LabelWidget();
        //ustawienie atrybutu class, by móc podpiąć własne CSS'y
        label.setStyleName("item_label");

        errorLabel = new Label();
        errorLabel.setStyleName("error_label");

        add(label);
        add(pass);
        add(errorLabel);

        //ustawienie atrybutu class dla całego FlowPanelu
        setStylePrimaryName("item");
    }

    //by nasza aplikacja działała poprawnie musimy utworzyć gettersy i settersy dla pól klasy

    /**
     * Pobranie wartości pola label.
     *
     * @return Wartość label
     */
    public final LabelWidget getLabel() {
        return label;
    }

    /**
     * Ustawienie wartości pola label.
     *
     * @param Podaj label
     */
    public final void setLabel(LabelWidget label) {
        this.label = label;
    }

    /**
     * Pobranie wartości pola errorLabel.
     *
     * @return Wartość errorLabel
     */
    public final Label getErrorLabel() {
        return errorLabel;
    }

    /**
     * Ustawienie wartości pola errorLabel.
     *
     * @param Podaj errorLabel
     */
    public final void setErrorLabel(Label errorLabel) {
        this.errorLabel = errorLabel;
    }

    /**
     * Pobranie wartości pola pass.
     *
     * @return Wartość pass
     */
    public final PasswordTextBox getPass() {
        return pass;
    }

    /**
     * Ustawienie wartości pola pass.
     *
     * @param Podaj pass
     */
    public final void setPass(PasswordTextBox pass) {
        this.pass = pass;
    }

    /**
     * Pobranie wartości pola id.
     *
     * @return Wartość id
     */
    public final String getId() {
        return id;
    }

    //ustawia wartość pola id dla obiektu pass

    /**
     * Ustawienie Id pola.
     *
     * @param id Identyfikator pola.
     */
    public final void setFieldId(final String id) {
        this.id = id;

        pass.getElement().setId(id);
        label.setFor(id);
    }
}

 

Użycie naszego widget’u w pliku *.ui.xml jest bardzo proste należy jedynie dodać w polu UiBinder xmlns:dowolna_nazwa="urn:import:nazwa_paczki". A następnie w ciele HTMLPanela dodać pole dowolna_nazwa:PasswordWidget i uzupełnić odpowiednio pola, np:

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder
    xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:widget="urn:import:client.application.view.widget"
    xmlns:gwt="urn:import:com.google.gwt.user.client.ui">

    <gwt:HTMLPanel tag="div">

        <widget:PasswordWidget fieldId="password" fieldLabel="Hasło" ui:field="password" />

    </gwt:HTMLPanel>
</ui:UiBinder>

W ten oto sposób stworzyliśmy najprostszy własny widget który możemy użyć w UiBinderze.

Tutaj załączam cały działający projekt Eclipse’a z naszym własnym widgetem (należy przed uruchomieniem zainstalować SDK GWT).


post Brakujący element Javarsovii

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.

Wróć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.

Podsumowując, czego można się spodziewać w najbliższy wtorek:

  • Celem prezentacji jest przedstawienie OSGi.
  • Tradycyjne podejście do usług w OSGi.
  • Co dodaje Spring DM/Blueprint.
  • Jak to uruchomić na Karafie1

Serdecznie zapraszam wszystkich zainteresowanych jak i zawiedzionych tym, że OSGi nie będzie na Javarsovii. :-)


1 Trwają negocjacje, czy Apache Felix Karaf zostanie projektem wysokiego poziomu (TLP) fundacji Apache.


post Praktyki studenckie w Code-House

Jakiś czas temu Jacek Laskowski wspominał o praktykach studenckich w IBM.

Celem 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.

Pula tematów dla praktykantów obejmuje następujące projekty fundacji Apache:

  • Apache 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ą “iterację” 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ń.

Do zarządzania, koordynacji zadań oraz dokumentacji i weryfikacji kodu wykorzystujemy narzędzia Atlassian:

  • JIRA
  • 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 rekrutacja@code-house.org 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.

Older Posts

OSGi-fikacja oraz nowe bundle w repozytorium ServiceMix

Specyfikacja Enterprise OSGi została opublikowana

Enterprise OSGi

Wprowadzenie do Apache ServiceMix 4 cz. 1

Wygodne środowisko dla programisty z JRebel