<?xml version="1.0" encoding="UTF-8"?>
<posts type="array">
  <post>
    <body>Kigger ud af vinduet mens jeg leger med en matematisk formel og t&#230;nker p&#229; &quot;Unit in the last place&quot;:http://en.wikipedia.org/wiki/Unit_in_the_last_place Beregningen fortager en prognose over en rate pension. Den antager en masse udfra nogle parameter og returner et resultat i form af kroner og &#248;re. Jeg er stoppet op for at t&#230;nke lidt over pr&#230;cision og udtryk mellem formler og programmeringsprog. Problemet er at jeg operere med store decimaltal og jeg ved de er upr&#230;cise. 

I f&#248;rste ilteration udnytter jeg Ruby som programmeringssprog fordi det handler udvikling af en formel og forst&#229;else af problemomr&#229;det. Derefter skal de bedste formler overf&#248;res til Java som implementeringserpog og Javascript for hurtige forretningsvalidering. Undervej har jeg erfaret at jeg f&#229;r forskellige resultater afh&#230;ngig af platform og sprog. 

Lad mig starte med et regnestykke. 0.1 + 0.1 + 0.1 = ?

&lt;pre&gt;
System.out.println(0.1 + 0.1 + 0.1); # 0.30000000000000004
&lt;/pre&gt;

Resultatet er skuffende, og ikke de forventede 0.3 men et mere pr&#230;cist resultat. Grunden er at Java konvertere v&#230;rdien 0.1 til en double repr&#230;sentation og nu vil de mest ih&#230;rdige Java folk straks r&#229;be l&#248;s om BigDecimal.

&lt;pre&gt;
System.out.println(new BigDecimal(0.1).add(new BigDecimal(0.1)).add(new BigDecimal(0.1)));
# 0.3000000000000000166533453693773481063544750213623046875
&lt;/pre&gt;

Og det hjalp ogs&#229; lidt. Nu er resultatet langt mere pr&#230;cist men stadig helt forkert. 

Problemet er at et &quot;floating point tal&quot;:http://en.wikipedia.org/wiki/Floating_point er internt repr&#230;senteret i bin&#230;r form og decimaltallet 0,1 kan ikke pr&#230;cist repr&#230;senteres som &quot;1,00011001100110&quot;. Det er lidt det samme som at dele en hel (1) i 1/3 og 2/3. Derved f&#229;r man en 0.333333 og en 0.666666. N&#229;r disse to l&#230;gges sammen bliver det kun en 0.9999999 og ikke en hel. 

Men dette er kun f&#248;rste del af svaret. Vi m&#229; l&#230;ngere ind.. 

Der findes to typer af l&#248;sninger. 

* Den mest &#229;benbare er at undlade at arbejde med tal hvori der indg&#229;r decimaler
* Den anden er at afrunde og besk&#230;re resultatet

Decimaler eller floating point er i sagens natur upr&#230;cise. De b&#248;r undg&#229;s hvis der i l&#248;sningen skal indg&#229; super pr&#230;cise svar. Fx ved bel&#248;b eller m&#248;ntenhed kan l&#248;sningen v&#230;re at holde alle en enheder p&#229; lavest mulig niveau. &#216;re frem for kroner. Det virker som en naturlig ting at g&#248;re, specielt hvis man t&#230;nker over at vi jo aldrig holder danske kroner i 10 stks pakker. 

Den anden metode er at sk&#230;re de sidste mindst betydende decimaler af resultatet. Denne l&#248;sning bliver heller ikke pr&#230;cis fordi der nu skal rundes af og jo flere kald der fortages jo flere metoder vil runde op eller ned ved afkortning af resultatet. Yderligere fejl findes der i de trigonometriske funktioner ikke der ikke er s&#229; teoretisk korrekte som man kunne forvente. Dette er et resultat af akkumulerede afrunding fejl i polynomium tiln&#230;rmelser der bruges internt til at beregne trigonometriske funktioner og logaritmer. 

Lad og kigge p&#229; &quot;Eulers konstant (e)&quot;:http://en.wikipedia.org/wiki/E_(mathematical_constant) E er den matematiske konstant t&#230;ttest p&#229; det unikke reelle tal. 

&lt;pre&gt;
System.out.println(Math.E); # 2,718281828459045
System.out.println(Math.exp(1)); # 2,7182818284590455
&lt;/pre&gt;


Teoetisk burder disse to v&#230;re ens i Java for at give resultater der er t&#230;t p&#229; det teoretiske forventede. I ruby har Matz afrundet og afkortet en decimal tidligere for at ikke at l&#248;be ind i akkumulerede fejl. 

&lt;pre&gt;
puts Math::E # 2,71828182845905
puts Math.exp(1) # 2,71828182845905
&lt;/pre&gt;

Log 

Den &quot;naturlige algoritme&quot;:http://en.wikipedia.org/wiki/Logarithm  er base e, hvor e er et irrationelt konstant p&#229; 2,71828182845905. Den naturlige algoritme er skrevet som ln(x) eller log(x). Logaritmen af et tal til et givet basis er eksponent som base skal h&#230;ves for at producere et antal. For eksempel, base-10-logaritmen af 1000 er 3, da 3 er den magt, som ti skal h&#230;ves med for at producere 1000: 103 = 1000, s&#229; log10(1000) = 3. Logaritmen til x til basen b er skrevet logb (x) eller, hvis basen er implicit, s&#229; log (x). S&#229; for en r&#230;kke x, en base b og en eksponent y. 

&lt;pre&gt;
Math.log(Math::E) # 1.00 
Math.log10(1000) # 3.00 
Math.log10(5000) # 3.60 
Math.log10(10000) # 4.00 
&lt;/pre&gt;

Anvendelsen af logaritmer til komplicerede beregninger er en v&#230;sentlig motivation i deres oprindelige udvikling og i dette tilf&#230;lde antagelse af nye rater. 

The Power of 

Math.pow, ^ eller ** betyder alle at opl&#248;fte noget i potents. &quot;POW&quot;:http://en.wikipedia.org/wiki/Power_(mathematics) beregner den naturlige logaritme af x ved hj&#230;lp af polynomiel interpolation, s&#229; ganger med p, beregner e til denne opl&#248;ftning. Den skal ogs&#229; sikre at begge operander er pr&#230;cise heltal repr&#230;senteret i double samt at resultatet er et heltal der kan repr&#230;senteres i en dobbelt. I Java b&#248;r man undg&#229; denne metoder hvis det lader sig g&#248;re. Kildekoden til Math.pow er kompleks og i floating point. Som alle floating point metoder er resultaterne kun omtrentlige. Hvis du &#248;nsker mere pr&#230;cise resultater kan man bruge BigInteger eller BigDecimal. Ellers brug Knuth side 462 i &quot;The Art of Computer Programming&quot;:http://en.wikipedia.org/wiki/The_Art_of_Computer_Programming bind 2 Seminumerical Algorithms. Den metode, der g&#229;r tilbage til 200 f.Kr. i Indien.

Hvorfor er det vigtigt naturlige tal? Forstil dig en konto med p&#229;lydende 1,00 kr. og 100% i rente om &#229;ret. Hvis renten konteres en gang om &#229;ret bliver v&#230;rdien fordoblet til 2,00 kroner. Meget flot. Men hvis renten konteres to gange om &#229;ret bliver regnestykket til kr. 2.25. Hvis samme rente beregnes kvartalsvis ser regnestykke s&#229;dan ud: 1.00 &#215; 1.25^4 = kr. 2.44. M&#229;nedlige afkast: 1.00 x 1,083^12 = kr. 2,61. 

Her er simpel konto konteringsberegning i ruby hvori der bruges POW

&lt;pre&gt;
1.00 * (1+((100.fdiv(1)) /100)) ** 1 # 2.0
1.00 * (1+((100.fdiv(2)) /100)) ** 2 # 2.25
1.00 * (1+((100.fdiv(4)) /100)) ** 4 # 2.44140625
1.00 * (1+((100.fdiv(52)) /100)) ** 52 # 2.69259695443717
1.00 * (1+((100.fdiv(400)) /100)) ** 400 # 2.71489174438123
&lt;/pre&gt;

&quot;Bernoulli&quot;:http://en.wikipedia.org/wiki/Bernoulli_number bem&#230;rkede at denne sekvens har en gr&#230;nse for flere og mindre konterings intervaller. L&#230;g m&#230;rke til at forskel p&#229; kontering mellem uge og dag er minimal. Beregning siger at konteringsintervaller med rente p&#229; 1/n pr interval er lig store n, alts&#229; e. Dvs at kontinuerlig kontering vil aldrig kunne komme over e = 2,71828182845905. Meget interessant hvis man selv kan styre sin bank forretning. 

Nu til beregningen af formlen. Tallet jeg skal opn&#229; er &quot;929117.930471227&quot;. Og formlen ser s&#229;dan ud: 

&lt;pre&gt;
P  * (1- (1 / (1+R^Y))) / LN (1+R)
&lt;/pre&gt;

Hvis P er kr. 100000, Y er 10 &#229;r og R er li 1.5 procent i rente skal udfald v&#230;re kr. 929118.- afrundet. 

Ruby som programmeringssprog er et godt udgangspunkt idet sproget har en syntakst som ligger t&#230;t op af de rigtige formler. Bem&#230;rk at opl&#248;ftning i potents sker ved at **. 

&lt;pre&gt;
P * (1 - (1 / ((1 + R) ** Y))) / Math.log(1 + R)
&lt;/pre&gt;

Java er lidt mere omst&#230;ndelig at arbejde med men det g&#229;r s&#229;l&#230;nge man holder sig til double notationen. 

&lt;pre&gt;
P * (1 - (1 / (Math.pow((1 + R), Y)))) / Math.log(1 + R);
&lt;/pre&gt; 

Java med BigDecimal er n&#230;sten ul&#230;selig og ser slet ikke ud som base formlen mere. 

&lt;pre&gt;
new BigDecimal(P).multiply(ONE.subtract(ONE.divide((ONE.add(new BigDecimal(0.015))).pow(10)))).divide(new BigDecimal(Math.log(ONE.add(R))));
&lt;/pre&gt;


Javascript har en lidt anderledes med parenteser og det kan let blive kompliceret. I&#248;rigt lod jeg m&#230;rke til at forskellige browser implementation beregnede forskellige hvis der fantes for mange indlejrede parenteser. 

&lt;pre&gt;
var P = 1 - (1 / Math.pow((1 + R), Y));
var balance = P / Math.log((1 + R));
var d = balance * amount;
&lt;/pre&gt;

Oversigt over de resultater fra eksekvering af formlen p&#229; de forskellige platforme. 

| Platform | format | Result |
| Javascript | 64-bit IEEE 754 |         929117.9304712246 |
| ruby loat | 64-bit IEEE 754-2008 |   929117.930471227 |
| java double | 64-bit IEEE 754 |       929117.9304712268 |
| java BigDecimal | 64-bit IEEE 754 |  929117.9282152719 |
| java BigDecimal | 128-bit IEEE 754 | 929117.9282152719097211956977844238 | 

S&#229; mens sneen har lagt sig udenfor og temperaturen er langt under frysepunktet kan jeg samle mine tanker. Alle skriver og skriger om at man skal bruge BigDecimal, og tilsvarende ting i andre programmeringssprog, til ting som skal v&#230;re pr&#230;cise og is&#230;r indenfor finans og &#248;konomi. 

Det er den st&#248;rste gang vr&#248;vl! 

IEEE 754 floating-point-tal som double og float er perfekte til n&#230;sten alle former for beregninger og formler. De tilbyder en vilk&#229;rlig pr&#230;cision og god kompromis mellem hastighed og pr&#230;cision. Alle beregninger med naturlige tal bruger flydende tal ligesom &#248;konomiske prognoser basseret p&#229; trigonometriske funktioner og logaritmer. Det eneste sted jeg kan komme p&#229; hvor man gad at bruge BigDecimal er ved m&#248;ntenhed. I de tilf&#230;lde har man nemlig brug for at kunne afrunde med en bestemt afrundingstrategi. N&#229;r man operere med naturlige tal g&#229;r det faktisk ud over pr&#230;cisionen ved de ikke trivielle beregninger ln, potents, cosinus. P&#229; en computer finders der ikke en n&#248;jagtigt metode til at beregne flydende tal. At folk anbefaler at bruge bigdecimal til at udregne kvadratroden vha. Newtons metode der udspringer af konvergerende sekvens af tiln&#230;rmelser(konto), knuser min tro p&#229; den menneskelige intelligens. Jeg foretr&#230;kker at bruge IEEE dobbelt numre, velvidende at jeg kan stole p&#229; kun s&#229; mange cifre i det endelige resultat, end lever med en illusion af vilk&#229;rlig pr&#230;cision, der bare ikke findes. 

Du kan skabe en illusion af vilk&#229;rlig pr&#230;cision ved at sk&#230;re decimalerne af for at l&#248;se g&#229;den om 0.1 + 0.1 + 0.1 = 0.3! N&#229;r jeg laver prognoser over mit aktieafkast vil jeg have alle decimaler med. Tak. </body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2010-02-09T13:31:38Z</created-at>
    <id type="integer">158</id>
    <post-id type="NilClass">158</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Unit of Least Precision</title>
    <updated-at type="datetime">2010-02-10T08:04:27Z</updated-at>
  </post>
  <post>
    <body>Jeg skal udstille en SOAP WebService fra et et lagacy system. Det er en forholdsvis triviel proces med enkelte retninglinjer men bliver ofte til noget overengineered markv&#230;rk. Min tanke er at det m&#229; kunne g&#248;res p&#229; en let og clean m&#229;de. Efter min mening er begrebet service i forbindelse med IT er desv&#230;rre druknet i forretningprocesser og total mangle p&#229; vision.

Mine forbehold er enkle! Jeg gider ikke skrive en WSDL fil og jeg vil helst ikke compilere tusindvis af filer flere m&#229;neder f&#248;r jeg kender kravene til applikationen. Under normale forhold ville jeg v&#230;re dj&#230;vlens advokat n&#229;r det g&#230;lder SOA, SOAP, Webservices og andre d&#248;dstjerne teknologer. Jeg vil have en service orienteret arkitektur med l&#248;s kobling og bl&#248;d binding mellem komponenterne. 

Her er klasse med noget opdigtet funktionalitet.

&lt;pre&gt;
/**
 * Leagcy business rule
 */
public class Palindrome {
  public static boolean isPalindrome(String word) {
    int left = 0; // index of leftmost unchecked char
    int right = word.length() - 1; // index of the rightmost
    while (left &lt; right) { // continue until they reach center
      if (word.charAt(left) != word.charAt(right)) {
        return false; // if chars are different, finished
      }
      left++; // move left index toward the center
      right--; // move right index toward the center
    }
    return true; // if finished, all chars were same
  }
}
&lt;/pre&gt;

Andrew S. Tanenbaum bog om distribuerede systemer dukker svagt op i min erindring n&#229;r vi taler om server klient applikationer. Derfor f&#248;ler jeg det er vigtigt at pr&#230;cisere context. Det f&#248;rste perspektiv er fra leverand&#248;rens(supplier) synspunkt. Rigtig mange problemer opst&#229;r i forskellige opfattelse af distribuerede systemer og det kan v&#230;re sv&#230;rt over tid at skele mellem hvad der er forbruger og leverand&#248;r i forskellige forretningsomr&#229;der. Leverand&#248;r processer som har flere afh&#230;ngigheder fra andre under-leverand&#248;rer som agere forbruger skal snart omskrives. 

F&#248;rste step er at fremstille en service. Jeg kalder processen for BusinessService men i teorien kunne det v&#230;re hvilken slags forretnings regel eller dataplukning. For at spare taste slag bruger jeg Groovy til service interface. Det statiske metode kald til legacy kassen er verdens v&#230;rste smutter men s&#229;dan er det jo med legacy. 

&lt;pre&gt;
class BusinessService {
  boolean isPalindrome(String word) {
    Palindrome.isPalindrome(word)
  }
}
&lt;/pre&gt;

Dette service objekt skal nu omformes til et endpoint. Denne gang bruger jeg groovyWS til at tale SOAP. Bem&#230;rk navne-sammenfald i konstruktionen der invokere groovy's dynamiske newinstance metode. Objektet kalder jeg for BusinessServiceEndpoint. Grunden er at jeg forst&#229;r at en port p&#229; en maskine er et endpoint mens mange forst&#229;r alt muligt andet. M&#229;ske er jeg for logisk? Logisk er det ogs&#229; at man skal passe meget p&#229; sin service stak og ikke mindst r&#230;kkef&#248;lgen i classpath.

&lt;pre&gt;
  new WSServer(&quot;BusinessService&quot;, &quot;http://localhost:6900/BusinessService&quot;).start()
&lt;/pre&gt;

Det var serverens endpoint. WSDL filen specificere alle n&#248;dvendige forhold omkring hvilken muligheder man som WS forbruger kan opn&#229;. Man kan se WSDL filen live p&#229; url: http://localhost:6900/BusinessService?wsdl

Nu er det tid til at tage det store skridt til h&#248;jre for at lege forbruger(consumer) af webservice. Som klient modtager jeg en url der peger p&#229; et service endpoint. Dette b&#248;r v&#230;re den eneste kobling mellem leverand&#248;r og forbruger. Hvis man har brug for mere som fx, et kompilerer jar arkiv, eller andre artifakter er man bundet for h&#229;rdt sammen. leverand&#248;ren har det med at &#230;ndre i sin kontrakt og fjerne dermed grundlaget for alle forbrugere. L&#248;sningen er enkelt, en leverand&#248;r push'er successivt alle &#230;ndringer til sine forbruger. Eneste forhindring er at man som udstiller af services skal vide hvor mange forbruger man har hvilket totalt &#248;del&#230;gger service tanken. Og Tanenbaum vender sig. 

* SOA er som et autovaskeanl&#230;g, du kan ikke bruge det uden at vide alt. I morgen er vaskehallen fx kun 1m bred men heldigvis ringer tankpasseren rundt til alle med &#230;ndringer.

GroovyWS har en fin klient til Webservices. Klienten skal blot have endpoint og en classloader. Instansen kalder jeg proxy fordi den illustrere det objekt som ligger hos udbyderen. N&#229;r man kalder initalize generes alle de n&#248;dvendige stubs for dig og man kan derefter direkte invokere metoder gennem proxy'en. I dette tilf&#230;lde kalder jeg isPalindrome med argumentet otto.

&lt;pre&gt;
  def proxy = new WSClient(&quot;http://localhost:6900/BusinessService?wsdl&quot;, this.class.classLoader)
  proxy.initialize()
  println proxy.isPalindrome(&quot;otto&quot;) # true
&lt;/pre&gt;

Det fede er naturligvis at der foreg&#229;r en masse nedeunder som jeg ikke engang gider ta mig af. Men dette var ret nemt fordi jeg jo blot bruger samme teknologi p&#229; begge sider af ledningen.

Lad og pr&#248;ve at skifte hele servicestakken p&#229; forbruger siden med noget helt andet. I teorien vil leverand&#248;ren gerne ha at s&#229; mange s&#229; muligt benytter de udstillede services fra s&#229; mange platforme som muligt. Dette er en af de gode grunde til at man ikke skal lade sine EA kommer med alt for mange gode ideer n&#229;r de udvikler meget komplekset WSDL'er. Sikkerhed best&#229;r ikke kun af kompleksitet.

Ruby har en 'soap/wsdlDriver' indbygget man kan bruge til at tilg&#229; soap endpoints. Syntakstisk minder det noget om groovyWS og man operere ogs&#229; direkte p&#229; en proxy uden at t&#230;nke p&#229; at afkode WSDL filen manuelt. Evt kan man se metodernavnen i browseren for derefter at invokere dem. Bem&#230;rk at argumentet i ruby er en hash fremfor en typed parameter. Hvis servicestakken &#230;ndres kan man risikere at skulle bruge andre navne end arg0, arg1 osv. 

&lt;pre&gt;
  require 'soap/wsdlDriver'
  proxy = SOAP::WSDLDriverFactory.new(&quot;http://localhost:6900/BusinessService?wsdl&quot;)
  proxy.create_rpc_driver
  puts proxy.isPalindrome(&quot;arg0&quot; =&gt; &quot;jruby-yburj&quot;)
&lt;/pre&gt;

Indtil nu har vi kun k&#248;rt med SOAP version 1.1. M&#229;ske er det tid at udstille en soap service i version 1.2. En ESB kan nemt udstille services af begge versioner og det ville v&#230;re ret cool fremfor at en central admin bestemmer at der kun findes SOAP version 1.2. Ved en s&#229;dan fremgangsm&#229;de bliver man ramt af en alt for kraftig binding mellem endpoints og services og har voldsomme implikationer for alle forbrugerne.

GroovyWS er ikke klar til soap version 1.2 ud af boksen og det kr&#230;ver for mange omg&#229;elser s&#229; det er tid at skifte til Metro 2.0 for at udstille vores n&#230;ste service som sjovt nok ogs&#229; er palindrome. Legacy klassen er stadig den samme men service wrapperen er udskifte til en POJO java klasse med JAXB annotationer. 

Service endpoint interface(SEI). For ethvert defineret interface i WSDL filen kan man generer en SEI. Fra et Java perspektiv kan man sige at wsdl:porttype mapper lige over til en implementation med annotationen @webservice hvor hver operation defineret i wsdl mapper til en metode i SEI. 

Bem&#230;rk at SOAP 1.2 support is added til JAX-WS 2.2

&lt;pre&gt;
/** SOAP 1.2 WS service */
@WebService
@BindingType(value = &quot;http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/&quot;)
public class PalindromeService {
  @WebMethod
  public boolean isPalindrome(String word) throws PalindromeServiceException {
    if (word == null || word.length() &lt; 2) {
throw new PalindromeServiceException(&quot;No word added!&quot;, &quot;Must have a word with length over 2 chars.&quot;);
    }
    return Palindrome.isPalindrome(word);
  }
}
&lt;/pre&gt;

Nu er den samme legacy kode alts&#229; d&#230;kket af flere service wrapper med forskellige egenskaber. Jeg kan bedst li Java klasse uden &quot;det tredie sprog&quot; annotationer men okey, det er bedre en r&#229; xml konfiguration. Her er tilf&#248;jet en eksplicit exception og et par valideringsregler. Nu kan vi g&#229; direkte til endpoint som ogs&#229; er en Java klasse som kalder et JAX-WS endpoint og publicer en ny service.

&lt;pre&gt;
public class PalindromeServiceEndpoint {
  public static void main(String[] args) throws Exception {
    Endpoint.publish(&quot;http://localhost:8080/business/ispalindrome&quot;, new PalindromeService());
  }
}
&lt;/pre&gt;

Grunden til at dette er i Java fremfor Groovy er at jeg ikke vil lade JAXB binde superclass metoder. En groovy klasse har et metaClass interface og det kan JAXB ikke h&#229;ndter. Dette kan afhj&#230;lpes ved brug af af en ekstra annotation. Det virker dog ikke s&#230;rligt robust p&#229; den nye metro distribution og jeg synes det forurener koden at man skal fort&#230;lle hvilken objekter der er root.

Nuvel, nu findes en service udbyder som har publiseret en service i SOAP version 1.2. Men beh&#248;ver man ikke vide om den. Vel? Det er nu vigtig at pointere at jeg har kaldt denne post &quot;dynamic&quot; fordi jeg ikke vil tilg&#229; services med en bin&#230;r afh&#230;ngighed. Det er ikke hensigten at modtage en *jar fil fra serviceudbyderen som jeg skal l&#230;gge i min classpath og kode imod fordi jeg ikke vil rammes af namespace &#230;ndringer overalt i min kodebase n&#229;r n&#230;ste version kommer.

Mit udgangspunkt er at alle i teorien kan benytte denne service ligegyldigt hvilken platform og hvilken teknologi de fortr&#230;kker. Jeg vil betragte denne service(endpoint) som et sted at starte og jeg h&#229;ber at wsdl filen fort&#230;ller mig om de n&#230;ste skridt jeg kan tage.

Jeg h&#248;re til den nysgerrige type og vil fors&#248;ge at forbruge denne service med med udgangspunkt i SOAP beskeden selv, alts&#229; &quot;the Envelope&quot;. I konvolutten ligger information om sikkerhed, transaktioner og andre, for mig, ligegyldige ting.

Klient koden til en soap 1.2 besked med standart Java 1.6 indbygende features.

&lt;pre&gt;
QName serviceName = new QName(service_namespace, service_name);
QName servicePort = new QName(service_namespace, service_port);

// Create a service and add at least one port to it.
Service service = Service.create(serviceName);
service.addPort(servicePort, SOAPBinding.SOAP12HTTP_BINDING, service_endpoint);

// Create a Dispatch instance from a service.
Dispatch&lt;SOAPMessage&gt; dispatch = service.createDispatch(servicePort, SOAPMessage.class, Service.Mode.MESSAGE);

// compose a request message
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);

// Create a message with the SOAPPART.
SOAPMessage request = mf.createMessage();
SOAPPart part = request.getSOAPPart();

// Obtain the SOAPEnvelope and header and body elements.
SOAPEnvelope env = part.getEnvelope();
SOAPHeader header = env.getHeader();
SOAPBody body = env.getBody();

// Construct the message payload, ant binding type value
SOAPElement operation = body.addChildElement(business_method, &quot;ns1&quot;, service_namespace);
SOAPElement value = operation.addChildElement(&quot;arg0&quot;);
value.addTextNode(business_args);
request.saveChanges();

// Invoke the service endpoint.
SOAPMessage o = dispatch.invoke(request);

// Get reply content
Source sc = o.getSOAPPart().getContent();
&lt;/pre&gt;

I dette eksempel var en IDE n&#248;dvendig b&#229;de fordi der er alt for meget kode og fordi JAXB bibliotekerne i denne EA version er noget forskellige fra den tidligere. Et par ting der er v&#230;rd at l&#230;gge m&#230;rke til: Jeg m&#229; bygge et soap xml request p&#229; Java's kedelige set get'er metodik. Ydermere, tiltrods for at jeg selv har konstrueret denne service m&#229; jeg ind i wsdl filer for at finde navnet hvori input best&#229;r, isPalindrome(String word) er alts&#229; blevet til en r&#230;kke af inputparameter med fortl&#248;bende arg0, arg1 osv. V&#230;k er det fine proxy objekt med stub'ens metode navne og hele interaktionen er alt for lowlevel for min smag. Og man bliver nu n&#248;dt til at bruge en Transformer for at MOF'e til et model objekt.

Klient koden til en soap 1.2 besked med Java 1.6 + Apache CXF.

&lt;pre&gt;
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();

URL serviceEnpoint = new URL(service_endpoint);
QName serviceName = new QName(service_namespace, service_name);
QName servicePort = new QName(service_namespace, service_port);

// create proxy and genered classes from wsdl
Client proxy = dcf.createClient(serviceEnpoint, serviceName, Thread.currentThread().getContextClassLoader(), servicePort);

// call method on proxy
Object[] res = proxy.invoke(business_method, business_args);

// use the new genered class in this classloader
Object palindrome = Thread.currentThread().getContextClassLoader().loadClass(business_class).newInstance();

p(palindrome.getClass());
p(palindrome.getClass().getMethods() );
&lt;/pre&gt;

Ahhh, noget mindre kode men stadig langt mere verbose en klienten med groovyWS. Men jeg fik min dynamiske proxy som svare til objektet p&#229; den anden side og det er muligt at kalde metoder direkte p&#229; proxy objektet. Hvor kom klient objektet fra? Tja de blev generet af wsgen udfra wsdl filen p&#229; samme m&#229;de som man ville g&#248;re p&#229; normal vis blot runtime. Ved den traditionelle metoder vil model v&#230;re dekoreret med referacer fra wsgen p&#229; compiletidspunkt hvor man med denne metoder f&#248;rst kender service objekterne runtime, dvs at ens model er uden reference til de generede service objekter.

Hvilket p&#229;pege et helt nyt sp&#248;rgsm&#229;l. Vil jeg arbejde p&#229; med en masse generede filer fra WSDL import eller vil jeg mappe en masse v&#230;rdier i wrapper klasser? Sjovt nok er der ikke en perfekt l&#248;sning p&#229; nogen af disse problemer.

N&#229;r et projekt i start fasen beslutter at bruge SOA/Webservices er det ikke fragmenteringen af service der kommer i f&#248;rste r&#230;kke. En regel siger at gamle udk&#248;rte lagacy systemer, og forretningens for&#230;ldede tanke m&#248;nstre, specificere det nye service layout. Lad mig g&#230;tte, dine services er store WS beskeder og det er kun n&#248;dvendigt at kalde ca 5 service for at udf&#248;re alle forretnings processer.

Hvis du kan svare ja til forg&#229;ende s&#230;tning har du en h&#229;rd kobling i dit system. Din udviklingsgruppe generet en domain model ud fra WSDL'er og der findes tusindvis af referencer til dine propriet&#230;re domain model. Den hurtige siger: vi har en rig domain model med et mapping layer! Okey, fint men samme problematik.

S&#229; hvordan opn&#229;r man en l&#248;s kobling med SOA og WebServices?

Kom til at t&#230;nke p&#229; at man ogs&#229; kunne omskrive legacy klasse til groovy.. 

&lt;pre&gt;
  def isPalindrome(String word)  {  word == word.reverse() }
&lt;/pre&gt;

</body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2009-09-16T07:45:30Z</created-at>
    <id type="integer">147</id>
    <post-id type="NilClass">147</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Dymamic SOAP</title>
    <updated-at type="datetime">2009-10-14T11:58:59Z</updated-at>
  </post>
  <post>
    <body>Java er en superst&#230;rk platform. Java som programmeringssprog er derimod ved at v&#230;re rigtig godt slidt. Sun er klar over at deres bedste &#8220;cash cow&#8221; er ved at l&#248;be t&#248;r for fodre, m&#229;ske derfor de kalder den JDK7 og ikke Java7.

Men et er sikkert, Java&#8217;s &#248;kosystem er en attraktiv platform og den vil overleve i bedste velg&#229;ende. P&#229; denne solide platform kan hostes en masse nye og smarte sprogvariationer som alle har det tilf&#230;lles at de kan eksekveres i en Java Virtuel Maskine(JVM). Disse nye sprog &#229;bner op for en masse nye muligheder for v&#230;kst mens tidligere investering i platform og infrastruktur kan bevares.

Nu er det muligt at v&#230;lge platform og programmeringssprog uafh&#230;ngigt af hinanden og man kan lade applikationens specielle krav om ydelse, hastighed eller samtidighed indg&#229; i valg af programmeringssprog.

# Development speed (websites, business)
# Parallel computing (mathematical finance)
# High volumen applications (twitter, flickr, finance)

Ovenik&#248;bet kan de forskellige programmeringssprog kombineres, fx kan man bruge ruby for at speede den daglige udvikling og benytte jruby til at overf&#248;re ruby koden til JVM&#8217;en for at hente en ydelsesm&#230;ssige fordel. Ruby on Rails applikationer kan ogs&#229; bruges som glaslagsapplikationer der ikke kr&#230;ver &#230;ndringer af en eksisterende Java-baserede infrastruktur. Produktive teams kan bruge denne fremgansm&#229;de for at minimere teknisk &quot;friktion&quot; i processerne men ogs&#229; for at opn&#229; de ydelsesm&#230;ssige fordele af JVM'en. Twtter applikationer benytter RubyOnRails til UI og Scala til de mest betydningsfulde programdele for at kunne lade dem skalere til maximum. De enkelte dele er l&#248;s koblede og kan skaleres og deployes efter specielle egenskaber. 

Enhvert moderne programmeringssprog b&#248;r som minimum have en read-eval-print loop (REPL) hvori man kan skrive evolutionary kode. Om sproget er dynamiske eller statisk, objektorienteret eller funktionelt betyder ikke s&#229; meget men de b&#248;r v&#230;re udformet som scriptsprog. 

Herefter l&#248;ber vandende hver sin vej hvad ang&#229;r enkelthed og indl&#230;ringskurve. Nogle af de nye sprog tager udgangspunkt i enkelthed og at &quot;de g&#248;r som man forventer&quot; mens andre er designede til at undg&#229; sideeffekter for samtidig eksekvering mens andre igen underst&#248;tter fx metaprogramming.

Ting man kunne klassificere et sprog efter:

# Interoperability: Hvordan sameksistere med Java platformen.
# Programmringsparadigme: Objekt eller funktionel model.
# Trends: Hvilken core egenskab har programmeringssproget.
# Integrated: Hvordan integreres med XML, SQL, DSL osv.
# Stability: Hvordan er stabiliteten.
# Performance: Hvordan er hastigheden i programmeringssproget.
# Adoption: Hvor stejl er indl&#230;ringskurven
# Tool support: Hvad med IDE 's, kode d&#230;kning osv.
# Deployment : Hvordan fungere det med build, deploy og udrulning

En af de sjove ting som skiller sig ud, er tanken om at bidrage med nye ideer og former til programm&#248;rene. Java verden lever med den absurde tanke at framework l&#248;ser alle dine problemer uden man beh&#248;ver at forst&#229; alle tankerne bagved enhver problematik. Heldigvis finder der en form for udvikling sted. Nogle af de nye &#8220;ideer&#8221; i de enkelt sprog kan v&#230;re af stor v&#230;rdi for udviklingsprojekterne eller/og selve platformen.

JRuby

JRuby er nok det mest popul&#230;re alternativ til et JVM sprog. JRuby drives i h&#248;j grad af interesse i Ruby og Ruby on Rails milj&#248;et. Ruby's programmeringsmodel og objektmodel er lidt anderledes end Java. Det er nemt at kalde Jruby fra Java og ogs&#229; omvend gennem JSR 223 scripting interface. JRuby kan kompiler ruby kode til Java-bytecode.

Ruby&#8217;s objekt model underst&#248;tter mixin moduler som har samme adf&#230;rd som Java interfaces men med implementation. JRuby har ogs&#229; closures, en meget &#248;nsket funktion som der ikke er med i JDK7. Med closures kan man opn&#229; en r&#230;kke functional-style iterative operationer som mapping, filtering, og reducing/folding. Ruby har &#229;bne klasser gennem virtual class og man kan tilf&#248;re en metode til en enkelt instans af en klasse. Ruby underst&#248;tter ikke funktionel programmering og giver ikke ekstra til samtidigheds problematikken. Ruby er dynamisk og kan udnytte metaprogramming faciliteter.

Ruby tillader nem adgang til XML og databaser. Ruby on Rails er legendarisk for at forbedre produktiviteten i web portaler og lettere applikationer. Ruby er et af de bedste sprog til definition af &quot;Intern DSL&#8221;. JRuby er stabilt og meget brugt i produktionsmilj&#248; og JRuby menes at v&#230;re den beste performing ruby platform, bedre end selv Metz native. Ruby syntaks er under forandringer med version 1.9 men migration ikke er nogen udfordring for et &#229;bent sprog.

Ruby er let at l&#230;re, superb til undervisning og studier. Ruby vil udbygge ens viden om objektorienteret tankgang. Anvendelse af avancerede teknikker s&#229;som metaprogramming kr&#230;ve dog lidt mere tid. Rubys specelle idioms er lette at forst&#229; og er ret veldokumenteret. Ruby oplever en enorm v&#230;kst i nye v&#230;rkt&#248;jer fra fx IntelliJ, NetBeans og Eclipse der alle arbejder p&#229; Ruby support og JRuby brugere kan udnytte mange eksisterende Java-v&#230;rkt&#248;jer. Kode analyse og test v&#230;rkt&#248;jer (TDD and BDD) er langt bedre end Java's. JRuby applikationer, og selv Ruby on Rails applikationer, kan indpakkes og deploy som jar eller war arkiver og kr&#230;ver ikke &#230;ndringer af den eksisterende Java-baserede infrastruktur. JRuby er java-bytecode p&#229; runtime og kan derfor debugges med JMX osv.

Groovy

Groovy er et objektorienteret sprog for JVM'en og er et godt alternativ til Java sproget. Groovy er designet specielt til interoperabilitet med Java. Det vil appellere til teams, der &#248;nsker en dynamisk-skrevet sprog, der er t&#230;ttere p&#229; Java end Ruby. Med web frameworket grails, har man en kombination som er sammenlignelig med Ruby on Rails. Groovy er dynamisk typed med egenskaber som ellers findes i python, ruby, perl og smaltalk. Groovy kan bruges som et scriptsprog for Java med en Java li &quot;curly bracket&quot; syntaks der bliver dynamisk kompileret til bytecode og fungere gnidningsfrit med anden Java kode og Java biblioteker. Groovy kompilere kan generer standard bytecode, alts&#229; class filer som kan bruges af rene Java projekter. Det mest Java kode er ogs&#229; valid groovy kode. Groovy sproget er stor set et subset af Java. Faktisk kan man omd&#248;be en .java fil til .groovy fil og den vil med f&#229; undtagelser virker.

Groovy har en r&#230;kke supercool features som Java ikke kan h&#229;ndterer. Indl&#230;ringkurven for Java programm&#248;rer er n&#230;sten nul, eller nil om man vil. Java folk kan uden videre g&#229; i gang med at l&#230;re en m&#230;ngde nye ting som g&#248;r hverdagen meget nemmere. Det er b&#229;de statiske og dynamiske syntaks, fx metode definitionen def, closures, operator, overloading og native list og associative arrays, maps. Groovy kan g&#248;res langt mere kompakt end Java.

Groovy supportere en m&#230;ngde forskellige integrations komponenter som markup, XML, dom der kan manipulere mange typer af hetrogene data struktureret p&#229; en koncis m&#229;de. Groovy er fuldt ud stabilt og alle nye landvindinger synes ikke at v&#230;re et problem idet sprogkernen ligger fast og nye ting ber&#248;re kun bibliotekerne. Clojure ogs&#229; har de f&#230;rreste kendte produktion implementeringer. Performance er i top men kr&#230;ver et udviklingsteam som kan lide Lisp. Hvis dette tilf&#230;ldet kan projektledelsen regne med h&#248;j produktivitet. Lisp er kendt for at v&#230;re simpelt sprog, hvor den egentlige l&#230;ring kommer i at forst&#229;, hvordan man bruger det effektivt!

Scala

Scala er et statisk-skrevet sprog som underst&#248;tter en forbedret objekt model med fuld mixin mekanisme og fuld st&#248;tte til funktionel programmering. Scala navnet er en sammentr&#230;kning af &quot;skalerbare sprog&quot;. Syntaksen ligner en krydsning mellem Ruby (metode definitioner starter med def) og Java (kr&#248;llede parenteser). Type inferencing og andre syntaktisk konventioner betydeligt reducere &quot;cluuter&quot;, s&#229;som antallet af eksplicitte type erkl&#230;ringer &quot;annotationer&quot; i forhold til Java. Scala syntaks er meget kortfattet, undertiden endnu mere end ruby! Scala og Java passer godt samme pga &#8220;static typing&#8221; og &#8220;closed&#8221; klasser. Det er trivielt at importere og bruger Java API. Direkte API-kald fra Java til Scala underst&#248;ttes ogs&#229;. Udvikleren har behov for at vide, hvordan navnene p&#229; Scala metoder kodning i byte kode. fx Scala metoder kan have &quot;operat&#248;r&quot; navne, som &quot;+&quot;. I byte-kode, er det &quot;$ plus&quot;.

Scala's objekt model extends Java's model med traits, som er flexble mixin composition, samme som moduler i ruby. Traits opf&#248;rer sig som interfaces med implementation. Scala objekt model bidrager med avancerede funktioner til opbygning af &quot;skalerbare&#8221; applikationer. Scala underst&#248;tter funktionel programmering til JVM, herunder first-class funktion og closures. Andre aspekter af funktionel programmering, som immutable variabler uden side-effekter. Dog er Scala ikke et rent funktionelt sprog.

Funktionel programmering er meget effektiv strategi for at skrive treads-safe-programmer der kan h&#229;ndtere mange samtidige processer. Scala benytter Actor Pattern fra Erlang der er en besked-baserede concurrency model. Actor modellen er nok den bedste general-purpose tilgang til concurrency med multi-threaded processer som skal eksekvere samtidigt. Scala har meget god st&#248;tte til opbygning af interne DSL 's, men det er ikke helt s&#229; god som Ruby. Scala har et &#8220;combinator parser&#8221; bibliotek der g&#248;r, at man kan konstruere eksterne DSL forholdsvis let. Scala tilbyder ogs&#229; p&#229; nogle innovative API 's for XML forarbejdning og Swing udvikling.

Scala er over 5 &#229;r gamle og er meget stabilt. API og syntaks udvikle sig men alle &#230;ndringer sker i biblioteker og ikke det sproget grammatik. Der er nogle velkendte &#8220;big load&#8221; applikationer fx Twitter der benytter Scala for high performance og volumen.

Scala giver sammenlignelige resultater til Java, da det er meget t&#230;t &quot;strukturelt&quot; til Java-kode p&#229; byte-kode niveau. Derfor Scala kan udnytte JVM optimeringer, der ikke er tilg&#230;ngelige til dynamisk-typed sprog. Men Scala vil ogs&#229; drage fordel af planlagte forbedringer for at st&#248;tte dynamisk-skrevet sprog, s&#229;som hale-call optimeringer. Derfor har Scala sandsynligvis en marginalt bedre ydeevne end JRuby. Hvis det er sandt, Scala kan v&#230;re mere tiltr&#230;kkende end JRuby som generelt sprog hvor udf&#248;relsen er kritisk.

Scala er sv&#230;rere at l&#230;re end JRuby fordi det er et mere omfattende sprog. Ikke kun pga af en sofistikeret objekt model men ogs&#229; fordi der underst&#248;ttes funktionel programmering, type inferencing osv. Efter min mening er den ekstra indsats vil blive bel&#248;nnet med en h&#248;jere produktivitet. Ogs&#229;, fordi det er t&#230;ttere p&#229; Java end JRuby og Clojure vil nye brugere vil v&#230;re i stand til at begynde at bruge det hurtigt som et &quot;bedre objektorienterede Java&quot;, mens de forts&#230;tter med at l&#230;re de mere avancerede funktioner, som f.eks funktionel programmering, som vil fremskynde deres produktivitet p&#229; lang sigt.

Scala IDE findes ikke endnu men der er gode plugins. Maven og ANT er almindeligt anvendt som bygge redskab til Scala applikationer ligesom der er adskillige fremragende TDD og BDD biblioteker tilg&#230;ngelige. Scala applikationer pakkets og installeres ligesom Java-programmer. En Scala runtime jar er p&#229;kr&#230;vet.

Lift er et helt nyt imponerede og elegant framework til webenabling af h&#248;jtydende applikationer. Lift er bygget omkring vigtigheden af sikkerhed, vedligehold, skalerbart og h&#248;j ydeevne. Derudover har Lift stor fokus p&#229; h&#248;j udviklingsproduktivitet. Lift l&#229;ner fra de bedste eksisterede frameworks som fx. Seaside og andre egenskaber fra som time to market, CRUD, templates osv. Lift er skrevet i Scala kan man benytte alle Java's API mens deployment og udrulning er lig Java.

Clojure

Clojure er den af de nye sprogversioner der mindst minder om Java. Sproget bliver kaldt Lisp 2 p&#229; grund af sin lisp syntaks og innovative &quot;programmerings model&quot;. Clojure er et rent functional sprog uden side effekter. Der findes kun immutable data strukture. Clojure har dynamisk kode fortolkning men er meget hurtigt.

Det er den nyskabende og sp&#230;ndende nye JVM sprog syntaks som g&#248;r Clojure interessant for mange mennesker. Clojure interop med Java-kode, men skal bliver betragtet som et funktionel programmeringsprog og supportere ikke object-orienteret programming. I stedet beror Clojure p&#229; mekanismer som multi-metoder og makroer til at behandle design problemer.

Clojure er bygget med transaktions memory der bruger en database-stil transaktion styring til samtidige &#230;ndringer af in-memory &#230;ndringer. STM. Clojure har ogs&#229; andre innovative metoder til at st&#248;tte &quot;principfast&quot; modifikation af mutable data samtidig med at brugen af immutable data. Disse funktioner med STM er grundlaget for Clojure's tilgang til robust concurrency. Clojure har gennemf&#248;rt flere kompiler optimeringer der er vigtige for funktionel programmering, s&#229;som optimering &#8220;tail call recursion&#8221;.

Clojure kan nemt sameksistere med Java men det er sv&#230;rt at kalde fra Clojure til Java, der m&#229; man lave proxyies p&#229; Clojure siden for at generere den bytecode som Java kr&#230;ver. Clojure st&#248;rste bedrift er at bringe functional programming med en smart List syntaks til JVM&#8217;en med multi-methods, metaprogramming og sikker concurrency. Clojure's kortfattede syntaks og indbygget i biblioteker g&#248;re forarbejdning af XML kortfattede og effektivt ligesom DSL st&#248;ttes af lisp mekanismer.

Clojure er den nyeste scriptsprog p&#229; JVM&#8217;en men er fuldt ud stabilt og alle nye landvindinger synes ikke at v&#230;re et problem idet sprogkernen ligger fast og nye ting ber&#248;re kun bibliotekerne. Clojure ogs&#229; har de f&#230;rreste kendte produktion implementeringer. Performents er i top men kr&#230;ver et udviklingsteam som kan lide Lisp. Hvis dette tilf&#230;ldet kan projektledelsen regne med h&#248;j produktivitet. Lisp er kendt for at v&#230;re simpelt sprog, hvor den egentlige l&#230;ring kommer i at forst&#229;, hvordan man bruger det effektivt!

Mange Java-v&#230;rkt&#248;jer kan anvendes sammen med Clojure men typisk arbejder man med Emacs som har fremragende lisp st&#248;tte. Clojure deployering synes at v&#230;re s&#229; ligetil som for de andre sprog. En Clojure runtime jar er p&#229;kr&#230;vet.


Lidt fra hver

Alle sprog kan let kaldes fra eksistere Java kode men det er lidt mere omst&#230;ndig at kalde fra de respektive sprog til Java. T&#230;ttes p&#229; er Scala med en objekt model der ser ud som ruby/java layout. Naturligivs g&#248;r ruby&#8217;s dynamiske giver sproget karakter. Begge extends Java objekt model med mixin komposition gennem modules og traits. Clojure er helt anderledes, med en v&#230;gt p&#229; funktionel programmering og ikke direkte st&#248;tte til objektorienteret programmering.

JRuby bringer produktivitet og effekter af et dynamisk-skrevet sprog til JVM, ligesom Groovy. JRuby har ogs&#229; nogle funktionelle idiomer. Scala og Clojure har fuld st&#248;tte til funktionel programmering. Scala har en komplet Actor model for concurrency implementeret som bibliotek. Clojure har software transaktionsh&#229;ndtering af hukommelse og andre nyskabelser som ganranteret robust samtidighed i applikationer. JRuby og Ruby ikke tilf&#248;je noget specifikt for concurrency. JRuby og Ruby er specielt god til at skrive interne DSL's. Scala er ogs&#229; meget god og Clojure har fordelene fra lisp's til DSL oprettelse.

Alle sprog implementeringer er af h&#248;j kvalitet med Scala som den mest modne mens JRuby er mest adopteret i produktion. Performance b&#248;r v&#230;re sammenlignelige for alle, men JRuby og Clojure har at g&#248;re med en vis ineffektivitet ved at eksekvere dynamiske sprog p&#229; JVM. Undg&#229; &quot;tidligt optimering&quot;, n&#229;r de skal v&#230;lge et nyt sprog. Ofte er team produktivitet og &quot;time to market&quot; langt vigtigere end r&#229; ydeevne.

Scala har den laveste barriere for adoption fordi det er det sprog, der mest ligner Java &quot;filosofisk&quot;, med statisk typing og v&#230;gt p&#229; objektorienteret programmering. Nye tilkommer kan starte med Scala som et &quot;bedre Java&quot; og gradvist l&#230;re de avancerede funktioner som mixin og funktionel programmering.

Scala vil appellere til de fleste teams der foretr&#230;kker statisk-skrevet sprog men alligevel &#248;nsker nogle af fordelene ved dynamisk-skrevet sprog, og gerne en kortfattet syntaks. Men Scala er det mest komplekse af de tre sprog, mens Clojure kr&#230;ver det st&#248;rste begrebsm&#230;ssige spring fra Java.

Clojure vil appellere til hold som er villige til at udforske mere gennemgribende afvigelser fra det de g&#248;r nu. Implementering er nemt med alle tre sprog. Scala er som Java hvor man kompilere koden til class-filer. JRuby og Clojure koden kan fortolkes p&#229; k&#248;rselstidspunktet eller blive kompileret.

Alle udviklingsteams der vil noget mere kan drage fordel af et eller flere moderne sprog men alligevel fuldt ud udnytte de eksisterende investeringer i Java platform. Efter min mening er Groovy er det sejeste sprog ovenp&#229; Java og tilbyder en lang r&#230;kke cool stuff.

Scala er m&#229;ske det nemmeste at vende sig til. JRuby bringer den pulserende Ruby verden til JVM. Clojure tilbyder den mest innovative tilgang til JVM'en.

Men der findes et par interessante variationer til:

# Fan &#8211; En hybrid af den objektorienterede og funktionelle verden. Mange lighedspunkter med Scala, f&#248;les ligesom et scripting-sprog. Har en helt anden indgangsvinkel til deling af state og l&#229;sning af f&#230;lles resources. De fleste andre performance sprog undg&#229;r sideeffekter ved at ikke dele state overhoved men FAN er mere som Java hvor flere processer kan dele resourcer og som f&#248;lge deraf m&#229; man l&#229;se adgang til dissse resourcer. FAN har Mixins og protype, functions og closures. FAN er hverken statisk eller dynamisk typed, men et sted derimellem. Sproget er ideelt for deklarativ programmering.
# Ioke &#8211; Et innovativt sprog udviklet af Ola Bini med k&#230;mpe potentiale. Ioke er et st&#230;rkt typed dynamisk, prototype baseret objektorienterede sprog. Ioke er bygget med indflydelse fra er Io, Smalltalk, Self, Ruby og Lisp. Sproget eksekveres p&#229; en JVM men Ola regner med at kompilere det til JavaScript V8 inden l&#230;nge. Sproget er specielt udformet til at kunne h&#229;ndtere &#8220;Intern DSL&#8221;. Programringssproget skal komme mindst muligt i vejen men ogs&#229; v&#230;re kraftfuldt nok til at udf&#248;re opgaver p&#229; h&#248;jt niveau. Nogle vil m&#229;ske finde makro-systemet vanvittigt og Ioke er sikkert for udfordrende for gennemsnittet af Java udviklere.
# Fortress &#8211; Et sprog t&#230;nkt som en erstatning for h&#248;jperformante FORTRAN til industrielle og akademiske &quot;number crunching&quot;. og videnskablig ingeni&#248;rkunst. Fortress ligner mest Scala Standard ML og Haskell. Sproget er designet til parallelitet med rig funktionalitet i biblioteker.

</body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2009-04-05T23:25:05Z</created-at>
    <id type="integer">138</id>
    <post-id type="NilClass">138</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Adopting JVM languages</title>
    <updated-at type="datetime">2009-04-10T23:17:29Z</updated-at>
  </post>
  <post>
    <body>Titlen p&#229; denne post har jeg snuppet fra et &#8221;white paper&#8221; om hastighedsoptimeringer i forskellige J2e applikationsserverer. For nogle &#229;r tilbage stod den helt store kamp p&#229; applikations markedet mellem ret enkelte egenskaber s&#229;som hastighed, kapacitet eller robusthed. 

Denne gang har jeg kun fokus p&#229; hastighed og specielt en applikationsserver har fors&#248;gt at markere sig som den absolut hurtigste. Under udviklingen nedsatte de nogle gruppe som udelukkende koncentrerede om at finde og afhj&#230;lpe hotspots for at finde yderligere hastighed. Under denne arbejdsindsats fandt de p&#229; mange tricks og metoder man kan g&#248;re for at optimere b&#229;de selve serveren men ogs&#229; i de applikationer som hostes af serveren. 

Konklusionerne er omfattende og komplekst men en enkelt tese munder ud i denne s&#230;tning: &#8221;Det koster mere at skabe en ny instans af en klasse, end det koster at have en instans og lave et antal kopier.&#8221;

Det konkredte problem er at jeg har et &#8221;Command Pattern&#8221; der har indkapslet et beregningsmodul. En hver beregning er isoleret og kan leve uden sideeffekter eller delt hukommelse under afvikling. Det uheldige er at beregningerne er koblede gennem et lag med serialisering/deserialisering. Som serialisering tool er valgt XMLBeans og mere end 95 procent af tiden g&#229;r med at instantiere XMLBeans objekter. 

Det er ikke et problem jeg vil l&#248;se ved at konstruere en ny applikationsserver men blot bruge samme analogi. Jeg har med succes implementering metoden flere gange og fundet betragtelige hastighedsoptimeringer. 

Hemmeligheden er hotspot compileren. Jeg vil ha hotspot til at clone objekter fremfor at new objekter. Metoden provokere hotspot til at lave effektive genveje melle bytecoden og basic CPU instruktioner. 

&lt;pre&gt;
/**
 * Static references optimizer
 * @see http://en.wikipedia.org/wiki/Java_bytecode
 */
class StaticReferencesOptimizer {
    private static XMLBean xmlbean = new XMLBeansDummey.create \AllBeans();
}
&lt;/pre&gt;

Ved applikations start vil disse notificeret beans blive instantieret og ved service kald vil compileren blot lave en kopi. Millionvis af kopier med 90 til 95 procent bedre hastighed end ved at lave nye instanser. Det var alt. Alle de XML beans som skal benyttes skal ind i s&#229;dan en klasse i en statisk kontekst og den hastighedsoptimering du kan opn&#229; ved s&#229; simpelt indgreb vil overraske dig. 

Selv om dette trick er utroligt enkelt er det langt fra alle mainstream Java programm&#248;rer som forst&#229;r de mekanismer som sker i hotspot compileren. Og heldigvis for det. Fra Java's perspektiv ses en klasse som ikke har referencer til eller fra andre klasser. Det mest normale er at en novice programm&#248;r sletter filen. 

Her kommer disciplin og dokumentation ind i billedet men det er en anden sag. 


</body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2009-02-01T04:38:56Z</created-at>
    <id type="integer">133</id>
    <post-id type="NilClass">133</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Static References Optimizer</title>
    <updated-at type="datetime">2009-02-01T08:08:52Z</updated-at>
  </post>
  <post>
    <body>Jeg har to problemer! Jeg vil kunne tilf&#248;re nye regler og undtagelser dynamisk i en process. Min kode, eller notation skal v&#230;re sprogneutral og den skal uden videre kunne l&#230;ses af forretningskyndige.   

Dette er et par ydmyg krav og opgaven er at overf&#248;re policer fra et system til et andet. Konverteringsprocessen l&#248;ber over flere dage og undervejs vil der komme undtagelser p&#229; enkelte policer og nye forretningsregler vil opst&#229;. Det er ikke en option at stoppe, restarte eller deploye applikationen igen for at realisere evt nye regler.  

Jeg har valgt at isolere en process omkring en pensions-regel p&#229; laveste niveau. En pension kan best&#229; af dusinvis af disse niveauer og en samling af dem udg&#248;r en fuld pension.  

Jeg tager udspring en den eksisterende kode. Det kan v&#230;re Java, .NET eller andre sprog som er konstrueret i samme programmering model.   

&lt;pre&gt;
DummyPolice police = new DummyPolice();
PoliceLevel level = new PoliceLevel();
level.setPolice(&#8220;150364xxxx&#8221;);
level.setGrundlag(&#8220;omregning&#8221;);
level.setProcent(3);
level.setGrundform(212);
level.setYdelse(123.340,25);
police.add(level);
&lt;/pre&gt;

Udviklere fra den dynamiske eller funktionelle verden er ikke imponeret. En af de f&#248;rste ting man kunne fornemme er en h&#248;j grad af syntaktisk st&#248;j. I denne situation findes to slags st&#248;j, un&#248;dvendige forstyrrende elementer, som parenteser, semikolon og lodret skrivemaskineapostrof/tegns&#230;tningsapostrof, og en del repeterende kode som fx &#8220;set&#8221;. 

&lt;pre&gt;
level.police &#8220;150364xxxx&#8221;
level.grundlag &#8220;omregning&#8221;
level.procent 3 
level.grundform 212 
level.ydelse 123.340,25
&lt;/pre&gt;

Hvordan skeler man mellem &#8220;set&#8221; kontra &#8220;get&#8221; metode signaturer. En &#8220;set&#8221; metode modtager input hvorimod en get metode afgiver output!  Hvordan bestemmes hvilken type som bliver overf&#248;rt i beskeden mellem objekterne? N&#229;r man arbejder med dynamiske sprog er en af de f&#248;rste ting man bem&#230;rker og s&#230;tter pris p&#229;, den mindre betydning som typer udg&#248;r. Med mindre systemet fejler er man faktisk ligeglad. Fx police identifikator er en integer, biginteger eller en streng n&#229;r man som her indf&#248;re &#8220;xxx&#8221; som erstatning for de 4 sidste tal. Hvis man vil have en numerisk v&#230;rdi skulle &#8220;xxxx&#8221; udskiftes med &#8220;0000&#8221;.    

Denne kode er en Intern DSL hovedsagligt opbygget gennem &#8220;DSL Method Chaining&#8221; med en tydelig kontekst(DSL Context). Konteksten er en police p&#229; laveste niveau. Det betyder at n&#229;r linjen &#8220;procent 3&#8221; eksekveres er det af en regel p&#229; et police niveau. 

&lt;pre&gt;
police 150364xxxx
grundlag omregning
procent 3
grundform 212
ydelse 123.340,25
&lt;/pre&gt;

Ved denne transformation har jeg nu noget business like kode som forretningens domain eksperter kan fortolke. Det er sprog neutralt og fungere som en pensions DSL input. Nu mangler jeg blot at skrive selve DSL fortolker koden, men det vil jeg ikke komme ind p&#229; i denne post.  

De yder omst&#230;ndigheder g&#248;r at dette skal eksekveres p&#229; en JVM og med Java SE kan det ikke lade sig g&#248;re. Med Java&#8217;s Scripting API JSR223 kan det lade sig g&#248;re. 

JSR223

Scripting API&#8217;et g&#248;r det muligt at eksekvere mange former script-sprog p&#229; Java platformen. Jeg gider ikke fort&#230;lle om de sm&#229; detaljer da frameworket er ganske lille og super enkelt. Java SE 6 indeholder en javascript-engine baseret p&#229; Rhino og det betyder at man kan fortolke dynamisk javascript i Java koden uden at addere ekstra jars. 

Hvorfor vil man eksekvere script kode internt i Java kode? 

* Java mangler en dynamiske tilgang
* Man kan skabe nye variabler uden at definere en type, man kan skifte type undervejs, typekonvertering sker i mange tilf&#230;lde helt automatisk. 
* Man kan edittere kode og eksekvere, uden brug af rekompilering.
* Man kan eksekvere konfiguration scripts, forretningslogik/regler og matematiske udtryk for finansielle applikationer fra en ekstern kontekst. 
* Man kan invokere &#8220;shell&#8221; scriptsekvenser i k&#248;rende applikationer. 

Hvis man vil have fortolket andre script-sprog, fx ruby i Java applikationen kr&#230;ver det at man l&#230;gger en jar fil med ruby-script engine i classpath. se nederst p&#229; siden for andre muligheder. 

N&#229;r man skal fortolke script sprog undervejs er hastigheden ikke fantastisk! Derfor er der indbygget mulighed for at kompilere et script til bytecode og optimere hotspots. 

Alle bin&#230;re script-engiens er bygget med Java SE 6 hvilket g&#248;r bagudkompatibilitet irriterende besv&#230;rligt. Med Java 1.4 er det n&#230;rmest umuligt idet der i implementationen er brugt varargs fra Java 5. I Java7 er flere dynamiske API&#8217;er p&#229; vej fx JRuby, Jython og Beanshell. Det betyder at det er muligt at skrive fx ruby kode i Java kode. Faktisk mangler man s&#229; kun at kunne at kunne markere blokke med ruby koden med tags direkte i Java koden. P&#229; samme m&#229;de som Pascal kunne h&#229;ndtere assembler i sin tid.  

Tilbage til eksemplet. Jeg vil udnytte groovy&#8217;s smarte og lette notation til denne opgave i en k&#248;rende Java applikation s&#229; lad os antage at jar filer og fortolker er tilstede i projekt konfigurationen. I teorien kunne det v&#230;re hvilken af de scriptsprog som underst&#248;ttes. 

Nu vil det v&#230;re muligt at skrive denne kode:

&lt;pre&gt;
public void run_groovy_code(Sting code) throws Exception { 
	ScriptEngineManager factory = new ScriptEngineManager(); 
	ScriptEngine engine = factory.getEngineByName(&quot;groovy&quot;); 
	Object ret = engine.eval(code); 
	assertEquals('this is groovy code', ret); 
} 
run_groovy_code(&quot;return 'this is groovy code'&quot;)
&lt;/pre&gt;

Nu er det alts&#229; muligt at overf&#248;re kode som eksekveres &#8220;on the fly&#8221;. 

Lad os nu antage at Java processen har k&#248;rt i flere timer og der kommer forskellige fejl. De bliver listet i en k&#248; og kan browses med en gui. Man kan hente hver enkelt ind og se beskeden og fejl beskeden. Der er ogs&#229; mulighed for at indtaste en regel som kan l&#248;se netop denne situation. Det modtagende system kan ikke modtage 212 for &#230;gtef&#230;lder, den skal konverteres til 216. 

&lt;pre&gt;
rule if grundlag == omregning &amp;&amp; grundform == 212 then grundform 216
&lt;/pre&gt;

Nu findes den nye regel i systemet og policen kan reeksekveres igen. Hvis k&#248;en er smart konstrueret opdager den selv at en &#230;ndring er sket og policen submittes ind i systemet mens den nye regel bytter 212 ud til 216 som det modtagne system kan h&#229;ndtere. 

Hvis man betragter applikationen som ren scaffolding for forretningsprocesser og forretningsregler kan man invokere et meget t&#230;ttere samarbejde med de forretningskyldige. Ligeledes kan man separerer/abstrahere forretningsspecifikke regler fra applikationer og dermed ogs&#229; de lange round-trips som vi lider under. En af de store n&#248;gler er at isolere enkelte processer til en niveau hvor det er muligt at skrive en DSL og skabe en mere deklarativ m&#229;de at anskue problemerne p&#229;-. Processen kan ovenik&#248;bet v&#230;re interaktiv og tillade at tilf&#248;re regler undervejs, m&#229;ske af forretningen selv. Sk&#248;nt!

JSR223 g&#248;r det muligt! 

Her er en kort liste med et par af de script-sprog som kan eksekveres i Java med JavaScripting API. 

* BeanShell - Small, free, embeddable Java interpreter
* FreeMarker - Java-based general purpose template engine
* Groovy - Groovy is an agile dynamic language for the Java
* Jaskell - Lazy functional programming language
* JavaScript 	Rhino 1.6R7 based JavaScript script engine. 	
* JEP - Parsing and evaluating mathematical expressions
* Jexl - Java Expression Language, expression language engine
* JudoScript - Scripting language built on top Java
* JUEL - Java Unified Expression Language
* OGNL - Object-Graph Navigation Language
* Ruby - Best language ever
* Scheme - multi-paradigm programming language, one of two main dialects of Lisp
* Tcl - Tool Command Language
* XPath - Finding information in an XML document
* XSLT - language for transforming XML
* JavaFX Script - Declarative scripting language
* AppleScript - The Language of Automation 
* Bex script 
* OCaml - fast, concise and powerful language 
* PHP 
* PHP 
* Python
* Smalltalk - Dynamically typed, reflective programming language
* CajuScript - Powerfull script to use with Java.  </body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2009-01-16T01:28:21Z</created-at>
    <id type="integer">131</id>
    <post-id type="NilClass">131</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>JSR223 &amp; DSL</title>
    <updated-at type="datetime">2009-03-21T01:40:47Z</updated-at>
  </post>
  <post>
    <body>Jeg er midt i en debugsession i en Java applikation som n&#230;gter at virke. Maskinen er en 64bit server med 16 fysiske CPU'er. Efter et par timer g&#229;r det op for mig at Java&#8217;s threadlocal er &#229;rsagen. Applikationen k&#248;re fint p&#229; en dual core maskine hvor CPU&#8217;er har f&#230;lles hukommelse men kan ikke k&#248;re p&#229; en maskine hvor alle CPU&#8217;er har hver deres hukommelse. Jeg g&#229;r ud fra at det underliggende operativsystem skifter CPU hvorefter min Java proces mister sin kontekst.   

ThreadLocal er en slags global variable allokeret til en tr&#229;d p&#229; en m&#229;de s&#229; den er synlig for alle objekter der eksekveres i denne i denne tr&#229;d. Denne metode benyttes ofte til at binde fx bruger-id eller transaction-id til en tr&#229;d og i meget sj&#230;ldent tilf&#230;lde en database forbindelse. I dette tilf&#230;lde er det det sidste. 

Hvis man kigger ind i threadlocal klassen finder man en n&#248;gle med v&#230;rdien 0x61c88647 og alle nye objekter af denne type tildeles v&#230;rdien hash_increment plus v&#230;rdien 0x61c88647.   Alts&#229;, v&#230;rdien 0x61c88647 er jo et tal i 16tals formatet og hvis man oms&#230;tter det til et decimaltal f&#229;r man enten 2654435769 eller -1640531527. Det er en 32-bit signed version af den usignerede 2654435769 og er den faktiske v&#230;rdi som Java bruger til at beregne hash. 

Tallet repr&#230;senterer &#8221;The Golden Section&#8221; eller den gyldne ratio(sqrt (5) -1) gange to til potensen af 31. Check Dr Ron Knott algoritmer og Donald Knuth, de b&#248;ger h&#248;rer hjemme hos en enhver seri&#248;s programm&#248;r. M&#229;ske ogs&#229; Merck Manual &#8221;adorns your health practitioner's&#8221;. 

Koden for threadlocal en smule kompliceret og jeg m&#229; ty til Dr Heinz for en forklaring. Tanken bag tidligere versioner af Java threadlocals var at dele state mellem flere tr&#229;de hvilket g&#248;r dem praktisk talt ubrugelige for multi-core-applikationer. I Java 1.4, blev et nyt design introduceret hvori threadlocals blev opbevaret direkte i den eksekverede tr&#229;d. N&#229;r man kalder metoden get() sker det p&#229; tr&#229;den og der returneres en instans af threadlocalmap som er en slags indre klasse af threadlocal.  I teorien skulle en udg&#229;ende tr&#229;d fjerne sine threadlocal v&#230;rdier lige f&#248;r garbage collection kaldes med exit() metoden. Hvis vi derimod glemme at fjerne en threadlocal er den stadig berettiget til automatisk garbage collection. Det skyldes en weak references intern i threadlocal til threadlocalmap der har normalt st&#230;rke henvisninger til v&#230;rdier.

Et threadlocal objekt bliver garbage collected n&#229;r den eksekverede tr&#229;d d&#248;r. Undtagen hvis tr&#229;den er blevet trukket ud af en objekt pool som fx i nogle applikationsserverer, i disse tilf&#230;lde bliver v&#230;rdierne aldrig garbage collected.    

N&#229;r et threadlocal objekt bliver garbage collected bliver den svage reference threadlocalmap ryddet. Hvorn&#229;r bliver det s&#229; virkeligt slettet fra threadlocalmap. N&#229;r vi kalder get() metoden p&#229; en indgang i java.util.WeakHashMap fjernes alle gamle indgange. Hvis vi kalder get() p&#229; threadlocalmap g&#229;r det hurtigere men kan give for&#230;ldet poster og dermed memory leaks.

N&#229;r man kalder ThreadLocal set() kan det falde ind under disse kategorier:     

# hvis v&#230;rdi ikke findes inds&#230;ttes den. 
# hvis vi finder vores n&#248;gle, byttes den med ny v&#230;rdi.
# hvis der ikke er plads til flere v&#230;rdier. Denne fase bruger en O(log2n) algoritmen i f&#248;rste omgang. 
# hvis en n&#248;glen er fjernet s&#229; er posten slettet. 

Hvis du &#248;nsker flere oplysninger om, hvordan det virker, kan du f&#229; nogle ideer fra Knuth 6.4 AlgoritmeR. 

Best Practices hvis du absolut vil bruge threadlocals skal du s&#248;rge for at fjerne de indsatte v&#230;rdier n&#229;r du er f&#230;rdig med dem, og helst inden du afleverer din tr&#229;d til en tr&#229;d pool. Den bedste m&#229;de at g&#248;re dette p&#229; er at bruge metoden remove() i stedet for set(null) som vil medf&#248;re at weak reference mappe bliver fjernes straks sammen med v&#230;rdien.  

</body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2008-11-17T22:19:08Z</created-at>
    <id type="integer">126</id>
    <post-id type="NilClass">126</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Threadlocal storage</title>
    <updated-at type="datetime">2008-11-17T22:21:13Z</updated-at>
  </post>
  <post>
    <body>Jeg skal hastighedsoptimere en Java applikation. Den skal performe max p&#229; kortest mulige tid. Den kan ikke skalere udad som man normalt ville &#248;nske men kun opad. Det vil sige en enkelt supermaskine med 16 CPU'er og 16G ram i 64bit software. 

I de senere &#229;r er kravet om hurtigere CPU hastigheder er faldet mens kravet om antal CPU'er er steget. Grunden er at en hurtig processor bruger mere str&#248;m end to processorer p&#229; den samme kraft og man udnytter alts&#229; forholdet mellem ydeevne og forbrug.

Problemet med at skalere en Java applikation er f&#248;rst og fremmest at Java ikke kan udnytte en &#230;gte multicore arkitektur s&#229; den &#248;nskede effektivitet kan opn&#229;s. Man kan tilf&#248;re s&#229; mange CPU'er man vil men Java kan ikke udnytte dem. Dog kan man sige at sige at Java processerne f&#229;r mere frihed idet de andre processer p&#229; maskinen som fx databaser kan k&#248;re p&#229; andre cores. 

Selve Java applikationen er en heterogen monolitisk struktur og den skal eksekveres som en 32bit applikation. Det vil sige at den kun kan udnytte 2G hukommelse eller mindre. Det betyder desv&#230;rre ogs&#229; at man skalere p&#229; den laveste f&#230;llesn&#230;vner. 

Men hvad sker der n&#229;r man flytter en applikation fra en dual core maskine til en &#230;gte fysisk 16 core maskine? Min interesse i sagen er kun henvendt p&#229; i hvilken udtr&#230;kning Java kan udnytte de mange processorer. Hvis Java kun kan udnytte en processor m&#229; applikationen kunne k&#248;re p&#229; samme vis som p&#229; andre duals maskiner. Hvad ville der ske hvis Java kunne udnytte flere CPU&#8217;er og de enkelte processer uds&#230;ttes for &#230;gte samtidighed, alts&#229; potentielt mange samtidige eksekvererne tr&#229;de i samme objekt?   

To ting vakte min opm&#230;rksomhed. Dels en memory leak og dels en slags forvirring omkring konfiguration og resourcer som fx databaseforbindelser. Memory leaks i applikationen skyldes bla ikke frigjorte v&#230;rdier fra hukommelsen. Den andre adf&#230;rd var mere underlig. Applikationen kunne k&#248;re skiftevis langt f&#248;r en tilstand reageret p&#229; manglede resourcer.  

Til min store overraskelses opdager jeg efter flere timers debug session at problemet ligger i ThreadLocal objektet i Java eller rettere dem m&#229;de man bruger dem p&#229;. Applikations designeren binder databaseforbindelser i disse tr&#229;d relaterede objekter. N&#229;r en container tr&#229;d d&#248;r tager den de lokale objekter med sig. Men n&#229;r 64bit maskinen bestemmes sig for at skifte CPU mister alle threadlocals konteksts. Det betyder at konfiguration og resources bliver frigivet midt i k&#248;rselen. 

ThreadLocal har v&#230;ret en meget brugt strategi gennem mange &#229;r og benyttes til at b&#230;re fx et ID gennem en applikation b&#229;de i en tr&#229;d men jeg vil p&#229;st&#229; at det er et antipattern at benytte den til andet fx databaseforbindelser. 

l&#230;s: Thread-local storage

Efter udbedrelse af problemerne k&#248;re softwaren fint p&#229; 64bit maskinen. Java installationen bruger to, m&#229;ske tre CPU'er til at eksekvere Java softwaren. N&#229;r man skalere er det &#248;nskeligt at kunne skalere line&#230;rt, alts&#229; ved en fordobling af kraft for&#248;ger man hastighed gange to. Reelt set k&#248;re denne Java applikation p&#229; en af de 16 hurtige CPU ad gange og udnyttelsen af den fine hardware stinker max. 

Hvis man vil kunne skalere sine applikationer m&#229; man skrive dem til multicore.

&quot;Small Things, Loosely Joined, Written Fast&quot;:posts/122-Small-Things-Loosely-Joined-Written-Fast</body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2008-11-01T09:51:34Z</created-at>
    <id type="integer">124</id>
    <post-id type="NilClass">124</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Scaling Enterprise Java on 64-bit MultiCore</title>
    <updated-at type="datetime">2008-11-02T22:50:31Z</updated-at>
  </post>
  <post>
    <body>En Java proces har et lineart stigende hukommelsens forbrug. En uheldig arkitektur beslutning afstedkommer en konstant &#248;gning af hukommelses forbrug ved eksekvering af processen.  Beslutningen resulterer i en begr&#230;nset k&#248;retid afh&#230;ngigt af den valgte m&#230;ngde af hukommelse hvori processen eksekveres. 

En proces med ca. 4000 enheder optager ca. femhundrede megabytes. Et ansl&#229;et estimat p&#229; ca. 10.000 enheder vil optage ca. femtenhundrede megabytes og s&#229; fremdeles. Det betyder at man skal bruge virkeligt meget hukommelse for at k&#248;re programmet f&#230;rdig. 

Kan det lade sig g&#248;re og hvad er hukommelse? 

Alle Java processer eksekveres i en JVM, container, som har automatisk hukommelsesstyring. Den allokerede m&#230;ngde hukommelsen som er afsat til at indeholde programmet kaldes Heap Memory. Denne container kan dekoreres med flag som bestemmer fordelingen mellem de enkelte hukommelsesomr&#229;der der allokeres til hver applikation. 

Der findes forskellige omr&#229;der eller pools under den f&#230;lles betegnelse Heap Memory. Nogle af disse omr&#229;der holder p&#229; nye objekter og andre p&#229; gamle. Heap er delt op omkring to hovedomr&#229;der, heap space og non heap space.  

* Eden Space - Pulje, hvorfra hukommelse er oprindelig blev tildelt for de fleste objekter.  
* Survivor Space - Pool indeholder objekter, der har overlevet GC for Paradis rummet.
* Tenured generation - Pool indeholder objekter, der har eksisteret i nogen tid i den overlevende plads
* Faste Generation - Besidder alle de reflekterende data i den virtuelle maskine selv, s&#229;som klasse og metode objekter. Med JVMs at bruge klasse deling af data, denne generation er opdelt i read-only og read-write omr&#229;der.
* Code cache - Memory anvendes til udarbejdelse og opbevaring af native kode
* Perm Gen &#8211; Stak eller information om alle de objekter som er placeret i hukommelsen. 


Den f&#230;lles samlede m&#230;ngde hukommelse er den vigtigste faktor. Men hukommelsen har ogs&#229; direkte indvirkning p&#229; garbage collection. GC er den proces som administrer hukommelsen og sikre at de programm&#248;rer som skriver Java kode ikke beh&#248;ver at vide noget om allokering af hukommelse.     

Ydeevnen ved garbage collection h&#230;nger t&#230;t sammen med hukommelsen. N&#229;r hukommelsen n&#229;r en vis udfyldings gr&#230;nse kaldes GC af systemet med j&#230;vne mellemrum. Under en garbage collection re-allokeres alle objekter i heap. Nogle objekter flyttes mellem forskellige pools mens andre fjernes helt. Heap vokser eller falder ved hver GC for at bibeholde forholdet mellem fri plads og de levende objekter. Fx indeholder Perm information om objekter i Eden og dermed kan man begynde at ane et m&#248;nster om relationer mellem de enkelte rum. 

Normalt er det god skik at stille JVM MIN til 512m og MAX til det samme. Ved denne indstilling kan systemet starte hurtigt og bruger ikke tid p&#229; store re-allokeringer af hukommelse ved GC. 
&lt;pre&gt;
-Xms512m
-Xmx512m
&lt;/pre&gt;

Hvis applikationen h&#230;nger eller f&#229;r en &#8221;java.lang.OutOfMemoryError&#8221; har man et heap problem. Typisk vil applikationer blot standse helt eller delvist. Hvis man angiver for stor hukommelse vil det tager langt tid at k&#248;re GC og derved vil applikationen opleve &#8221;stop and go&#8221; funktionalitet med alvorlig forringelse i ydeevne. 

Applikationer med dynamisk kode og mange klasser som fx GEN, JSP, groovy osv kan blive n&#248;dt til at &#248;ge MaxPermSize. Den default JVM st&#248;rrelse for stakken er 64 megabyte. 

&lt;pre&gt;
-Xms512m
-Xmx1024m
-XX:MaxPermSize=128m
&lt;/pre&gt;

Hukommelsen gemmer objekter og stakken holder styr p&#229; oplysninger om objekter. Derfor, jo flere objekter, der findes, jo mere information finder der og jo st&#248;rre stak skal genneml&#248;bes ved hver GC. Efter denne logik fyldes Perm hurtigere hvis din applikation indeholder mange sm&#229; class-filer frem for f&#229; store class-filer. 


Hvordan sikre man at disse opstarts parameter rent faktisk virker? 

I Java 5.0 findes et omfattende overv&#229;gnings og ledelsesm&#230;ssig v&#230;rkt&#248;j. Jconsole er en gr&#230;nseflader indtil Java Virtual Machine men giver ogs&#229; out-of-the-box fjernbetjening, overv&#229;gning og forvaltning. Den bruger omfattende instrumentering af JVM for at give oplysninger om ressource forbrug af applikationer ved hj&#230;lp af Java Management Extension (JMX) teknologi.. 

Man kan lave sine egne beans til overv&#229;gning og styring af selvbyggede processer i JVM. En bean skal f&#248;lger og opfylde JMX design m&#248;nstre. En bean kan repr&#230;sentere et program eller en ressource som skal forvaltes. Intern i bean findes l&#230;se og skrive attributter samt metoder til invokation. En bean kan ogs&#229; udsende meddelelser ved at foruddefinerede begivenheder. 
Hvis man vil monitorere en remote proces i en JVM kan man tilf&#248;je disse &#8211;D parameter.  

&lt;pre&gt;
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=[port]
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
&lt;/pre&gt;

Derefter er at blot at starte Jconsole og connected under remote fanen.

Der findes en r&#230;kke parameter man kan overf&#248;re til JVM via -D argument. Men m&#229;ske m&#229; du ser realiteten i &#248;jne og erkende at din applikation har alvorlige fejl som b&#248;r l&#248;ses.   



* Xmx1500m # Heap size p&#229; 1500 MB
* Xincgc # Incremental low pause collector. L&#248;bende oprydning af tenured space.
* XX:GCTimeRatio=24  # lad JVM selv bestemme sit footprint ud fra en m&#229;ls&#230;tning om at bruge 4% af tiden p&#229; GC
* Xmn1g # newsize p&#229; 1GB, svarer til ratio p&#229; 2/3 p&#229; jespers server (?)
* Xss128k # reducerer st&#248;rrelsen af stakken ifht. det vi k&#248;rer med nu mhp. at skabe mere plads til hoben.
* XX:+UseConcMarkSweepGC  # Concurrent mark sweep collector
* XX:SurvivorRatio=10  # Survivor space 1:10
* XX:TargetSurvivorRatio=90 # Bedre pladsudnyttelse af survivor space
* XX:MaxTenuringTreshold=15 # Objekter kan overleve flere sweeps f&#248;rend de bliver flyttet til tenured


</body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2008-10-14T03:32:26Z</created-at>
    <id type="integer">123</id>
    <post-id type="NilClass">123</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Java Virtual Machine Heap Memory</title>
    <updated-at type="datetime">2008-10-22T22:32:12Z</updated-at>
  </post>
  <post>
    <body>Jeg har lige modtaget en java kildefil fra en kollega med ca. 300 linjer. Jeg vil ikke vise den fordi den er alt for verbose eller lowlevel. Der er en main metode og et par metoder med noget dato fis. I teorien skulle klassen kunne beregne b&#248;rneydelse og er en del af en st&#248;rre skattepakke der er baseret p&#229; Magnus og kan beregne b&#229;de skat og budget. 

Det var faktisk noget jeg skulle ha brugt min tid p&#229; men min kollega kunne bare ikke g&#248;re for det. Opgaven er jo faktisk sjov n&#229;r man kan de ret enkelte regler som udg&#248;r denne ydelse. Og Java klassen regner rent faktisk korrekt. 

Det giver til geng&#230;ld mig en god mulighed for at abstrahere lidt over noget kode hvilket jeg synes er sjovt. Der hvor k&#230;den hopper af for mig er m&#230;ngden af kodelinjer brugt p&#229; simple konstruktioner. Fint nok, jeg bruger da koden i det forretningsmodul hvori denne funktionalitet skal v&#230;re men kan ikke lade v&#230;re at t&#230;nke over de implikationer det har p&#229; for eksempel drift, vedligehold, videreudvikling osv. 

Hvad betyder det n&#229;r f&#229; og ret enkelt regler bliver implementeret og fragmenteret ud i 300 linjer procedural  kode? Ja til at starte med er det jo ikke enkelt mere. Jo jeg medgiver at alle os der arbejder professionelt med Java tendere til at g&#248;re alting mere komplekst end det i virkeligheden er. Selv vores projektledere kan ikke genkende selv simple opgave efter vi har fundet en lille variation af et kendt teknisk problem som vi lige skal l&#248;se f&#248;rst, alle opgaver ender med at v&#230;re Java problemer. 

Et andet problem er l&#230;sbarhed. Kan jeg i det hele taget forst&#229; koden. Kan koden klassificeres efter kravet om beautyful code (en anden post). Nej, allerede efter ca. 40 linjer gider jeg ikke l&#230;se mere. Giver det fremtidige problemer? Ja, for reaktionen er jo at jeg selv vil bygge en helt ny udgave n&#229;r der kommer en mindre tilf&#248;jelse. 

&quot;Beautyful code&quot;:http://www.frankvilhelmsen.com/posts/71-Beautyful-code

Et at de vigtigste objektorienterede principper er genbrug. Men meget f&#229; t&#230;nker i de baner n&#229;r de udvikler software. Ofte er undskyldningen at der ikke er tid! Pis, hvis der er tid til d&#229;rligt design er der ogs&#229; tid til bedre design. 

Hvordan organiseres logiskesammenh&#248;rerne sprog konstruktioner? Skal man fokusere p&#229; sproget eller p&#229; forretningen? Et andet objektorienteret princip omhandler adf&#230;rd og m&#229;ske ville det v&#230;re nyttigt at bruge de gamle dyder og give objektet mulighed for at l&#248;se sine egen opgaver ved at implementer disse egenskaber i klassen selv. Sproget betyder mindre hvis man implementerer efter objektorienteret paradigmer.

Hvis man vil lave god software mener jeg at man m&#229; forst&#229; pr&#230;misserne om opgaven. En ting som undrede mig var at der i Java koden ikke er brugt datastrukturer til at repr&#230;sentere fx, perioder, &#229;rgange og kvartaler. Ca. 25% er brugt til simple traversering af dato. Det kan jeg g&#248;re bedre. Faktisk vil jeg definere alle de ting som jeg med sikkerhed ved fra start og binde dem i strukturer. 

Et andet sted hvor jeg virkelig kan g&#248;re en forskel er omkring selve algoritmen som beregner de n&#230;ste 12 m&#229;neders b&#248;rneydelse. Java klassen har defineret 100 linjer til denne metode alene. F&#248;rst findes de n&#230;ste 4 kvartaler. Dern&#230;st det ultimative stopkriteriet som er at b&#248;rneydelsen udl&#248;ber den dag man fylder 18. Sjovt er det at man begynder f&#248;rst p&#229; den 20 i n&#230;ste kvartal efter f&#248;dsel. Til slut er det blot at plukke de respektive bel&#248;b. 

&lt;pre&gt;
module Childcontribution

  class Calculate_benefits
    
    def initialize(child)
      @child  = child
      @petite_18_teen_birthday = Date.new(y=@child.year+18, m=@child.month, d=@child.day)
      @today = Date.today
      periods
      quarters
      ranges
    end

    def payment_next_12_month
      
      @ydelse = Hash.new(0)
      @quarters.each do |quarter| 
        y = calculate_age(quarter, @child)
        if y == 18
          if birthday_in_last(quarter) 
            @ydelse[quarter] = calculate_speacial_case(quarter) 
          else
            @ydelse[quarter] = 0
          end
        else 
          @ydelse[quarter] = @ranges[y]
        end
      end

      @ydelse.each_pair do |key, value|
        puts &quot;Ydelse pr. #{key} kr. #{value} &quot;
      end
      
      amount = 0
      @ydelse.values.collect {|value| amount += value }
      amount
    end
    
    private

    def birthday_in_last(quarter)
      start = @periods[@periods.rindex(quarter)-1]
      is_birthday_in_last = start &lt; @petite_18_teen_birthday &amp;&amp; quarter &gt; @petite_18_teen_birthday
    end
    
    def calculate_speacial_case(quarter)
      start_date = @periods[@periods.rindex(quarter)-1]
      puts day_pay = @ranges[@ranges.size-1] / 90 # 2515 / 90
      days = @petite_18_teen_birthday - start_date
      day_pay * days
    end
    
    def calculate_age(quarter, birthday)
      (quarter - birthday).to_i / 365
    end

    def ranges
      @ranges = Hash.new(0)
      (0..2).each  { |n| @ranges[n] = 4039 } # 0-2- &#197;rige 
      (3..6).each  { |n| @ranges[n] = 3198 } # 3-6- &#197;rige 
      (7..17).each { |n| @ranges[n] = 2516 } # 7-17 &#197;rige 
    end
    
    def periods 
      @periods  = Array.new()
      for y in [2007, 2008, 2009, 2010] 
        for m in [1, 4, 7, 10]
          @periods &lt;&lt; Date.new(y=y,m=m,d=20)  
        end
      end
    end

    def quarters
      @quarters = Array.new(0) # Hash.new(0)
      for i in 0...@periods.length
        if @periods[i] &gt; @today
          for n in i...i+=4
            @quarters &lt;&lt; @periods[n]
          end
          break
        end
      end
    end
    
  end
end

child = Date.new(y=1991,m=1,d=1)
calc = Childcontribution::Calculate_benefits.new(child)
puts &quot;Next 12 month #{calc.payment_next_12_month}&quot;
&lt;/pre&gt;</body>
    <category-id type="integer">11</category-id>
    <created-at type="datetime">2008-06-09T02:52:00Z</created-at>
    <id type="integer">112</id>
    <post-id type="NilClass">112</post-id>
    <published type="boolean">false</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Child Care Benefit</title>
    <updated-at type="datetime">2008-06-11T22:10:05Z</updated-at>
  </post>
  <post>
    <body>Jeg sider p&#229; et projekt og abstrahere nogle skatteberegninger som skal eksekveres i Java. Alt det kryptiske g&#248;jl omkring ops&#230;tning og sm&#229; ligegyldige spidsfindigheder er p&#229; plads. Det som holder mig v&#229;gen er hvordan jeg skal synligg&#248;re eller promote gr&#230;nsefladen til disse beregninger for en stribe udviklere.  

Jeg kan jo bare lade dem konstruere en stribe objekter og invokere set metoder p&#229; objekterne. Det er bare s&#229; almindeligt og jeg er d&#248;dtr&#230;t af hele termologien omkring set og get metoder. Jeg kunne ogs&#229; bruge injection framework eller m&#229;ske factory metoden.  

Flere af beregninger kan udf&#248;re alene men nogle andre er afh&#230;ngige af delberegninger. Hvordan udtrykker jeg det p&#229; en simple og hensynsfuld m&#229;de? Alle beregninger kr&#230;ver forskellige input og nogle resultater er input til andre hvilket medf&#248;rer en bestemt r&#230;kkef&#248;lge. 

Fluent interface kunne v&#230;re en l&#248;sning nu da platformen er Java. Martin Fowler har skrevet flere blogs omkring emnet og de er for det meste fornuftige. Et sandt fluent interface kan v&#230;re en forn&#248;jelse at bruge. Man beh&#248;ver ikke huske alle mulige ting om implementeringen og man kan direkte fortolke lingo&#8217;en. 

Fluent interface har levet i lange tider i dynamiske sprog men gode eksempler er der ikke mange af. 

Fluent interface kan tvinge en til at t&#230;nke h&#229;rdt over selve forretningen og det det er der jo aldrig tid til. S&#229; hellere lave &#233;n d&#229;rlig l&#248;sning. N&#229; det handler om Lingo.   
&lt;pre&gt;
        Beregn beregn new BeregnImpl();
        beregn.befordring().
        beregn.fribil().
        beregn.skat();
&lt;/pre&gt;
Dette er en fin l&#248;sning og n&#230;sten helt deklarativ programmering, men tager ikke h&#248;jde for input/output og heller ikke for selve eksekveringen. Fluent interface er m&#229;ske den bedste metode til at g&#248;re statiske Java til et DSL sprog? M&#229;ske ikke helt men n&#230;sten, der er stadig de grimme parenteser alle vegne og lidt gentagelse men det kan lade sig g&#248;re at skrive noget kode som n&#230;sten lader sig l&#230;se som plain sprog. 

N&#229;r man arbejder med fluent interface drejer det sig om at opbygge en kontekst der kan opereres p&#229;. S&#229; fribil er alts&#229; en metode p&#229; beregn og fribil returnere samme kontekst osv.   

At designe et fluent interface er sv&#230;rt, at implementere bibliotekerne bag er endnu sv&#230;rere. 

* Skjul dit arbejde. Hvis du hele tiden f&#248;ler dig n&#248;dsaget til at fort&#230;lle hvor langt du er kommet er der noget galt. 
* Hold din kontekst for dig selv. Klienten m&#229; naturligt kunne fornemme konteksten. 
* Eksponer ikke din implementation. Klienten m&#229; kun se de valg som findes netop i denne kontekst. 
* Brug lang tid p&#229; navn konvention. Perspektivet er klientens og DSL&#8217;en skal udtrykke forst&#229;elige koncepter.  
* Lav flere design. Fly ikke med det f&#248;rste. 
* Lad aldrig klienter gentage sig selv. 

Lad mig pr&#248;ve at g&#248;re det lidt bedre:
&lt;pre&gt;
        Beregn().befordring().fribil().skat();
&lt;/pre&gt;

Gentagelserne er v&#230;k. Desv&#230;rre kan jeg ikke styre eksekveringen, skal hver metoder invokere en del beregning? Og hvad med input og det faktum at befordring er en del af skatberegningen. 

Vil jeg s&#230;tte input p&#229; Beregn(), s&#229; input g&#230;lder alle beregninger? Beh&#248;ver jeg en metode til sidst som eksekvere koden? Hvad er output? 

Mens jeg t&#230;nker over dette har min kollega lavet denne presentation om fluent interfaces. 

&quot;Fluent interface for SQL in Java&quot;:http://docs.google.com/Presentation?id=dckns5q8_86hff23tcw

</body>
    <category-id type="integer">11</category-id>
    <created-at type="datetime">2008-05-16T05:44:00Z</created-at>
    <id type="integer">111</id>
    <post-id type="NilClass">111</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Fluent interface</title>
    <updated-at type="datetime">2008-05-27T00:45:10Z</updated-at>
  </post>
  <post>
    <body>I Java er string konstanter gemt i en intern tabel. Ogs&#229; hvis konstanten findes i flere klasser. N&#229;r der findes flere samtidige eksekverende tr&#229;de er det udviklerens opgave at beskytte de f&#230;lles ressource imod korruption eller sideeffekter. 

Hvis man har interesse i systemernes performance starter man typisk med at se p&#229; CPU, disk, IO og memory forbrug. Hvis ser p&#230;nt ud g&#229;r man videre til at se p&#229; tr&#229;de og garbage collector aktivitet. Hvis der stadig ikke er fundet en flaskehals har vi med stor sandsynlighed et stridssp&#248;rgsm&#229;l mellem individuelle tr&#229;de. 

S&#229; lad os kigge p&#229; et par problem omkring synkronisering:

&lt;pre&gt;
String LOCK = &quot;LOCK&quot;;
synchronized(LOCK) { ... }
&lt;/pre&gt;

Denne konstruktion er helt normal i Java og beskytter beskytter imod forurening i kodeblokken. Men den fungerer ogs&#229; som flaskehals idet den l&#229;ser for parallel eksekvering af flere tr&#229;de. Java string konstanter bliver gemt i en intern tabel og hvis LOCK objektet eksistere i to klasser vil de realiteten pege p&#229; samme instans af string, v&#230;rdien LOCK. 

&lt;pre&gt;
public class One {
  private String LOCK = &quot;LOCK&quot;;
}

public class Two {
  private String LOCK = &quot;LOCK&quot;;
}
(one.LOCK == two.LOCK) # true 
&lt;/pre&gt;

Her er to klasser med hver deres instans af LOCK, alts&#229; to objekter men de peger p&#229; samme string. Hvis man produceret String LOCK objektet med metoden new ville det stadig v&#230;ret to forskellige objekter med hver deres string. 

Men det er stadig en d&#229;rlig metode til objekt l&#229;sning. 

&lt;pre&gt;
public class One {
  private String LOCK = new String(&quot;LOCK&quot;);
}
public class Two {
  private String LOCK = new String(&quot;LOCK&quot;);
}
(one.LOCK == two.LOCK) # false
(one.LOCK.intern() == two.LOCK.intern()) # true
&lt;/pre&gt;

De to strenge er forskellige ved sammenligning men hvis vi kalder metoden string.intern() kan man se at det stadig er en reference til selv samme objekt. Det betyder at vi ville med denne fremgangsm&#229;de synkronisere hele systemet p&#229; dette ene objekt. 

Java har mulighed for atomics referencer eller atomics primitiv. Atomics benytter Compare-And-Swap fremgangs m&#229;den. Fx med metoden addAndGet(int num) der som udgangspunkt er en optimistisk metode. Hvis der ikke er en konflikt vil den s&#230;tte v&#230;rdien num men hvis der er en konflikt vil den pr&#248;ve igen. 

P&#229; denne m&#229;de kan vi have thread sefe kode uden eksplicit l&#229;sning. Men der er stadig et problem idet feltet inden i en atomic er markeret volatile for at forhindre at den bliver sat. 

Der er dog flere metoder til at minimere risiko for korruption. Fx ved brug af Concurrent-klasserne under collention i stedet for de gamle HashMap, HashTable osv. En ConcurrentHashMap kan partitioneres i buckets for deling mellem klienter.  

B&#229;de synkroniseret metode og synkroniseret blok er til for at kunne l&#229;se et objekt. 

# Synchronized metode

En synkroniseret metode vil l&#229;se alle objekter. Anvendes n&#229;r man er sikker p&#229; at alle tilf&#230;lde vil arbejde p&#229; det samme s&#230;t af data via samme metode. 

# Synkroniserede blok 

En synkroniserede blok vil l&#229;se et bestemt objekt. Synchronized blok anvendes n&#229;r man bruger kode som vi ikke kan &#230;ndre sig selv og tredjepartskode osv.

B&#229;de synkroniseret metode og blokke bruges til at erhverver en l&#229;s til et objekt. Men kontekst kan varierer. 


&lt;pre&gt;
private Object LOCK = new Object();

static ConcurrentLinkedQueue list = new ConcurrentLinkedQueue();

public String getText(@PathParam(&quot;cpr&quot;) String cpr) {
    synchronized(LOCK) {
        list.add(&quot;element&quot;);
    }
}
&lt;/pre&gt;

ConcurrentLinkedQueue FIFO (first-in-first-out) er et godt valg n&#229;r man vil dele adgang til en f&#230;lles liste samtidigt fra mange tr&#229;de. 
</body>
    <category-id type="integer">11</category-id>
    <created-at type="datetime">2008-01-22T00:05:00Z</created-at>
    <id type="integer">94</id>
    <post-id type="NilClass">94</post-id>
    <published type="boolean">false</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Java LOCK objects</title>
    <updated-at type="datetime">2010-01-15T10:53:16Z</updated-at>
  </post>
  <post>
    <body>Jeg ser frem til at afpr&#248;ve alle de nye features i Java 7 som snart kommer i de f&#248;rste prebuilds. Men inden da vil jeg her give min sidste uforbeholdne mening om Java op til version 6 som jeg ser det. 

h4. Stabiliser Java 

Java som sprog tr&#230;nger til at blive stabiliseret. En bred skare af personer arbejder p&#229; nye sprogkonstruktioner til Java men efter min mening b&#248;r de overf&#248;re de gode tanker til et nyt sprog. Brug alle dejlige fors&#248;g med closures til Groovy og Scala. Rens ud i boilerplate kode som get/set paradimet, anonyme inner klasser, de lange type deklarationer og d&#229;rlig generics. Mit liv er for kort.    

h4. Java&#8217;s anden storhedstid

Den ene ting som kunne eksplodere interessen omkring Java igen er at lade JVM&#8217;en overtage alle aspekter omkring multithreaded programmering og samtidig deprecare samtlige current pakker. Alle vi programm&#248;rer har &#248;delagt nok med vores sublime tanker om samtidighed. Jeg vil eksekvere kode p&#229; Intel med 16 cores. 

h4. The web

Indf&#248;r &#233;n stateful m&#229;de at udvikle webapplikationer som kan appellere til 90 procent af brugerne. Web programmering i Java er kn&#230;kket og stinker big time. 

Konklusionen er at jeg fra dd. ikke gider Java pre 7. 
</body>
    <category-id type="integer">7</category-id>
    <created-at type="datetime">2008-01-15T23:18:00Z</created-at>
    <id type="integer">92</id>
    <post-id type="NilClass">92</post-id>
    <published type="boolean">false</published>
    <tag-id type="NilClass">14</tag-id>
    <title>Java succes!</title>
    <updated-at type="datetime">2008-01-23T05:30:13Z</updated-at>
  </post>
</posts>
