Zobrazují se příspěvky se štítkemjava. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemjava. Zobrazit všechny příspěvky

pondělí 25. září 2017

Sémantický identifikátor entity

Na projektech korporátních i startapových jsem se setkal vždy s tím, že si servisní třídy mezi sebou vyměnují identifikátory entit.

Často je to např. Long, pokud je datovým podkladem SQL databáze ale setkávám se i se Stringem, když je entita ze vzdáleného systému volaného přes MQ, WebServices, Rest apod.

Problém pak nastává v tom, že se tyto identifikátory často pletou.

Například

public void updateTransaction(Long transactionId, 
                              Long userId, 
                              Long operatorId, 
                              Long clientId) {
 // ... do some nasty business logic
}

Není jasné, jestli userId je identifikátor entity User - nejspíš ano. A co operatorId? Je to taky z entity User? Obzvláště, když žádná entita Operator v doménovém modelu není. 


Co kdyby rozhraní vypadalo takto
public void updateTransaction(TransactionId transactionId, 
                              UserId userId, 
                              UserId operatorId, 
                              ClientId clientId) {
 // ... do some nasty business logic
}

Takto už je sématický význam parametrů jasnější. Co ale ve skutečnosti obsahuje třída UserId?
public final class UserId {
  private final Long value;
 
  private UserId(Long value) {
    this.value = value;
  }
 
  public Long getValue() {
    return value;
  }
 
  public static UserId of(Long value) {
    if (value==null) throw new IllegalArgumentException("Parameter 'value' can't be null.");  
    return new UserId(value); 
  }
 
  public static UserId of(String value) {
    if (value==null) throw new IllegalArgumentException("Parameter 'value' can't be null.");  
    return new UserId(Long.valueOf(value)); 
  }
}


Instance je immutable a je tedy thread-safe. Zároveň hlídá, že hodnota value je ne-null-ová. Může obsahovat tolik factory metod kolik je potřeba - v tomto případě umí instanciovat z Long a ze String. 

Co když používám Hibernate? Jak to mám namapovat? Můžeme nentitu nechat tak jak je - anotovanou nad attributy - pak Hibernate mapuje hodnoty přímo na atributy bez použití set a get metod.
  
@Entity
@Table(name = "COOL_USER")
public class User {
  @Id
  @GeneratedValue
  @Column(name = "USER_ID")
  private Long id;

  @Column(name = "FIRST_NAME")
  private String firstName;
   
  @Column(name = "LAST_NAME")
  private String lastName;

  public UserId getId() {
    return UserId.of(id);
  }

  public void setId(UserId id) {
    this.id = id.getId();
   }
    
    // other set get methods for firstName and lastName

}

Čitelnost servisního kódy je mnohem lepší a navíd kompilátor za vás dělá kontrolu, jestli jste parametry nepopletli. 

Myslím si, že podobný přístup by se dal použít i na jiné jednoduché datové typy - např. AccountNumber, BirthNumber, DateOfBirth místo String, String, Date. 

čtvrtek 20. dubna 2017

How to join strings with separator

import com.google.common.base.Joiner;
 
public static void main(final String[] args) {
  final String output = Joiner.on(", ").join("white", "blue", "red", "black");
  System.out.println("output = " + output);        
}
output = white, blue, red, black

pondělí 21. listopadu 2016

Peníze v Javě


Tentokrát bych chtěl rozebrat možnosti a moje zkušenosti, jak v kódu nakládat s penězi.

Datový typ - BigDecimal


Pro ukládání částky je rozhodně nutné používat datový typ BigDecimal  Jedině ten zaručuje, že nebude docházet k nečekanému zaokrouhlování za desetinou čárkou. BigDecimal snese v podstatě libovolnou přesnost a velikost čísla. Rozhodně nepoužívejte datové typy typu Float nebo Double.

Setkal jsem se i s aplikací, kde částky byly uchovávány jako celé číslo. Pro zobrazení se pak musela desetinná čárka uměle posouvat, tak aby dávala obsahově smysl. Fungovalo to dobře, ale myslím, že už je to přežité. Použil bych tento přístup jen v programovacím jazyku, který nemá BigDecimal alternativu.

Třída BigDecimal je immutable, takže se s instancemi ve vícevláknovém běhu pracuje bezpečně. Poskytuje všechny základní operace jako je sčítání, násobení a zaokrouhlování.

Identifikace měny


Peníze jsou ale ve skutečnosti dvojicí částky a měny.  Třídu, která by ale skládala dohromady částku a měnu přímo v JDK nemáme. Pokud máte částku a víte že jde o nějaké peníze, ale nevíte v jaké měně, tak je to docela problém.

public class Product {
    private final Long productId;
    private final String name;
    private final BigDecimal price; // What currency is it ?

    public Product(final Long productId, 
                   final String name, 
                   final BigDecimal price) {

        this.productId = productId;
        this.name = name;
        this.price = price;
    }
    // geters …
}

Třídu pro měnu máme v Javě už od verze 1.4 -  Currency. Rozšířit entitu o další atribut by neměl být problém.

public class Product {
    private final Long productId;
    private final String name;
    private final BigDecimal price;
    private final Currency currency;

    public Product(final Long productId, 
                   final String name, 
                   final BigDecimal price, 
                   final Currency currency) {

        this.productId = productId;
        this.name = name;
        this.price = price;
        this.currency = currency;
    }

    // geters …
}

Pokud v jedné entitě máte více cen - např. prodejní, nákupní, apod. Duplikují se vám dvojice částka a měna a poměrně snadno při použití může dojít k tomu, že částky a měny poplete. Musíte také ohlídat, aby byla vždy zadaná celá dvojice. Pokud dovolíte zadat částku bez měny, opět je to problém.

Joda Money

Problém neexistence třídy pro peníze vyřešil Stephen Colebourne, mimochodem autor populární knihovny JodaTime. Naimplementoval knihovnou pod názvem Joda-Money. Ta obsahuje třídu jak pro měnu - CurrencyUnit tak pro magickou dvojici částka, měna - a to hned ve dvou různých třídách Money a BigMoney. 

Money je třída, která agreguje  dvojici částka (jako BigDecimal) a měna (jako CurrencyUnit). Navíc hlídá počet desetinných míst pro danou měnu. Třída BigMoney poskytuje vše co Money, ale nehlídá počet míst za desetinou čárkou pro danou měnu. To se hodí, pokud vám částky přicházejí ze zdroje, který nemáte úplně pod kontrolou. Konverze mezi oběma typy je samozřejmě přímočará.  Obě třídy jsou immutable, takže opět bezpečné pro práci ve vícevláknovém prostředí. 

Upravený příklad vypadá takto.

public class Product {
    private final Long productId;
    private final String name;
    private final Money price;
    
    public Product(final Long productId, 
                   final String name, 
                   final Money price) {

        this.productId = productId;
        this.name = name;
        this.price = price;
    }

    // geters ... 
}

Závěr

Pokud pracujete v rámci programu s penězi, doporučuji určitě zahrnout do projektu o jednu závislost navíc a důsledně používat datový typ Money resp. BigMoney, místo dvou nezávislých atributů pro částku a pro měnu. Předcházíte tak riziku, že atributy prohodíte. Navíc je kód mírně přehlednější. Líbí se mi i že místo obecného typu pro číslo použit naprosto konkrétní pro peníze.


čtvrtek 18. srpna 2016

Mockování emailové komunikace v integračních testech

Na projektu JdemeNaTo jsme narazili na problém, jak v selenium integračních testech pracovat s emaily.

Testovaná aplikace posílá emaily přes SMTP protokol. Test je pak musí přečíst a zpracovat. Samozřejmě, že email jako takový se nesmí dostat ven z integračního prostředí.

Poměrně dlouhou dobu jsme používali jednoduché řešení Dumbster. To spočívalo v tom, že si test vytvořil při svém spuštění mock SMTP server na dohodnutém portu, a test si pak přímo přečetl příchozí mail. Po skončení testu se port zase uzavřel.

Toto řešení jsme museli ale opustit v době, kdy máme celé integrační prostředí postavené na dockeru. Testy pouštíme stále pomocí mavenu na TeamCity proti testovanému serveru hostovaném v docker kontejneru. Každý docker kontejner má svoji ip adresu a namá ponětí o tom, kdo ho volá.

Hledali jsme vhodnou náhradu za Dumbster a našli jsme překvapivě robustní implementaci v javě GreenMail, který je určený právě pro testovací účely. Sympatická je i velká variabilita nasazení - poskytují docker image, tak i standalone aplikaci či jako war do Tomcatu. Na straně posílání mailů jsme nemuseli udělat žádnou úpravu. Na straně čtení jsme si napsali jednoduchou rutinu založenou na POP3 protokolu.

Pokud hledáte řešení, jak mockovat email server v interačních testech, mohu GreenMail určitě doporučit.

sobota 17. ledna 2015

Code coverage of Selenium tests in TeamCity

There are couples of tools, which measure code coverage in java - cobertura, emma, jacoco.
They work pretty well for regular unit tests.

But how to measure code coverage of integration tests?

Here is my solution

All integration tests are written in Java - jUnit and Selenium WebDriver API - run by standard maven-failsafe-plugin. Application is deployed on Tomcat by TeamCity. Integration tests are run by TeamCity also.

If you run Tomcat with JaCoCo agent, you can measure code coverage on the Tomcat side.

This is part of Tomcat setenv.sh file

CATALINA_OPTS="-Xms512m -Xmx8g -XX:MaxPermSize=1024m -server -javaagent:/opt/tomcat1/org.jacoco.agent-0.7.2.201409121644-runtime.jar=output=tcpserver,address=localhost,port=6300"

After run all integration tests may TeamCity ask for results by jacoco-maven-plugin. It connects to Tomcat by TCP and saves result localy to jaacoco.exec file.

mvn jacoco:dump

TeamCity supports import javacoco result file by service massages. I added a regular command line build step. Service message should be printed into a standard output stream of the build; hence I used linux echo command. Unfortunately, single quote must by surround by double quote.

echo \##teamcity[jacocoReport dataPath="'"target/jacoco.exec"'" includes="'"com.jpower8.*"'" excludes="'"com.jpower8.*.*Test"'"]

Additional tab with coverage results appears in build detail.

středa 12. listopadu 2014

SQL Performance Explained

Na konci října jsem vyrazil na Geecon, který se poprvé konal v Praze. Na jedné z přednášek o SQL prezentátor Lukas Eder doporučoval knížku SQL Performance Explained.

Protože se po večerech a víkendech snažím o zrychlování našeho systému JdemeNaTo, tak jsem zainvestoval €10 a začetl se.

Knížka detailně popisuje, jak funguje index a jaké jsou běžné chyby při používání. Příklady autor ukazuje hlavně na Oracle, ale alternativy i na jiných - např. moje oblíbená PostgreSQL.

Moc se mi líbí stručný a výstižný jazyk. Každá věta nese informaci. Nikde žádná zbytečná výplň.

Nové poznatky jsem ihned začal úspěšně aplikovat na naší databázi, která už není úplně malá (řádově miliony řádků).

Rozhodně doporučuji k prostudování a dokonce zvažuji, připlatit si za vytištěnou verzi.

středa 2. dubna 2014

Řízení transakcí přes různé DAO implementace

Na startu projektu jdemenato.cz jsme DAO vrstvu implementovali přes JPA/Hibernate - standardně dle návodů.

V produkčním režimu, kde nám neustále roste počet uživatelů, jsme s tímto naivním řešením vydrželi jen několik měsíců. Kritické dotazy, které nejvíce vytěžovaly databázi,  jsem přepsali přes Criteria API na "lepší" SQL dotazy.

Po dalších měsících produkčního života nás zákaznické požadavky přinutili některé SQL dotazy psát ručně. Nejprimitivnější jsme zrealizovali přes Hibernate native SQL ale u složitějších jsme šáhli na JdbcTemplate a později k MyBatis.

To ovšem nastolilo problém s řízením databázových transakcí, jejichž součástí je více DAO technologií.

Ukázalo se, že na podobné případy chlapci ve springu pamatovali a stačilo vyměnit HibernateTransacionManager za DataSourceTransactionManager.

Tímto způsobem je DataSource "nejmenším společním jmenovatelem" spojující DAOs implementované přes Hibernate, MyBatis i JdbcTemplate.

Aby si AnnotationSessionFactoryBean nevytvořila svůj vlastní transakční manager, je nutné nastavit ji property useTransactionAwareDataSource=true.

        
<bean name="sessionFactory" 
  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>       
  <property name="useTransactionAwareDataSource" value="true"/>
</bean>
<bean id="sqlSessionFactory" 
         class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="configLocation" value="classpath:/META-INF/mybatis/myBatis-configuration.xml"/>
</bean>

středa 25. prosince 2013

Logování

Na projektech, kterých se účastním, se ještě dnes setkávám kódem, který považuje logování pomocí System.out za výborný nápad. Proto bych v tomto článku chtěl rozebrat, co považuji konci roku 2013 za nejlepší logovací řešení.


Přehled

V javě máme několik možností, jak logovat:
  1. System.out respektive System.err,
  2. java.util.logging (JUL),
  3. Jakarta (Apache) commons logging (JCL),
  4. log4j,
  5. slf4j a
  6. logback.

System.out resp. System.err

Tuto variantu používám jen při zkoušení izolovaných věcí a záměrně odřezávám nepotřebné závislosti. Funguje na všech verzí javy.

Hlavní důvody, proč nepoužívat System.out
  • Nelze konfiguračně vypnout na různých prostředích což má za následek výkonostní a bezpečnostní problémy a
  • nelze konfiguračně nastavit úroveň zpráv.

Java Util Logging (JUL)

Tato možnost již máme v JRE myslím od verze 1.5. Kupodivu jsem ji  na komerčních projektech ani v open-source projektech nepotkal. Podle mě se neujala, protože přišla tak trochu s křížkem po funuse. 


log4j

Tuto možnost jsem používal na SE i EE projektech před pěti a více lety. Nenarážel jsem na limity tohoto řešení a byl jsem s ním byl spokojen. Možnosti konfigurovatelnosti ale daleko zaostávají za jeho nástupcem - logback.  


Jakarta Commons Logging (JCL)

Toto řešení mělo za cíl unifikovat rozhraní mezi různými logovacími frameworky. Samo o sobě logování neřeší, jen posílá zprávy do konkrétních implentací - log4i, JUL.  Rozhraní je skutečně jednoduché a můj oblíbený spring framework je tímto api prolezlý skrz naskrz. Toto řešení bohužel sebou nese některé problémy, kvůli kterým bych toto řešení nedoporučoval. 


slf4j

Tato knihovna řeší stejný problém jako JCL - tedy unifikace rozhraní nad různými logovacími API. Nové komerční projekty i řada open-source projektů dnes používá právě toto api. Dnes ho používám na několika komerčních i sranda projektech k plné spokojenosti. 


logback

Autorem je tvůrce log4j i slf4j - Ceki Gülcü.
Důvody, proč přejí z log4j na logback sám sepsal v článku Logback: Reasons to Switch 

Mě osobně nejvíce oslovily dvě vlastnosti:
  1. podmíněná konfigurace, kterou používám pro nastavení úrovně logování v závislosti na prostředí. 
  2. SiftingAppender, který umožňuje logovat dle dynamického parametru, např zalogovaného uživatele.

Závěr

  • Nepoužívejte System.out resp. System.err
  • Používejte slf4j spolu s logback.


pondělí 12. března 2012

Upgrade maven libraries

Na klasickém maven projektu používáme stabilní verze pluginů – hlavně kvůli stabilitě buildu. Kvůli drobné chybce v pluginu wsimport jsme používali workaround, který upravuje vygenerované zdrojáky. Projížděním konkurenčních blogů jsem zjistil, že tato chyba je od nějaké verze už opravená. To jak jsem to ale zjistil, není vůbec systémové. Jak tedy zjistit, jaké nové verze pluginů nebo knihoven jsou k dispozici, aniž bych musel trávit hodiny na internetu?

Jak už to tak na světě bývá, nejsem první, kdo něco podobného potřebuje. K tomuto účelu dobře poslouží versions plugin. Používal jsem ho dříve jen na zvedání verzí, dnes mi je zvedá teamcity spolu s release pluginem.

Versions plugin toho ale umí mnohem víc.

Např.
mvn versions:display-dependency-updates
vám řekne, jak jste na tom se závislostmi, jestli nevyšel nový spring, hibernate, joda-time apod.

mvn versions:display-plugin-updates
vám zase prozradí, jak jste na tom s aktuálností pluginů.

Pak už záleží jen na vás, jestli upgrade provedete nebo ne.

Upgradu zdar.

úterý 18. října 2011

Validace vstupních parametrů metod.

Všechny vstupní parametry metod je vhodné validovat na jejich korektnost dříve než se s nimi začne pracovat.
V 90% případů mi stačí zkontrolovat, že vstupní parametr není null.
Joshua Bloch radí vyhodit NullPointerException, ale já, a troufám si tvrdit že i velká část java komunity, preferuje IllegalArgumentException.
Kód by mohl vypadat třeba takto
    public void foo(final String request) {
        if (request == null) {
            throw new IllegalArgumentException("Parameter 'request' can't be null.");
        }
    }
Protože nejsem na světě sám, co potřebuje validovat vstupní parametry, existuje spousta knihoven, které lze pro tyto účely využít (psát vlastní validační knihovnu považuji jen za zvyšování chaosu ve vesmíru).
První možností je třída org.apache.commons.lang.Validate z knihovny Apache Commons Lang.
    public void foo(final String request) {
        Validate.notNull(request, "Parameter 'request' can't be null.");     
    }
Místo původních třech řádků jen jeden. Na skoro všech projektech ale používám i Spring, tak proč nepoužít třídu org.springframework.util.Assert, která je hodně podobná org.apache.commons.lang.Validate?
    public void foo(final String request) {
        Assert.notNull(request, "Parameter 'request' can't be null.");
    }
Samotní autoři nedoporučují použít tuto třídu! Citace z javadocu:
Mainly for internal use within the framework; consider Jakarta's Commons Lang >= 2.0 for a more comprehensive suite of assertion utilities.
Další možnou variantou je knihovna Guava.
    public void foo(final String request) {
        Preconditions.checkNotNull(request, "Parameter 'request' can't be null.");
    }
Na té se mi ale nelíbí, že vyhazuje NullPointerException a varianta checkArgument, která vyhazuje IllegalArgumentException má vytaženou podmínku ven z metody, čímž se kontrola lehce komplikuje.
    public void foo(final String request) {
        Preconditions.checkArgument(request != null, "Parameter 'request' can't be null.");
    }
Já osobně zůstanu u třídy Validate. Jak validujete parametry metod vy?

sobota 12. prosince 2009

Maven support in Intellij IDEA 9.0 (Maia)

Last week was released latest stable version of IDEA 9. I was curious about new maven integration. In the version eight, whenewer you changed the pom file, all project had to be reloaded, which took couple of minutes in my project.
In version nine I have enabled auto refresh feature, and whenever I change the pom file, refresh is done automatically. Reload the project takes couple of seconds now.
Moreover, they added dependency graph feature - say good by dependency:tree command.
Thanks jetbrains for great improvement.

pondělí 8. prosince 2008

How to calculate age?

I offten have on my projects a lot of conditions, which depends on the age of the client, user, his wife or dog ;-).

Standard Java API is not very friendly for this use case. If you can't use JodaTime as me, I hope you appreciate this little calculator.



public class AgeCalculator {

public static int getAge(final Date dayOfBirth) {
return getAge(dayOfBirth, new Date());
}

public static int getAge(final Date dayOfBirth, final Date referenceDay) {
if (dayOfBirth == null) {
throw new IllegalArgumentException("Parameter 'dayOfBirth' can't be null.");
}
if (referenceDay == null) {
throw new IllegalArgumentException("Parameter 'referenceDay' can't be null.");
}

final Calendar calRef = Calendar.getInstance();
calRef.setTime(referenceDay);

final Calendar cal = Calendar.getInstance();
cal.setTime(dayOfBirth);

final int yearRef = calRef.get(Calendar.YEAR);

final int year = cal.get(Calendar.YEAR);

int result = yearRef - year;

cal.set(Calendar.YEAR, yearRef);
if (calRef.before(cal)) {
result--;
}

return result;
}

}

pátek 5. prosince 2008

Už nikdy více NPE

Na posledním projektu jsem ze zabýval archeologickou činností - upravovat aplikaci, která vznikla asi před dvěma lety a od té doby se příliš neměnila. Šlo o poměrně jednoduchou webovou aplikaci, která ukládá data z pár formulářů do databáze. Prostě brnkačka.

Horší to bylo s implementací. Kód byl úplně zamořen následující konstrukcí

if (someString!=null && someString.trim().length()>0) {
// do something
}

nebo ještě v komplikovaněji

if (firstName!=null && firstName.trim().length()>0 && lastName!=null && lastName.trim().length()>0) {
// do something different
}

Kdyby to byl výskyt jen tu a tam, tak nad ním mávnu rukou, ale podobné podmínky tvořili asi 80% celého kódu.

Většinou si programátoři začnou psát svoji vlastní MyUtil třídu, kde soustředí různé malé metody. Co programátor, to další MyUtil třída.

Neznalost neomlouvá, takže - pro tyto účely je už dávno vytvořená, zdokumentovaná a asi milionkrát otestovaná třída StringUtils, která je součástí apache commons lang balíčku (doporučuji prostudovat vše, co v této knihovničce je - pozor je vysoce návyková).

Výsledek vypadá následovně - čitelnost o poznání lepší.

if (StringUtils.isNotBlank(firstName) && StringUtils.isNotBlank(lastName)) {
// do someting
}

Pokud tedy máte pocit, že si chcete napsat svoji vlastní MyUtil třídu vězte, že objevujete znova kolo.

pátek 17. října 2008

Testing blocking operation

Sometimes I have a luck and I can write multi-threaded application. I like testing all my classes with JUnit but it has no support for concurrency.

During studding an excellent book Java Concurrency in Practice which explains all new features added in JSE5 regarding to concurrency, I was looking forward to chapter about testing with JUnit.

The author recommends - if you need to test, that your operation blocks the calling thread, it is similar pattern as testing that your operation throws Exception.


void testTakeBlocksWhenEmpty() {
final BoundedBuffer bb = new BoundedBuffer(10);
Thread taker = new Thread() {
public void run() {
try {
int unused = bb.take();
fail(); // if we get here, it's an error
} catch (InterruptedException success) { }
}};
try {
taker.start();
Thread.sleep(LOCKUP_DETECT_TIMEOUT);
taker.interrupt();
taker.join(LOCKUP_DETECT_TIMEOUT);
assertFalse(taker.isAlive());
} catch (Exception unexpected) {
fail();
}
}


While I was watching funny video about java puzzles I was surprised, that the example from the book does not work !!!

JUnit framework all exceptions and errors which are thrown from user thread does not interprets as failure! Fortunately, it logs stack trace to the console at least.

Try this simple example - what colour does your test - green or red ?

public void testFail() throws InterruptedException {
final Thread t = new Thread(new Runnable() {
public void run() {
assertEquals(2, 5);
}
});
t.start();
t.join();
}


My is green and I expect, it should be red, because in my world, two does not equal to five.

How to fix it? You need to catch the exception or error in your user thread and forward it to JUnit normal thread. For example in this way.


private volatile Exception eException = null;
private volatile Error eError = null;

public void testEquals() throws InterruptedException {
final Thread t = new Thread(new Runnable() {
public void run() {
try {
assertEquals(3, 5);
} catch (Exception e) {
eException = e;
} catch (Error e) {
eError = e;
}
}
});
t.start();
t.join();
}

protected void tearDown() throws Exception {
if (eException != null) throw eException;
if (eError !=null) throw eError;
}

protected void setUp() throws Exception {
eException = null;
eError = null;
}

čtvrtek 18. září 2008

return ve finally ?

Na certifikačním serevru javablackbelt jsem narazil na otázku, jak se chová fuknce, pokud má více návratových míst. Docela mě zarazilo, že návratovou hodnotu lze přepsat ve finally bloku.


public class FinallyExample {

public static void main( String[] args ) {
System.out.println( test(true) );
System.out.println( test(false) );
}

public static String test(boolean e) {
try {
if (e) throw new RuntimeException();
return "A";
} catch ( Exception ex ) {
return "B";
} finally {
return "C";
}
}
}

Bez ohledu na to, jestli v metodě dojde či ne k vyjímce, hodnota ve finally bloku nakonec vyhrává - program tedy vypíše dvakrát C C.

Inu, ne nadarmo je v idei automaticky zapnutá inspekce, která ihned varuje.

This inspection reports any instances of return statements inside of finally blocks. While occasionally intended, such return statements may mask exceptions thrown, and tremendously complicate debugging.

středa 20. srpna 2008

Jak jsem se nechal certifikovat – SCBCD

Ve firmě, kde právě pracuji jsem se nechal uvrtat do toho, že povedu školení o EJB3. Materiály jsem převzal po kolegovi, takže jsem s tím neměl moc práce. Horší bylo, že EJB3 jsem znal jen z rychlíku. Přesně podle hesla: “Ten kdo to neumí, ten to učí“. Takže jsem musel začít od začátku.

Pomohla mi knížka EJB3 in Action (mimochodem, knížky od
Manningu jsou vždy výborné). Je teda trochu obsáhlejší, asi 700 stran, takže na studium v tramvaji je to přece jen macek. Líbilo se mi, že se nesnaží obhajovat předchozí verze EJB a nevyhýbá se ani springu . Takže můžu jen doporučit.

Školení proběhlo v pohodě, a aby čas strávený studiem nepřišel vniveč, rozhodl jsem se, že se nechám ocertifikovat.

Jako studijní materiál jsem zvolil samotnou specifikaci. Původně jsem si myslel,že se nebude dát číst, ale opak byl pravdou. Dokonce jsem díky ní odhalil některé chyby v knize (mimochodem, autor odpovídá promptně).

Na java ranči doporučovali ještě poznámky Mikalai Zaikina. Ty se ukázaly jako velice užitečné, neboť popisují i to, co EJB neumí.

Abych nevyšel ze cviku, tak jsem si za těžce zdaněné peníze koupený tester od whizlabu. Ten mě ale velice zklamal. Nevím jak tester vyvíjejí, ale mě padal jak hrušky, a když spadl po 61 zodpovězených otázkách, tak jsem ho v rámci duševní hygieny smazal. U některých otázek byli dokonce špatné odpovědi! Takže rozhodně nebrat.

Naštěstí jsem od firmy dostal licenci na uCerify – super věc, rozhodně doporučuji.

Nakonec jsem zkoušku složil na 88%.

pátek 15. srpna 2008

Jak jsem se nechal ocertifikovat - SCJP

Po několika letech kdy jsem dostudoval výšku a ještě víc letech co se živím (bavím) programováním v javě jsem se nechal ukecat na certifikaci (SCJP) - prý tím stoupne moje cena na trhu práce.

Nejdříve jsem si nabubřele myslel, že se nebudu muset nic učit - vždyť všechno už znám ne ;-) ? Kolegové, kteří už ono martýrium absolvovali mě varovali, že si mám zkusit alespoň nějaké cvičné testy, ať vím co čeho jdu - ještě že je mám (ty kolegy).

Testovací příklady jsou zejména o tom, jestli daný kód jde nebo nejde zkompilovat a proč. Přiznám se, že tuto práci za mě dělá počítač sám, takže jsem se moc nechytal. Druhý zádrhel byla znalost API - třeba v které package je DateFormat a tak. Přiznám se, že slovo klíčové import jsem nenapsal od doby co je za mě IDEA píše sama (minimálně 5 let).

Na druhou stanu abych jen nehaněl, dozvěděl jsem se i o některých záludnostech, o kterých jsem nevěděl, neb jsem se s nimi nesetkal - např. anonymní iniciátory.

Suma sumárum. Pokud se na certifikaci SCJP chystáte, určitě doporučuji nastudovat tuto knížku. Dále jsem měl k dispozici příklady testů od whizlabu. Poté test uděláte bez problémů (já jen na 90%).

Na co vše se dá certifikovat - link.

Poté, co jsem se nechal namočit do školení o EJB3 jako speaker, jsem se rozhodl, že si udělám i SCBCD, ale o tom až někdy příště.

čtvrtek 24. července 2008

commonj TimerManager

Trápil jsem se rozběháním commonj knihovny na BEA WebLogic 9.2. Potřeboval jsem rozběhat periodický timer a byl jsem nucen použít tuto feature (Quartz mi byl zakázán).
Postupoval jsem podle manuálu a světe div se, nefungovalo to.

Prý stačí vložit do web.xml následující konstrukci a je to

<resource-ref>
<res-ref-name>timer/MyTimer</res-ref-name>
<res-type>commonj.timer.TimerManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>

Problém ovšem nastane při deploy !?!
Žádná package commonj.timer totiž není, zato existuje commonj.timers.
Chyba je tedy v jednom písmenku - s.

středa 9. července 2008

Vychytávky v IntelliJ IDEA o kterých jsem nevěděl

Přihlásil jsem ke k odběru refcardz a poslední příspěvek byl o IntelliJ IDEA. Vzhledem k tomu, že Ideu používám již léta a vždy mě dokáže něčím překvapit jsem se pustil do čtení. Myslím si, že většinu funkcí znám, tak se zaměřím jen na ty, o kterých jsem nevěděl.

Copy/Paste
To že se přes schránku kopíruje pomocí Ctrl+C/V není nic objevného. Zajímavé je ale to, že pokud není označené nic, automaticky se kopíruje celý řádek.

Autoscroll from Source
V projektovém panelu lze zapnout funkci, že pokud změníte selekci ve stromečku, automaticky se v editoru otevře příslušný soubor. Opět nic světoborného a nečekaného. Zajímavé je to, že to může fungovat i naopak. Tedy, pokud se přepínáte mezi taby v editoru, automaticky se skroluje na příslušný prvek ve stromě. Dříve jsem pro tuto funkci používal zkratku Ctrl+F1.

Goto Class
Pro nalezení třídy dlouhá leta používám Ctrl+N. Nevědel jsem ale, že pomocí Shift+Up/Down můžete vybrat tříd více.

Goto Parent
Pokud jsem potřeboval skočit na metodu předka, kterou overriduji, vždy jsem klikal na ikonu vedle metody. Odedněška už na myš nešáhnu. Stačí Ctrl+U.

Autoscroll to Source in the Find pane
Při vyhledávání pomocí Ctrl+F se ukáží výsledky v okně ve kterém se můžete pohybovat pomocí šipek nahoru a dolu. Lze zapnout i autoscroll, kdy při změně selekce ve stromě se automaticky odskroluje v editoru. Já toto většinou mám vypnuté, neb mě to vyrušuje. Zajímavé je ale, pokud máte autoscroll vypnutý, tak ho můžete "temporary" zapnout pomocí Ctrl+Alt+Up/Down.

Preview in the Find pane
Po vyhledávání pomocí Ctrl+F se mi většinou změní otevřené soubory v editoru a musím je pracně hledat a otevírat znovu. Ve Find pane lze ale zapnout preview okno, ve kterém se při změně selekce ve stromu automaticky skroluje do preview okna.

Vyhledávání funkcí v menu
Menu je poměrně rozáhlé a občas je probém najít tu správnou položku. Pomocí Ctrl+Shift+A lze vyhledávat v akcích menu. Toto považuji za velice užitečnou funkčnost. Škoda, že něco takového není i ve Wordu - tam tápu téměř pořád.

Expand Word
Pomocí Alt+Slash umí editor napovídat jména proměných. Moc jsem nepochopil, jak to funguje, ale vyzkouším.

Surround with Live Template (Ctrl+Alt+J)
To, že lze obalovat kusy kódu pomocí Ctrl+Alt+T jsem věděl a používám. Že existují Life templates (Ctrl+J) jsem věděl taky ale že může být life template+surround je pro mě novinka.