Arkiv for kategorien 'Java'

Endelig skikkelig konfigurasjonsstyring av java-applikasjoner

For oss utviklere som er opptatt av å levere kvalitetsløsninger så har konfigurering av deploymentpakker for ulike miljøer som test, stage og prod vært problematisk og tungvint.

En nokså populær måte bygge deployment pakker på har vært å bruke Mavens funksjonalitet til å definere profiler og filtrer. På denne måten får man definert hvilke konfigurasjonsfiler som skal være med i de ulike miljøene. Ulemen med denne løsinger er at man ender opp med en pakke for hvert miljø, noe driftspersonal ikke ønsker. De ønsker å kunne deploye den samme pakken i alle miljøene.

For å løse dette så er det ofte vanlige å trekke ut konfigurasjonsfiler av deployment pakkene, og legge dem på et bestemt sted(/etc/konfig.properties)  hvor de blir lest ved oppstart.  Ulempene med denne løsningen er at konfigurasjonsfilene blir spredd ut over forkjellige maskiner. Dette gjør det  tungvint å refakturere og endre på strukturene av konfigurasjonsfilene. (I stedet for å endre på konfigurasjonsparameter så beholder man det subboptimale for å unngå å måtte gjøre endringer på flere forskjellige maskiner.) En annen svakhet med denne løsningen er at det blir vanskelige å holde styr på hvilke parameter som er satt i de ulike miljøene for eksempel når man introduserer nye parameter.

En bedre løsning hadde vært å kunne gjøre alle konfigurasjonene på en plass i en fil. Dette er nøyaktig hva Constretto muligjør.

Constretto er et java open-source rammeverk laget av Kaare Nilsen fra Arktekk som gjør det mulig å deploye samme pakke i flere miljøer. Constretto kan ta konfigurasjonsfiler på to forskjellige måter.

Den første er en variant over java properties filer og ser slik ut:

parameter1 = min felles verdi
parameter2 = enda en felles verdi

@test.parameter3 = en verdi for test
@stage.parameter3 = en annen verdi for stage
@prod.parameter3 = en tredje verdi for prod

Vi har altså parametrer som er felles for alle miljøene, samt parametere for hvert miljø.

Den andre konfigurasjonsmåten er basert på gamle gode ini-fil-notasjonen:

[default]
parameter1 = min felles verdi
parameter2 = enda en felles verdi

[test]
parameter3 = en verdi for test
[stage]
parameter3 = en annen verdi for stage
[prod]
parameter3 = en tredje verdi for prod

Så dette var to forskjellige konfigurasjonsmåter, men hvordan vet hvert miljø hvilken parameter3 som skal brukes? Dette gjøres med å angå ved oppstart av java hvilket miljø man er i. For test vil det være –DCONSTRETTO_TAGS=test, og så vil Constretto lese de riktige parameterne.

Til slutt, hvordan kommer disse parameterne inn i selve java-applikasjonene? Bruker man Spring rammeverket så har Constretto en konfigurasjonslaster som oppfører seg veldig likt Springs egen property-placeholder, og som gjør at man når parameterne med vanlig ${parameter3} notasjon:

<constretto:resource location=”classpath:konfigurasjonsfil.properties”/>

<bean class=”KonfigKlasse”>
<property name=”parameter3” value=”${parameter3}”/>
</bean>

En annen måte å få injektet parameterverdier på er å bruke Constretto sine egne snertne java annotasjoner:

public class KonfigKlasse{
private String parameter3;

@Configure
public void configure(String parameter3){
this.parameter3 = parameter3;
}

Alt i alt så har dette revolusjonert konfigurasjonsstyring av java applikasjoner for meg. De er nå mye lettere å vedlikeholde og vi har nå en helt ny kontroll på hvilke parameter som blir brukt i de ulike miljøene.

Av variantene over så foretrekker jeg ini-filer sammen med java annotasjoner.

Pragmatisk programmering mot interfaser

Det sies at å programmere mot interface er god praksis. Spesielt når man kobler sammen applikasjonen via IoC(Inversion of Control) container som for eksempel Spring, så er det lissom en selvfølge at man skal bruke interfacerer og klasser. Hvor tanken er at brukere av klassen forholder seg til et interface og hvor IoC containeren injecter en bestemt implementasjon av interfacet. Tenken er god, men hva når man kun har en implementasjon av disse interfacene?

Trelags arkitektur (med domeneobjekter)

La oss tenke oss en trelags arkitektur, hvor man kjører enhets/integrasjonstester helt igjennom helt ned til en testdatabase (som opprettes helt automatisk f.eks via DbUnit). Hva er da hensikten med å lage og vedlikeholde disse interfacene? Slik jeg ser det er det ingen vits. Det skaper kun ekstra arbeid. Mange filer, og mer tungvint utvikling.

Jeg har akkurat opplevd dette hvor jeg har gjennomført programmert mot interfacer, men nå har fjernet alle, og det ser veldig ryddig ut.

Men så kan du spørre, hva om ønsker å injecte dummy test-klasser da? Jo, fint. Det er bare å refakturere. For eksempel så har MyService brukt CustomerDao, og vi ønsker å lage en dummy implementasjon av CustomerDao som heter CustomerDaoDummy. All right. Endre navn på CustomerDao til CustomerDaoImpl og lag et interface som heter CustomerDao som de ulike klassene implementerer. Brukere av klassen trenger man ikke å endre.

Min anbefaling er derfor å ikke programmere mot interface med mindre man trenger det. Du får renere og mer oversiktlig kode på denne måten. Dette er henhold til agile prinsipper og naturligvis KISS prinsippet (Keep It Simple, Stupid).

PS: Det skal sies at dersom man lager biblioteker og funksonalitet som krysser applikasjoner så kan det være hensiktmessig og ryddig med interfaces, men det er ikke tilfellet i en vanlig enkel applikasjon.

Spring med ny vedlikeholds policy

For de som ennå ikke har hørt det så har Spring gjort en relativt betydelig endring i deres release policy. Den nye policien sier at etter 3 måneder av en major release så vil kun de som betaler få nye bug-fix releaser. Så for eksempel når 3.0.0 slippes, og etter tre måneder så er man på 3.0.2,  så vil kun de som betaler få nye oppgradering som 3.0.3 osv.  Kildekoden vil likevel være tilgjengelig i SpringSources repository, men de som ikke betaler må laste nede og bygge selv.

Jeg ser ikke dette som et stor problem, men som en påminnelse om at selv om det er open source så betyr det ikke at det er gratis. I dette tilfellet så er kildekoden fortsatt gratis, men SpringSources koordinering av bugfixer må man betale for.

Det jeg tror vil skje er at noen i open source miljøet vil ta på seg å koordinere og lage bug-releaser selv.  Hvordan dette vil påvirke tilbakemelding og rapportering av bugs vil tiden vise.

Motivasjonen for dette er for meg tydelig, SpringSource ønsker flere betalende brukere og presser kundene på denne måten.  Noen vil argumentere for at firmaer som bruker Spring i kritiske applikasjoner burde uansett ha en supportavtale, men det som det har vært tilfelle med Spring er at bug-fix release har vært så gode at man ikke har trengt support, og veldig få har tatt seg ”bryet” med å betale.  Så med mindre gode alternativer for Spring kommer opp så vil nok flere firmaer nå ta seg bryet med å betale for varen.

Det jeg er nyskjerrig på er hvordan dette vil påvirke Maven bygging når releaser ikke lengre vil være i åpne repositorier.  Med mindre vi får en ny måte å gjøre dette på vil dette medføre mye rot som Maven til nå har løst.

Spring har nå vært en de facto standard for de aller fleste java prosjekter, hvor man har inkludert biblotekene selv om man ikke har brukt dem så mye. Jeg tror nå med den nye vedlikeholds policien så vil man tenke seg litt mer om før man inkluderer dette flotte biblotektet. Dette er litt trist, fordi etter min mening er Spring noe av det viktigste som har skjedd i java enterprise verdenen.

Lang diskusjon finnes her.

Luclipse et Lucene index verktøy for Eclipse

For alle som jobber med Lucene indexer av og til har vi nå laget et nytt verktøy som kan gjøre hverdagen litt enklere. Luclipse er en eclipse plugin som gir deg tilgang til dine Lucene indexer direkte fra Eclipse. Hittil har alternativet vært å bruke Luke, som har sine mangler. Bl.a. huser ikke Luke hvilke indexer du tidligere har åpnet, og brukergrensesnittet kan være noe overveldende og forvirrende før man har brukt det en del. På sikt er Luclipse tenkt å ha mye den samme funksonaliteten som Luke som sikkert flere kjenner, men forhåpentligvis vil Luclipse gi et enklere og mer effektivt brukergrensesnitt.  Vi ser også for oss å legge til funksjonalitet for å kunne teste sine egne alalyzere. Luclipse har vi valgt å legge ut som et opensource prosjekt, slik at andre kan være med å bridra til at vi får et bedre verktøy for jobbe med lucene. Den første versjonen og kildekode kan lastes ned på http://sourceforge.net/projects/luclipse/