26. září 2010

Bude Oracle pro Javu přínosem? - výsledky

I'm back :-). Mám za sebou na dovolené a práci bohaté léto, takže jsem neměl moc času na psaní. Také se ale musím přiznat, že na mě padla tak trochu "autorská krize", a že jsem rád, že jsem za těch pár měsíců mohl nabrat novou energii a nová témata. I když práce na podzim bude hodně, tak i přesto bych rád sem tam něco napsal ...


Před pár měsíci skončila poslední anketa na tomto blogu s těmito výsledky (celkem hlasovalo 59 lidí):

  1. Ne (37%)
  2. Ano (30%)
  3. Nevím (20%)
  4. Nic se nezmění (11%)

Já osobně jsem hlasovalo pro "Ne" a myslím, že události v posledních měsících tomu jednoznačně napovídají. Oracle byla, je a bude firma primárně zaměřená na peníze. To je asi většina firem, jinak by bylo asi něco špatně, ale u jiných firem to není tak okaté, není to tak na první pohled vidět. Co jiného si mám myslet o žalobách na Android? Co si mám myslet o posledním vývoji JDK a Javy samotné? (pozn. do teď si pamatuji, jak se Sun dušoval po vydání Javy 5, že nyní budou každé dva roky nová verze JDK ...)

Je pravda, že se na celou věc koukám z pohledu normálního programátora, kterého asi nejvíce zajímá samotná Java a co s ní bude do budoucna. Kdybych se na to koukal jako nějaký manažer nebo obchodník, tak bych to asi viděl zase jinak. A nebo prostě má Oracle špatný marketing a pověst ve srovnání s ostatními podobnými hráči.

Na druhou stranu se musím přiznat, že od samotné Javy už toho moc neočekávám. Dnes samotná Java nic není. Javovská platforma je dnes takový ekosystém všech možných knihoven, frameworků a dynamických jazyků, které mají to společné, že mohou běžet v JVM. Proto nemá cenu do jazyka Java přebírat všechny možné vychytávky z jiných jazyků, ale spíše se snažit o udržení přehlednosti a jednoduchosti jazyka. Když se podívám na seznam plánovaných vlastností, tak já osobně bych nejvíce uvítal nativní podporu modularizace přímo na úrovni JVM a integraci knihovny JODA pro lepší práci s datumem a časem. Některé zbylé věci mi přijdou jako "nice to have" (např. strings in switch, Automatic resource management, The fork/join framework), ale jiné bych prostě do Javy už nedával (např. closures, Diamond operator, Annotations in more places).

Jsem toho názoru, že Java jako jazyk má nejlepší léta za sebou a nemá nyní cenu se snažit dohánět ostatní nové moderní jazyky. Já programuji v Javě skoro deset let a vždy jsem nejvíce oceňoval jednoduchost, přehlednost a stabilitu jazyka, širokou komunitu, velké množství informací a možnost volby a výběru a nikdy jsem si moc nestěžoval, že by se mi něco psalo nějak špatně, že by se to mohlo psát lépe.

Co ale vidím pozitivně je to, že Java tu bude ještě hodně dlouho, protože Oracle je na Javě výsostně závislý, a proto se nebojím toho, že by během pár let padla v zapomnění. Takže ještě pár let budu programovat a pak už snad budu rentiér :-).

24. května 2010

Kdo nemá twitter, není správný programátor

"Kdo nemá twitter, není správný programátor" - takový pocit jsem získal v poslední době, když pozoruji své kolegy v práci nebo lidi v Java komunitě. Pokud nemáš twitter, tak jsi out :). Je to samozřejmě přehnané, ale když se podívám na českou Java komunitu, tak je opravdu hodně lidí, kteří Twitter používají.

Nepřidávám se snad ani kvůli tomu, že chci být in, ale hlavně z toho důvodu, že to chci zkusit. Chci zkusit zjistit, zda je tato forma komunikace pro mě přínosem, chci tímto způsobem získat nové zajímavé informace, chci tímto způsobem i já sám s trochou přispět a upozornit na zajímavé články nebo myšlenky. Určitě ale nechci psát o mém soukromí, o tom, co právě dělám a o tom jak se mám. Rád bych, aby se vše týkalo vývoje a Javy.

Nevím, zda je to jen můj pohled, ale přijde mi, že v poslední době (cca půl roku zpátky) se nepíší blogy tak jako dříve. Těžko říci, čím to je - již není o čem psát? Jsou už blogeři unavení nebo mají již něco jiného na práci? Nahrazuje twitter klasické blogování? Myslím si, že asi od všeho něco. Já bych každopádně ještě nějaký čas rád psal, protože pořád cítím, že mi to více dává než kolik tomu dávám já.

Pokud mě tedy chcete následovat, pak mám účet pjuza.

21. května 2010

Auto-wiring a možná řešení při více beanech stejného typu

Pokud používáme auto-wiring (dále předpokládám auto-wiring podle typu), tak se nám lehce může stát, že máme více beanů (instancí) stejného typu. V tomto případě Spring vyhodí výjimku, protože nemá žádný návod, jak tuto situaci vyřešit.

Zejména v testech se mi toto stává velice často, protože mám bean produkčního kódu, ale pro testy chci použít implementaci určenou pouze pro testy.

Příklad:

context.xml
<bean id="b1" class="FooImpl" />

context-test.xml
<bean id="b2" class="FooTestImpl" />

@ContextConfiguration(locations = {"classpath:/context.xml", "classpath:/context-test.xml"})
public void FooTest() {
@Autowired
private Foo foo;
}


Mám několik možností, jak tento problém řešit:

  • nadefinuji druhý (testovací) bean se stejným ID jako produkční bean a jelikož se testovací bean inicializuje jako druhý (z tohoto důvodu je velice důležité pořadí inicializace souborů Spring konfigurace), tak se přepíše (override) a ve Spring kontejneru bude ve výsledku pouze jeden bean - v tomto příkladu FooTest. Stejně to bude fungovat i když u obou beanů vynechám atribut ID. Pak se ID generují automaticky (viz implementace BeanNameGenerator) a budou tedy také stejná.

  • použiji anotaci @Qualifier a poradím Springu, jakou beanu má přesně vybrat. Ovšem ještě musím upravit konfiguraci beanu b2.

    <bean id="b2" class="FooTestImpl">
    <qualifier value="test">
    </bean>

    @Autowired
    @Qualifier("test")
    private Foo foo;

    Také to jde bez úpravy konfigurace a bez použití tagu <qualifier>. Pokud tento tag není definován, pak defaultní chování je takové, že se vygeneruje qualifier s hodnotou ID daného beanu. Mohu tedy pak napsat následující (ovšem pro tento přístup spíše doporučuji použití anotace @Resource, která je pro to určena):
    @Autowired
    @Qualifier("b2")
    private Foo foo;

  • použití anotace @Resource je pro tento případ vhodnější nez @Qualifier, zejména z pohledu sémantiky obou anotací.
    @Resource(name = "b2")
    private Foo foo;

  • použití primary atributu. Tento atribut dostupný pro každý bean říká, že se jedná o primární (první, doporučený) bean pro auto-wiring, pokud bude více adeptů stejného typu. Tuto vlastnost jsem objevil až nedávno, protože zmínka o ní je celkem zapadlá v dokumentaci.

  • za určitých podmínek by bylo možné ještě použít atribut autowire-candidate u produkčního beanu b1 a nastavit ho na false. Tím pak bude pro auto-wiring určen jen bean b2.

Tak jednoduchý problém a tolik možností řešení :). Já osobně nejčastěji používám řešení s primary a nebo s přepisováním definice beanu.

16. května 2010

Jaká bude budoucnost Javy? - výsledky

Dnes skončila další anketa a to s těmito výsledky (celkem hlasovalo 77 lidí):

  1. Pozice Javy se moc měnit nebude (50%)
  2. To nejlepší má již Java za sebou (25%)
  3. Javu čekají světlé zítřky (19%)
  4. .Net časem získá převahu (14%)
  5. Budoucnost patří dynamickým jazykům (12%)
  6. Za 10 let si na Javu nikdo ani nevzpomene (6%)

Jako hlavní komentář mi dnes poslouží článek Dagiho Mračna, sluníčko a nebo smrádek a teploučko nad Javou. Sám bych to lépe nenapsal a s jeho názorem souhlasím.

Celkem mě překvapuje, že si tolik lidí myslím, že Java na tom bude pořád stejně. Mě se toto celkem špatně posuzuje, protože se soustředím jen na Javu a nemám moc času sledovat i jiné platformy, ale jeden příklad bych měl. Ve firmě nyní připravujeme novou generaci klienta našich aplikací (nyní jsou klienti programovány v Delphi) a nebylo celkem co řešit - vítězem se stal Silverlight od Microsoftu. Samozřejmě snaha byla o to, aby i klient byl v Jave, když celý server je Javovský, ale Java prostě v této oblasti zcela zaspala a JavaFX ve mě pořád nebudí takovou důvěru, aby jsme se nyní na ní mohli spolehnout na dalších 5, 10 let.

Sice si také nemyslím, že by se pozice Javy v nejbližších letech měla měnit, ale určitě je potřeba inovovat. Na závěr bych použil jeden předvolební slogan "Nezajímá mě zítřek, ale budoucnost". (snad jsem to napsal dobře :-) ).

Generování class diagramů - Maven plugin

Na konci minulého roku jsem psal o programovém generování class diagramů.

Dnes bych na tento článek navázal implementací Maven pluginu. Ve firmě jsme kompletně přešli na Maven, takže jsem byl nucen vhodně přepsat původní ANT skript.

Implementace byla jednoduchá, napsal jsem totiž Maven plugin pomocí ANTu (pozor, nemyslím využití Maven Ant pluginu).

Dále přikládám zdrojové kódy, které asi nepotřebují další komentáře:

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cz.marbes.plugins</groupId>
<artifactId>daisy-maven-plugins</artifactId>
<version>3.12.0.11-SNAPSHOT</version>
</parent>
<groupId>cz.marbes.plugins</groupId>
<artifactId>generator-diagram-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>3.12.0.11-SNAPSHOT</version>
<name>generator-diagram-plugin Maven Mojo</name>
<description>Plugin na generovani class diagramu</description>


<build>
<plugins>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.3</version>

<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-tools-ant</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>

<configuration>
<goalPrefix>diagram</goalPrefix>
</configuration>
</plugin>
</plugins>
</build>


<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-script-ant</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.umlgraph</groupId>
<artifactId>doclet</artifactId>
<version>5.1</version>
</dependency>
<!-- Knihovna UmlGraph vyzaduje, aby byl vedle ni umisten tools.jar -->
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
<!--<systemPath>${user.home}/.m2/repository/org/umlgraph/doclet/5.1/tools.jar</systemPath>-->
</dependency>
</dependencies>

</project>


diagram.build.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project name="generator-diagram-plugin">
<target name="generate">
<!-- vytvoreni vystupniho adresare -->
<mkdir dir="${outputDir}"/>
<delete dir="${outputDir}"/>
<mkdir dir="${outputDir}"/>

<!-- generovani class diagramu -->
<java classname="cz.marbes.plugins.maven.generator.diagram.ClassDiagramGenerator">
<arg value="${package}"/>
<arg value="${outputDir}"/>
<arg value="${srcDir}"/>
<arg value="${dotFile}"/>
</java>
</target>
</project>


diagram.mojos.xml:

<?xml version="1.0" encoding="UTF-8"?>
<pluginMetadata>
<mojos>
<mojo>
<goal>generate</goal>

<!-- this element refers to the Ant target we'll invoke -->
<call>generate</call>

<requiresProject>true</requiresProject>

<description>
Plugin na generovani class diagramu.

Plugin vyzaduje (bohuzel) dve nutna zla:
- musi byt lokalne nainstalovay Graphiz (http://www.graphviz.org). Cesta k '
dot' souboru se zadava pres property 'dotFile'
- knihovna tools.jar musi byt vedle knihovny UmlGraph v Maven repository
</description>
<parameters>
<parameter>
<name>outputDir</name>
<property>outputDir</property>
<required>true</required>
<readonly>true</readonly>
<expression>${outputDir}</expression>
<defaultValue>${project.build.directory}/diagram_output</defaultValue>
<type>java.lang.String</type>
<description>Cesta k vystupnimu adresari, do ktereho se bude generovat diagram.</description>
</parameter>
<parameter>
<name>srcDir</name>
<property>srcDir</property>
<required>true</required>
<readonly>true</readonly>
<expression>${srcDir}</expression>
<defaultValue>${project.build.sourceDirectory}</defaultValue>
<type>java.lang.String</type>
<description>Absolutni cesta k adresari projektu se zdrojovymi soubory, kde je zadany package,
napr. '
/Volumes/Obelix/projects/daisy/apl/aa/trunk/aa-core/src/main/java'.
</description>
</parameter>
<parameter>
<name>package</name>
<property>package</property>
<required>true</required>
<expression>${package}</expression>
<type>java.lang.String</type>
<description>Package, pro ktery se ma generovat class diagram,
napr. '
cz.marbes.daisy.modules.aa.wscommon.komu.v1_1_2'.
</description>
</parameter>
<parameter>
<name>dotFile</name>
<property>dotFile</property>
<required>true</required>
<expression>${dotFile}</expression>
<type>java.lang.String</type>
<description>Cesta ke graphviz DOT souboru (napr. '
/usr/local/bin/dot')</description>
</parameter>
</parameters>
</mojo>
</mojos>
</pluginMetadata>


Nakonec ještě přikládám použití pluginu:

<profile>
<id>generate-diagram</id>
<!--
Profil vyzaduje dve nutna zla:
- musi byt lokalne nainstalovay Graphiz. Cesta k 'dot' souboru se zadava pres property 'dotFile'
- knihovna tools.jar musi byt vedle knihovny UmlGraph v Maven repozitory

Priklad:
mvn process-classes -Pgenerate-diagram -DdotFile=/usr/local/bin/dot -Dpackage=cz.marbes.daisy.modules.aa.modules.pvs.ws.v2_0_0
-->
<build>
<plugins>
<plugin>
<groupId>cz.marbes.plugins</groupId>
<artifactId>generator-diagram-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>process-classes</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${user.home}/.m2/repository/org/umlgraph/doclet/5.1/tools.jar</systemPath>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>


Stejně jako původní řešení, tak i Maven plugin má své omezení, ale pro interní použití se to dá překonat. Důležité je, že dokážeme generovat pěkné class diagramy k našemu kódu. Class diagramy dáváme zejména do dokumentace k našim webovým službám, protože to zvyšuje jejich čitelnost a použitelnost.