2006/10/31

Keep working

Ősz, levelek, netbeans (stabil), benne kísérletek. Ez van mostanában.

jBluez

A BlueZ a linux bluetooth stack-je, a JBluez egy JNI-s adapter hozzá. A SourceForge múzeumból egy 2002-es release tölthető le hozzá, ami megdöbbentő módon teljesen jól működik. Van hozzá 3 rövid példaprogram, megy egy rövid txt, hogy hogyan leheljünk bele életet, és egy mégrövidebb Troublehooting Guide, hogy hol fog elszálni. És tényleg elszállt ott, és tényleg úgy lehetett kijavítani, és utána tényleg ment. El voltam ájulva.

A szomorú az benne, hogy nem JSR-82 kompatibilist, de olyat még nem sikerült találnom Linux alá.

(Közbe frissíŧettem az ubuntu-mat, és ebben már libbluetooth2-van, és a bináris nem azzal ment. De egy szimbolikus linket megkockáztattam (új api a régi néven is), és megette.

OpenSSO

Gyűrés alatt. Vicces, mert mindenhol azt írják, hogy az OpenSSO based on Sun Java Access Manager, de én sose tudom, hogy hogyan van a reláció. Pl. az OpenSSO-ban csak maga a web-app van, meg most már az adapterek, de a plusz konzolos alkalmazásokat még nem találtam meg. A dokumentációja is érdekes: felrakták a Use Case leírásokat, meg az architektúra leírásokat, amit elég izgalmas olvasni, (milyen egy Sun-os ilyen), de a használatról nem sok. Csak admin és config guide-ok, semmi development útmutatás.

Van viszont elég sok cucc a docs.sun.com-on az Access Manager-hez, de az meg ugye nem pont ez. Amire hivatkozik sokszor hiányzik, és lehet keresni, hogy azok a utility-k itt hol vannak.

Tutorialt egyelőre nem találok, csak WebService titkolódzosat a NetBeans tutorialok között, de én egyelőre csak sima SSO-t szeretnék egy web appban. Illetve van egy , de még 8.1-es glassfish-hez, abból talán még lehet valamit.

A lényegből eddig ezt látom: egy deployolt webalkalmazás maga az Access Manager. Lehet más szerverekre Agent-eket deployolni, amik szintén webappok. Mivel ezek már a célalkalmazással egy domain-en futnak, ezért ha ezek kommunikálnak az Access Manager-rel, és után egy cookie-ba nyomják az eredményt, az elvileg a célalkalmazásból is hozzáférhető, és kezelhető.

Agent glassfishez csak 8.1-hezvan, de majdnem felment a 9-re, sőt valakinek állítólag ment is. A 8.1-eshez viszont demo is van, annak kéne mennie.

2006/10/25

J2EE security

Bármennyire is csodálná valaki a j2ee építmény, azt mindenkinek be kell látnia, hogy a security rész elég halványra sikeredett.

Azt, hogy mit tud, és mit nem, elég jól összefoglalja ez a cikk, szépen körbejárja az 1.4-ben lévő dolgokat (a részletességre jellemző, hogy olyan fejezetek is vannak benne, hogy What is a container? De ennek ellenére tényleg korrket.)

A cikk a container security megoldásira ezeket az előnyökket mondja:

  • beépített, tehát nem kell nekünk szarozni a session-ba rakosgatásával a User objektumoknak
  • kőbe van vésve az apija (csinálhatunk pl. taglibrary-t a használatához, ami mindenhol menni fog)
  • a több webapp között (egy szerveren) hordozni lehet a a belépési információt
  • Átmegy a webtier és a business tier között

Nekem ebből az utolsó a legmeghatározóbb. Az azért tényleg kényelmes, hogy weben authentikálok, és EJB-k között is meg lesz a user info. Viszont cserébe a container semmit sem ad. Nem lehet jól bővíteni, az apija minimális, auditálás 0, stb.

Van ugyan a JAAS, de ahogy a cikk is írja:

JAAS is included as a required authentication method that containers must support. But the specification is not strict about how the container should provide this functionality; therefore, each container provides different support for JAAS.

Pl. a Sun Java Application Server-ben egy com.sun-os osztályt kell leszármaztatni saját realm írásakor, ami ugyan leszármazottja a JAAS osztályoknak, de egy másik appserveren hajunkra kenhetjük az egészet.

Az meg már csak hab a tortán, hogy a JAVAEE 5 speckóban ilyen kedves bekezdések vannak:

Web-based internet applications often need to manage a set of customers
dynamically, allowing users to register themselves as new customers. This scenario
was widely discussed in the servlet expert group (JSR-53) but we were unable to
achieve consensus on the appropriate solution. We had to abandon this work for
J2EE 1.3, and were not able to address it for J2EE 1.4, but hope to pursue it further
in a future release.

(kiemelés tőlem)

Nem marad más hátra, mint mindenféle külső szoftvert használni. Ezek közül is 2 megoldást találtam:
  • Gyártófüggetlent, ami csak a servlet apira épül, jól hordozható, és általában elég pehelysúllyú.
  • Robosztus megoldásokat, amiktől gyártófüggő lesz a kódunk, viszont SAML-tól kezdve mindent tud.

Azt utóbbira (amennyire látom) példa a Sun (Java System) Access Manager termék, ezt még nem sikerült mozgás közben látni, az előbbire viszont egy elég jó (bár nem túl friss lista) olvasható itt.

Amiket ebből megnéztem

jGuard: Ez nézett ki a legjobban, valamennyi doksija is úgy tűnt, hogy van, van nem túl régi release, és a tervezése is elfogadhatónak tűnt távolról nézve. Gyakorlatban viszont se Tomcat-tel se Glassfish-sel nem sikerült működésre bírni a doksija alapján. 3-4 óra szívás után frissen telepített Tomcat-tel (NetBeans embedded-del nem) a példa alkalmazást sikerült feléleszteni.
Amúgy Pure JAAS modulokat eszik, valószínű, ha egy kicsit szájbarágósabb, precízebb leírása lenne, még tetszene is.

Kasai: Ezt még több helyen linkelték: 2005-ös release. Azt mondja, hogy az ő saját API-ja sokkal jobb mint a JAAS. Hát lehet.

Seraph: Atlassian, tehát már ajánló levél, plusz tisztességesen legenerált lap/doksi (maven). A SSO menüpont alatt viszont azt ajánlják , hogy úgy használjuk SSO-nak, hogy egy szerveren autentikálunk, ott egy cookie-t ragasztunk a kliensre a user névvel. És ha a domain alatt egy másik alkalmazáshoz téved a felhasználó, automatikusan beléptetjük a cookie-ben tárolt felhasználó nevére. Ezt vagy nagyon nem értem, vagy nagyon gyanús. A cookie-k mintha kliens oldalon lennének, és azt a user nevet írom bele, amelyiket akarom.

Gabriel: Azt mondja azt adja mint az EJB (ami nem túl sok) csak EJB nélkül. Mellesleg halott

Mindig óvva intenek, hogy feltaláljam azt, ami már úgyis meg van, de egyelőre úgy tűnik, hogy ha normális security szolgáltatásra lesz szükségem nekem kell majd implementálni.

2006/10/19

DOM4j vs JDOM

Vicces dolog két olyan library összehasonlítani, amiből az egyik utoljára 2004/09/09-ben a másik 2005/05/16 jött ki, és azóta semmi. Mindenesetre a JDOM és a dom4j is olyan dolgokra jött lérte, amire elvileg sem a DOM sem a SAX nem képes.

Mindkettő tud írni és olvasni SAX-ból és DOM-ból. a JDOM azzal reklámozza magát, hogy sokkal egyszerűbb, mert milyen jó dolog olyanokat írni, hogy
Element e = new Element();
A dom4j ezzel szemben viszont sokkal jobb :-)
Jó elismerem, kell hozzá factory, hogy létrehozzunk egy új element-et (illetve ez sem biztos, mert csak a gyökér elemhez kell, utána lehet az element.addElement("gyerekteg") -gel is létrehozni új gyerek elemet, ami visszaadja az új elementet.

Viszont cserébe minden csak interface. Alatta a beállításoknak megfelelően különböző implementácíójú osztályok lehetnek. Van pl. olyan, ami egy kicsit több memóriát eszik, de sokkal gyorsabban keres attributumokra, van olyan, ami olyan dom4j komponens fát csinál, ami simán castolható DOM fává (nem kell egy új DOM fát építeni a konvertálásnál), és ez azért elég szép dolog.

Van benne még mindenféle adapter Swing-es elemekhet (pl. TableModel), tud XSLT-jellegű transzformációt (Rule-oknak hívja magát), amit két bejegyzéssel ezelőtt szerettem volna. A gyerekeket meg tudja mondani List-ben, Iterátorban, vagy egyenként (for ciklus). Szépen kezeli az XPath-t, keveset fogyaszt, és a dokumentációja is egy újnyival több mind a JDOM-nak.

2006/10/15

Maven2

Mit akarok csinalni egy projekttel?

  • Létrehozni
  • Librarykat hozzáadni
  • Megírni a kódot
  • Buildelni
  • Tesztelni
  • Futtatni
  • Csomagolni
  • Publikálni

Akkor nézzük mit ad nekem ehhez Maven, es mit a hagyományos IDE alapú fejlesztés (nálam NetBeans)

Létrehozás: Mivel csak standalone Java programot csináltam nem volt szükseg bonyolult archetypokra. Netbeans kreálta alap pont olyan jó volt mint a Maven-es.

Libraryk: Az nagyon okos, hogy a Maven egy helyen tárolja a függősegeket (azaz csak egy helyen kell meglennie pl. a log4j.jar-nak), de ugyanezt az IDE-k is tudjak. Igaz, itt fontos, hogy az összes hasznalt gepen ugyanolyan nevű shortcutokra legyen beallitva a jar file. Ha több gépen is fejlesztjük az egy projektet nagyon hasznos lehet, hogy a Maven library hivatkozás globalis, tehat ha beirjuk mi a függőség, bárhol is vagyunk letölti neküknk uazt a jart.

Megírni a kódot:Sajnos ezt is kell, és hiába csinál egy csomó mindent meg helyettem a Maven, ha a programozást segítő kiegészít funkciók közben meghallnak az IDE-ben, akkor nem fog érdekelni a dolog.

Buildelni/tesztelni: Ez mindkettőben ugyanaz az élmény. Bár Buildelni Netbeansben csak a saját ant build szkriptje alapjan sokkal gyorsabb, mint meven ide-n keresztul.

Futtatni: Ezt Mavenben vagy úgy eldugták, hogy nem találtam, vagy nincs. Ideből röhögve.

Csomagolni: Netbeans alapból jar csomagot állít elő, a dist könyvtárba. Maven plugin némi szöszölés után sokkal jobban testreszaható. Bár azt hiszem ant alapon a NetBeans-et is meg lehetne tanítani okosabb dolgokra.

Publikálás: Ebben egyértelműen a Maven a nyerő, site-ot csinál, reportokat generál.

Szóval itt tartok. Próbáltam a mevenide-t NetBeans-hez, nagyon szép, csak pont a finisben hasal el. Pl. ha Maven projektet nyitok nem használhatom a persistence-s varázslókat. EJB3-mal meg se mertem próbálni. Ha csak command line-ból használok Maven-t, és fejlesztéshez NetBeans-t akkor is iszonyú szívás a dolog.

A Maven a library kezelésben nagyon erős, meg a site deployban, de emellett hiába van róla ingyenes könyv, meg a honlapon elég sok guide nagyon nehéz eligazodni a doksikban, és advanced dolgok már nincsenek nagyon leírva. A library kezelést lehet mással is helyettesíteni (pl. Ivy), de a report generálás azért hiányozni fog.


2006/10/12

XSLT logika javaban

Ezzel ax XSLT-ve en sohasem voltam kibekulve. Szep az elmelet, de ha bonyolult dolog van, akkor az ember ugyis valami ertelmes programnyelvhez nyul transzformaciohoz. Ha meg csak az alapdolgokhoz jo, akkor mi szukseg van valami uj nyelvszeru dologra. (Gondolkodtam nagykepuen).

Jo, csinaljuk meg Javaban. Kell egy olyan dolog, ami vegigmegy az XML-fan, minden node-nal megkeresi a legjobban illeszkedo szabalyt (az illeszkedest tetszoleges bonyoult XPath-szal definialom), es lefuttatja.

Az hamar eldolt, hogy SAX nem lesz jo, hisz ott az Event fuggvenyek csak string-eket kapnak, a dom poziciorol semmit sem tudnak, es a szabalybol sem tudok kinezni a dom mas agai fele.

Akkor legyen DOM (ugye mindig mas XML kell, schema nem is bitos, hogy van ezert a JAXB, ami szinten DOM szagu, nem jon szamitasba.). A problme az, hogy meg nincsenek meg azok a fuggvenyek, amik a DOM fa kurrens poziciojanak XPath-at ossze tudna vetni egy adott szabaly/listener elore, esetleg teljesen mas alakban megadott szintakszisaval.

Viszont, egyreszt a Xalanban van XSLT motor, ugy hogy o megcsinalja valahogy, illetve van meg az xsltc, ami java byte code-ot fordit xslt-bol (mar jol hangzik). Szoval ilyen iranyban guglizunk tovabb.

2006/10/06

Netbeans 5.5 RC1

Igazából csak arról akartam írni, hogy miután sikerült JSF CRUD-ot összelőcsölnöm mindenféle doksi alapján, megtaláltam a Netbeans-ben, hogy DB alapján néhány gombnyomással legenerál ő mindent.

Szóval akkor már: kijött a napokban az RC1. Persze a changelog-ot sehol se találom, mert az már a véglegeshez van, de néhány új code generáló mellett (pl. JMS hívás) találtam pl. Kodo-t és Hibernate-t is a persistence unitok között.

2006/10/01

Java persistence api

A mondás az, hogy azért került be csaj az EJB3 JSR alá, hogy gyorsabban át lehessen nyomni a processen. Ezzel szembe akár standalone alkalmazásokba is lehet használni.

A lényege, hogy Pojo entitásokat használ, és egy absztrakt apit definiál, amivel perzisztálni lehet ezeket. Descriptor helyett pedig annotationok vannak a Pojoban.

Szép, egyszerű: ide is rakok egy példát az íze kedvéért:

Az entitás

package jpasample;

import java.io.Serializable;

@javax.persistence.Entity
public class SampleEntity implements Serializable {

    @javax.persistence.Id
    private Long id;
    
    public SampleEntity() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public int hashCode() {
        int hash = 0;
        hash += (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }

    public boolean equals(Object object) {
        if (!(object instanceof SampleEntity)) {
            return false;
        }
        SampleEntity other = (SampleEntity)object;
        if (this.id != other.id && (this.id == null || 
                !this.id.equals(other.id))) return false;
        return true;
    }

    public String toString() {
        return "jpasample.SampleEntity[id=" + id + "]";
    }
    
}

A meghívó program már egy kicsit bonyolultabb, de csak a tranzakció és kivétel kezelés szórta meg nagyon.

package jpasample;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {
    
    //private static EntityManagerFactory emf = 
       Persistence.createEntityManagerFactory("TopLinkPU");
    private static EntityManagerFactory emf = 
       Persistence.createEntityManagerFactory("HibernatePU");
    
    public static void main(String[] args) {
        new Main().run();
    }
    
    public void run(){
        
        EntityManager em = emf.createEntityManager();
        SampleEntity entity = em.find(SampleEntity.class,1l);
        if (entity==null){
            System.out.println("nincs ilyen");
            entity = new SampleEntity();
            entity.setId(1l);
            em.getTransaction().begin();
            try {
                em.persist(entity);
                em.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                em.getTransaction().rollback();
            } 
        } else {
             System.out.println("van ilyen");
             em.getTransaction().begin();
            try {
                em.remove(entity);
                em.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                em.getTransaction().rollback();
            } 
            
        }
        em.close();
    }
}

És persze kell hozzá még egy descriptor is, hogy melyik Persistence Api implementációt használjuk:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="TopLinkPU" transaction-type="RESOURCE_LOCAL">
  <provider>
  oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
  </provider>
        <class>jpasample.SampleEntity</class>
        <properties>
            <!--<property name="toplink.jdbc.url" value="jdbc:derby:asd;create=true"/>-->
            <property name="toplink.jdbc.url" 
                         value="jdbc:derby:asd"/>
            <property name="toplink.jdbc.user" 
                         value=""/>
            <property name="toplink.jdbc.driver" 
                         value="org.apache.derby.jdbc.EmbeddedDriver"/>
            <property name="toplink.jdbc.password" 
                         value=""/>
            <!--<property name="toplink.ddl-generation" 
                         value="create-tables"/>-->
            <property name="toplink.jdbc.url" 
                         value="jdbc:derby:asd;create=true"/>
        </properties>
    </persistence-unit>
    <persistence-unit name="HibernatePU"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>jpasample.SampleEntity</class>
        <properties>
            <property name="hibernate.connection.url" 
                         value="jdbc:derby:asd;create=true"/>
            <property name="hibernate.connection.driver_class" 
                         value="org.apache.derby.jdbc.EmbeddedDriver"/>
            <property name="hibernate.connection.password"
                         value=""/>
            <property name="hibernate.connection.username"
                         value=""/>
        </properties>
    </persistence-unit>
</persistence>

A NetBeans (5.5 beta 2), amivel ezekenek a kódoknak a nagyrészét generáltam az Oracle TopLink Essential-ját használja. De látható, hogy Hibernate Entity Manager-rel is ment a dolog szépen, csak az EntityManagerFactory konstruktorában kell más persistence-szre hivatkozni. És ez azért nagy királyság: kész a program, de még cserélgethetem a persistence megoldást, hogy megmérjem melyik jobb nekem.

Alapvetően egyébként a JDO is hasonló lehet (múltkor belelapoztam egy könyvbe), elvileg meg is van ígérve, hogy a két speckót egyesítik. De a JPA mellett szól az is, hogy az EJB3 pihepuha Entity Bean-jei is ezt használják.

2006/09/26

internet updater

Szeretnék egy standalone Swing alkalmazásban internetes software update lehetőséget tenni. (Illetve csak érdekel, hogy lehetne megoldani.)

Hiába túrom az internetet, seholse találom, hogy lenne rá előre kész megoldás. Van a web start, de nekem nem az kell. Tudom, hogy a JVM magát tudja, de nekem az se jó. Más találat nem érkezik.

Az egyetlen megoldás eddig amit találtam, hogy Eclipse vagy NetBeans platform alá vonulok, de én ennél pehelysúlyubb megoldást keresek. Esetleg látott már valaki ilyen frameworkot?

2006/09/21

JSF (IoC)

Az IoC-s huhogásom visszavonva, megtaláltam rá a megoldást. A faces-config.xml-ben vidáman lehet egymásra hivatkozni a beanekkel:

   <managed-bean>
        <managed-bean-name>RecipeAction</managed-bean-name>
        <managed-bean-class>recept.RecipeAction</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
        <managed-property>
            <property-name>recipe</property-name>
            <value>#{recipeDTO}</value>
        </managed-property>

    </managed-bean>
    <managed-bean>
        <managed-bean-name>recipeDTO</managed-bean-name>
        <managed-bean-class>recept.RecipeDTO</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>

Azaz a RecipeAction recipe metódusába a setteren keresztül szépen belemegy egy recipeDTO (mivel request scope, ezért mindig újra létrejön egy új és azt rakja be).

Lesz ebből még valami.

2006/09/20

JSF (part 1)

A napi adag mellett végre talán megint lesz egy kis időm tovább nézni a JSF-t, de előtte gyorsan leírom az eddigi tapasztalatokat:

A kontextus: azt mindenhol mondják, hogy a JSF szép fastruktúra, a web komponensek hasonlóan felépítenek egy fát, mint mondjuk a Swing-ben. Adatok beküldésekor, validálásakor, rendereléskor, minden node a saját részét csinálja meg. Ami nekem új volt, hogy a másik alapvető dolog, hogy vannak POJO bean-ek (xml-ben definiálva, hogy application, session vagy request scope-pal működnek.) Ezeknek a bean-eknek az egyes attributumait (de néha a függvényeit is) hozzá lehet rendelni a fa komponenseihez. (Tipikusan mondjuk formhoz). Ez az EL-hez hasonló szintakszissal megy, csak $ helyett #-el.

Pl. meg lehet csinálni, hogy egy form mögé rakok egy bean-t, és submit-kor az egész bean kitöltődik a request adatokkal. Rögtön tehetem session scope-ú bean-be is, és akkor már is elraktam a session-ba a bemeneti adatot (persze a validálás után).

Minták: A gond nálam ott bonyolódott el, hogy bármelyik form bármelyik eleméhez lehet bindelni. Ezzel nagyon szép kaotikus dolgokat lehet csinálni. Én pl. szívesen tanulmányoznék néhány mintát, hogy hogy lehet viszonylag normálisan összekötögetni a dolgokat, hogy valamiféle szétválasztása a rétegeknek megmaradjon.

IoC Ehhez kapcsolódik, hogy nekem, aki a Spring IoC konténerén szocializálódott, egy kicsit kaotikus volt. Egyrészt, hogy minden bean-t össze drótozunk minden formmal, másrészt, hogy a a beanek is egymással statikus gyártófüggvény szerű dologból lekérhetőek. Nem tudom miért nincs benne egy kicsit több IoC szellem. Talán meg kéne néznem a Spring integrációt is.

A doksi: az apit és a taglibrary doksit nézegettem, de néha elég nehéz volt kideríteni belőle dolgokat (pl. hogy működik a dataTable). Aztán most nézem a speckót, úgy tűnik az én hibám, mert teljesen más helyen kellett volna kereseni. Azért sokat segítene egy almanac szerű oldal.

ui: ja és semmi Creator csak Netbeans, ez nagyon fontos

Folyt köv.

2006/09/06

Session cookie

Jó dolog ez a jcp igazán, szórakozásnak se utolsó olvasni a specifikációkat és a szavazásokat. Hanem az kezd igazan jo lenni, amikor kevésnek bizonyul speckó.

Pl. szeretnék olyan session-t, ami megmarad 1 napig, mégha a böngészőt be is zárom. Ezt nem tudom (eddig nem sikerült) megcsinálnom. A session cookie ugyanis Expired kitétel nélkül jön le, tehát addig él, ameddig a böngészőmet bezárom. (Legalább is ez a tapasztalatom. A 2.4-es Servlet speckóból semit sem találtam az ügyre vonatkozóan).

A session cookie-t nem lehet lekérdezni az apival (bár gyártó függő csomagok néha vannak, de azt ugye azért mégsem). Tehát nem marad semmi eszközöm arra, hogy befolyásoljam a session cookie életét.

Előszőr arra gondoltam, hogy valami Listenerrel megfogom a requesteket, és amikor új session(isNew) van, akkor megfogom a cookie-t. De hamar rajottem, hogy ehhez a request (amibol a session jön) es a response (amibe a cookie-kat dobaljuk) is kell.

Akkor jott a filter. Ott megvan mindkettő, de tüzetesebben vizsgálva szembeötlő, hogy a Cookie-kat csak befele dobalni tudom lekérni egyáltalan nem. Na erre hamarabb is rájöhettem volna.

Akkor csinálok egy HttpServletResponseWrapper-t a filterben es azt adom tovább a chain-nak és a setCookie metodusaban árgus szemekkel figyelek: ezt is hiába, mert semmi nem törtenik. Valószinűleg a hasznalt implementáció közvetlenül a writer-be nyomta bele a cookie headert. Vegül is senki nem irja elő, hogy a setCookie-t kell használni.

Na itt adtam fel. Talán még az lenne megoldas, hogy egy Wrapper osztállyal az egész Response outputot bufferelem, ha még nem volt session, és a végen parsolom a header-t. Na de ez már olyan nagy áldozat lenne, hogy inkább alábbadok az igenyeimből. (Vagy ilyenkor kene hozzaszolni a JSR-hez?)

2006/09/05

Sun Java Studio Creator

Nem tudom pontosan mikor, de csak néhány napja, hogy a legfrissebb javításokkal a fenti program más tapasztalatai szerint 50-90%-ékkal gyorsabb lett. Ennek örömére újra megpróbáltam és tényleg javítottak rajta.

Bár én inkább annak örülten, hogy a most letöltött változat végre hajlandó Ubuntu alatt is elindulni. (Kb 3 hónapja még a projekt létrehozásakor széthallt az egész és hosszas guglizás és bugreportolás sem segített).

Egyébkén a fenti tapsztalatok (mármint hogy gyorsabb) nem az enyémek, hanem csak hallomás, és azt is mondták, hogy bugos-bugos, de már nagyon jól használható.

Hát nem tudom. A visual összerakóját én inkább fentartásokkal kezelném, de azt hiszem a JSF-be most már mindenképpen bele kéne mélyednem egy kicsit.

2006/08/28

JavaBeans és O/R mapping

Ülök az ablak mellet és a tájat nézem. A JavaBeans-eken elmélkedem.

Egy kevéssé típusos nyelvben olyat is láttunk már hogy lekérdezés előtt az sql query-t keresztül eregették néhány kiterjesztő modulon valamilyen hook rendszer segítségével, és mindegyik modul átformálta úgy a lekérdezést, ahogy ő szerette volna (pl. hozzácsapott valamit). A választ meg majd szintén keresztül eregették a hook systemen, és minden modul szemezgetett 
belőle, és felhasználta az eredményben a kapott plusz mezőket.

Ez eddig nem nagy szám. Javaban is meg lehet ezt csinálni. Mondjuk én szívem szerint kipróbálnám, hogy nem a query String referenciáját küldeném át (ez a String viselkedése miatt nem is lenne annyira jó) hanem csinálnék egy Query osztályt, amihez tagfüggvényekkel tudnék hozzáadni plusz WHERE, ORDER BY stb. feltételeket.

Aztán megkapnám az eredményt. Ez is száll ágról ágra, és minden modul ki tudná venni pl. res.getString("plusz mező")-vel plusz oszlopokat a ResultSet-ből, amiket az sql módosításával ő biztosított magának.

A probléma ott van, hogy múltkor elkezdtem O/R mapping-gel kísérletezni, és az első egyszerű példák valóban nagyon kellemesen kézbe símultak. Csakhogy O/R mapping-gel az adatbázis válasz struktúráját beledrótozzuk a bean osztály szerkezetébe, amit nem fogunk tudni sehogy sem kiterjeszteni (a leszármaztatás már rögtön a több modulnál elvérzik, de az interface implementálás sem járható út).

Őszintén szólva nem ismerem ilyen mélyen az O/R mapping megoldásokat, hogy erre milyen megoldásokat ismer. Két dolog kéne
  • egyrészt, hogy a lekérdezéskor ki lehessen terjeszteni az (?)SQL lekérést plusz WHERE, JOIN stb. feltételekkel
  • és az így kapott plusz mezőket valahol visszaadja
Pl. visszaadhatna egy bean helyett egy bean tömböt (legyen mondjuk Map). A tömb elemeiért (amik egyenkén JavaBean-ek) különböző modulok felelősek, és az alapmodulnak nem kell tudnia a kiterjesztés plusz bean fragmentumairól. Csak persze akkor meg az lesz a kérdés, hogy honnan 
tudjuk, hogy a lekérdezésnek az egyes oszlopaiból melyiket melyik JavaBean-be dobjuk szét.

Nem tudom sikerült-e jól artikulálnom a problémát, de szerintem elég szerény kívánalom. Talán tudja is valamelyik O/R mapping cucc, csak sokkal mélyebben el kéne olvasni a doksikat.

2006/07/21

Time out

Semmi gőzölgő kávé, semmi forróság. Elmentünk északra. Augusztus végén jövünk.

Liferay ismerkedés

Szóval keresek egy portálrendszert, ami: ingyenes, moduláris, könnyen bővíthető, viszonylag vállalható architektúrájú.

Ennek keretében nyomogattam egy kicsit a Liferay-t. Első tapasztalatok.

1. Nem tudom miért, de ezzel is az az érzésem, hogy fejlesztők azt mondják, hogy jó jó az OS, de a dokumentációt nem visszük túlzásba, hogy a supportba visszacsöpögjön valami. Mert vagy én vagyok nagyon hülye, vagy tényleg egy kicsit kevés a dokumentáció.

Senki nem szólt pl. hogy linux alatt léteznie kell egy /home/liferay-nek, ahová tudjon írni a portál, különben exception-ökkel elszáll.

(Külön izgalmas, hogy ha dokumentációt keresek az oldalon, akkor azzal kell szembesülnöm, hogy én nem felhasználó vagyok, hanem developer. A developer zone alatt vannak a doksik, és a developer doc tartalmaz egy sokkal részletesebb install leírást, mint az user guide.)

2. Ami izgalmas volt számomra, az a portlet alapú működés. Eddig is tudtam a portletekről, de még sose láttam a gyakorlatban, hogy hogy megy. A Liferay nagyon szép példa volt. Teljesen más gondolkodás mód mint amit megszoktam. A kis CMS-ek általában úgy működnek, hogy van egy url, és az alatt egy funkció (hírek, képgaléria, stb.). És ha nagyon kell, akkor blokkokat nyomhatok a fő tartalmak köré. (Szerencsés esetben megadhatom, hogy a blokkok mikor ne, illetve mikor látszódjanak).

Itt teljesen máshogy van. Van egy url, és az egy tiszta lap. Ebbe dobálhatom bele a portleteket (blokkokat). Mindegyik lapra külön beállíthatom, hány hasábos legyen, és hogy portleteket dobálok bele, vagy mondjuk IFRAME-es legyen.

A portleteket külön lehet konfigurálni, viszont ha egy oldal egyik portletjének egy aloldalára szeretnék menni, akkor az teljes képbe bejön, és eltűnik minden más az oldalról, pedig lehet, hogy néhány blokkot én továbbra is láttatni szeretnék.

3. A Liferay4.0-val szállított portletek szerintem elég halványak. Pl. az Image galery elég szánalmas. Ezért inkább egy jó keretrendszernek tűnik (legalábbis azt nem néztem) de a hozzáadott dolgok egy kicsit fapadosak, kevés dolgot lehet konfigurálni rajtuk.

4. Néhány megjegyzés még:

  • My places alá helyet új community felvételével lehet csinálni.
  • Ha utáljuk az alap demó adatbázist, akkor első körben a web.inf-ben kell a company_id-t megváltoztatni. (Gondolom az adatbázisban a sok szemét még megmarad, de legalább üresen lehet tesztelni.)
  • Az többnyelvű tartalmakat nem tudom elérni, mert amit a csilli villi lifecat tutorial mutat, az az üres adatbázisban nálam nem elérhető, és a doksi mélyen hallgat, hogy hogy kell bekapcsolni.
  • Azt hogy egy oldal hány oszlopos legye, az új portletet hozzáadó oldalsávban lehet beállítani.

2006/07/19

Maven kezdet

Valószínű már mindenki Maven2-n nyomja (az egészen ortodox ant hívőket kivéve), meg kellett hát néznem nekem is. Egy kis projektem migrálásával próbáltam ki.

Útmutatóm a nagyon korrekt (regisztráció után ingyenes letölthető) Better Builds with Maven könyv volt. (Az első fejezeteit olvastam el eddig, az alapokat nagyon korrektül leírja).

A vélemények:

  1. a plugin rendszer, a közös repo, amiben a függőségeket tárolja az első használat után is igen meggyőző megoldás.
  2. az alap pluginek a leírás alapján nagyon könnyen beizzíthatóak voltak, ment minden pöccre.
  3. illetve néha kiírta, hogy valamilyen függőséget nem talál, de ha mégegyszer elindítottam, akkor simán letöltötte. Utána meg már ment, úgy hogy nem volt kedvem utánamenni mit nem állítottam be.
  4. Azért az alap pluginek között is van néhány rejtély. Pl. az scm (amiről a könyv nem beszélt részletesen csak a release fejezet révén egy kicsit és ott még nem tartok). A generált honlapja pl. tartogat néhány 404-et, és a jirában 2004 óta terveztgezik, hogy Create user guide/Guide for the impatient programmer
  5. Azért én türelmes voltam és kiderült, hogy viszonylag kis munkával, ha nincsenek is a goal-ok kiírva a plugin lapján a forráskódból kideríthető a működés.
  6. A pluginek doksija általában néhány példa, ami sokszor elég, néha nem. Nagyon sokat lehet tanulni azonban a forrásukból is, mert általában a pom.xml (és pl. a site source) is fent van a verzókövetőben és rögtön lehet látni, hogy hogy csinálták meg ők valamit.
  7. Persze az alap pluginek működése közül sok nem azt nyújtja pontosan amit én szereték (pl. changes), de azt látom, hogy nagy királyság az is, ha ilyenkor írok egy plugint és egy életre meg lesz ami kell.
  8. Azért nagy és bonyolult projekteknél a site generátor nem tudom mennyire működne, de szinte megjött a kedvem a kis lokális projekteket is egy hejde kis maven site-tal dokumentálni.
  9. Alig várom, hogy az sf plugint is kipróbáljam, mert ha az is megy, akkor tényleg befizetek rá.

Hessian

Kb. 1.5 hete babráltam vele egy kicsit, úgy hogy gyorsan leírom a tapasztalataimat, amíg el nem felejtem.

Előszőr is (tudom unalmas): dokumantáció. Én se vagyok egy nagy bajnok benne, de az hogy a http://www.caucho.com/hessian/ oldalon a JavaDoc menü alatt nem a legfrissebb verzió (2005/05/16 3.0.13) javadocja van kigenerálva, az szerintem elég átverés (én meg naívul onnan kezdtem el böngészni, és csodálkoztam, hogy a forrással nem klappol.)

A másik az volt, hogy nekem még mindig túl sok adat ment át a hálózaton. Ez főleg azért történt, mert a protokol az objektumokat ugyanúgy kezelte mint a Map-et, azaz kulcs érték párokat írt le, és ha én 1000 objektumot (mondjuk egy List-be rakva) leszerializálok, akkor 1000-szer benne lesz a kódolt üzenetben az összes osztályváltozóm neve. (Ez még teljesen korrekt, egy protokolt valahogy definiálni kell.)

Sebaj gondoltam, majd szépen átírjuk a szerializáló függényt. Azt hogy melyik objektumra milyen szerializáló algoritmust használunk a SerializerFactory adja meg. (byte-tól kedzve char[]-ig mindenre szépen külön megadja, hogy ki fogja szerializálni). Gondoltam szépen származtatok belőle egy sajátot, és ott átírom az Object[] szérializátorát. Ekkor jött a meglepetés: az alap szerializátorokat egy static{} (!) blokkban állítja be az osztály (a getSerializer függvény nem static). Biztos volt oka, hogy miért nem a konstruktorba került, végül is csak futólag néztem meg, de ez futólag nézve nekem elég gyanúsnak tűnt.

((A megoldás egyébként az lett volna, hogy csinálok egy üres SerializerFactory-t, ami csak az én konkrét osztályaimra ad vissza szerializátort, és ezt egy alfactoryként hozzá lehet adni a főhöz. De pl. az Object szerializátorát globálisan nem tudtam megváltoztatni.)) Végül egy rövid teszt program (csak hogy itt legyen nekem) hogy hogyan teszteltem, hogy mekkora lesz egy objektum szerializálója (a service POST-okat használ, azt nem volt kedvem birizgálni) Object test = new TestOne(); OutputStream os = new FileOutputStream("test.bin"); HessianOutput out = new HessianOutput(); SerializerFactory factory = new SerializerFactory(); out.setSerializerFactory(factory); out.init(os); out.writeObject(test); os.close();

2006/07/13

Spring plugin framework

Régóta foglalkoztat a kérdése, hogy hogy lehet a Spring frameworkből (j2ee használat esetén) valami modulláris-pluginos cuccot csinálni. (Mondjuk mint a JPF, aminek meg az Eclipse a mintája).

Most a TSS linkelt be egy cikket. Ami lightweight pluginekről beszél spring alatt.

A tehcnika röviden:

class betöltés
: j2ee esetén azt tanácsolja, hogy dobjunk be mindent a WEB-INF/lib-be, és akkor nem kell velel foglalkozni, hogy mi töltődik be. Standalone app esetén egy ant build fájlt használ indításra. Az ant classpath megadásánál ugyanis lehet * wildcardot használni.

A j2ee-s változattal csupán az a bajom, hogy a modulr kódja és a függőségei összekeverednek egymással. Ha egy-egy modulomnak 5-10 jar függősége van, akkor nehéz lesz kihámozni a lib könyvtárból, hogy mi a függőség, és mi a modul.

Viszont az kétségkívül előnye, hogy könnyen meg lehet emiatt oldani a több modul -- ugyanaz a függőség problémát. Lehet hogy valami fájlleíróval a függőségeket is szimpla modulként kéne kezelni.

spring bean építés: a bean-ek külön fájlokba helyezése sose volt probléma. A Spring remekül támogatja, hogy ne egy bean fájlt, hanem sok kicsit olvasson be.

hook rendszer: A kiterjeszthetőség elég izgalmas: Hook meghirdetése gyakorlatilag egy szimpla bean-nel történik, aminek a List típusú paramétereit üresen hagyja. Hook regisztrálása egy BeanFactoryPostProcessor leszármazottal történik (emiatt az xml-el feldolgozása után, de a bean-ek létrehozása előtt kerülnek ezek a beanek meghívásra). És ezeknek a bean-eknek a konstruktorába szépen a meghirdetett beanek üres paramétereit kitölti a saját praméterei alapján. (Nem tudom nem gáz-e, hogy ha sok ilyen kiterjesztést akarunk regisztrálni, akkor tele leszünk, felesleges objektumokkal a memóriában. EZek az objektumok csak regisztráláskor fontosak).

A TSS cikke után viszont izgalmas hozzászólások vannak, egyéb megoldásokra.Eddig csak az el4j-t néztem. Lehet hogy én vagyok nagyon nehéz felfogású, de én még egy kicsit több doksira, és step-by-step tutorialokra vágynám, hogy teljesen átlássam a dolgokat.

2006/07/09

Tomcat Xen memory test folyt.

A dolog most így áll: a szerveren postgresql 8.1, tomcat 5.5 és egy alap spring framework alapú AJAX-os j2ee alkalmazás. (Meg presze munin-node, amivel a grafikont csináltam). Úgy tűnik ennyi még éppen belefér a 128 megába. (a zöld, amit használok, a cache-t, ha jól tudom, még fel tudnám használni)

UPDATE: úgy tűnik hosszú távons is bírja. Amióta 128-on megy, még nem volt oom killer.

2006/07/05

Tomcat Xen alatt memory test

Szóval mennyi memória kell egy xen dom1-nek, ha tomcat-et akarok futtatni rajta. A dolog egyszerű:

  1. default ubuntu dapper debootstrap
  2. apt-get install sun-java5-jdk
  3. wget tomcat 5.5, tar xvzf
  4. startup.sh
Egyelőre nézzük az alap telepítést, különösebb app nélkül: 128 memória alatt simán ment. Lemegyek 48-ra: az is megy.

Ez azért érdekes, mert a budget dedicated hasonló cucca 48 memórával meghallt. Úgyértem el se indult.

Most 48-ccal simán megy, de annyira nem szép a helyzte, mert az oom killer rendszeresen kilövi a tomcat-et memória hiánykor. Vissza 128-ra.