Links

  • 1. Sogeti
  • 2. JBoss
  • 3. IBM
  • 4. Oracle
  • 5. SpringSource
  • 6. NL-JUG
  • 7. Java

Archives

Syndication  RSS 2.0

RSS 1.0
RSS 2.0

Bookmark this site

Add 'JCN Blog' site to delicious  Add 'JCN Blog' site to technorati  Add 'JCN Blog' site to digg  Add 'JCN Blog' site to dzone

Posted by Jaap Coomans at 10:12 on Wednesday 13 November    Add 'JFall 2013: Designing Distributed Programs with a Raspberry Pi cluster' site to delicious  Add 'JFall 2013: Designing Distributed Programs with a Raspberry Pi cluster' site to technorati  Add 'JFall 2013: Designing Distributed Programs with a Raspberry Pi cluster' site to digg  Add 'JFall 2013: Designing Distributed Programs with a Raspberry Pi cluster' site to dzone

De eerste sessie na de middagkeynote op JFall 2013 was voor mij “Designing Distributed Programs with a Raspberry Pi cluster” door Arjan Lamers van First8. Natuurlijk kwam ik in eerste instantie af op het geek-appeal van de titel, maar al snel bleek dit ook inhoudelijk een erg goede sessie.

De essentie van het verhaal was dat Arjan een proof-of-concept omgeving had gemaakt voor gedistribueerd programmeren met behulp van een batterij Raspberry Pi’s. De hardware setup bestond uit twee clusters van 4 Raspberry Pi’s, per cluster aangesloten op een switch. Deze twee switches waren onderling met elkaar verbonden. Zo had hij dus voor een zeer beperkt budget twee “datacenters” met ieder 4 nodes. Naast dat dit voordelig, compact en geeky is, brengt het ook als voordeel mee dat de Pi’s traag zijn. De redenatie van Arjan: als je je gedistribueerde applicatie op een Pi al goed kan laten performen, dan komt het in je productiecluster zeker goed. Daar valt uiteraard wat voor te zeggen.

Om het geheel te demonstreren had Arjan een eenvoudig gedistribueerd programma gebouwd: Pigs in Space. Niet veel meer dan een veld waar ruimteschepen overheen vliegen met collision detection om te zorgen dat ze niet door elkaar heen vliegen. Met behulp van Hazelcast was het veld in sectoren opgesplitst en verdeeld over de diverse Pi’s. Aan de achtergrondkleur van de sector was af te lezen welke Pi de sector onder zijn hoede had.

Hoewel dit allemaal geen rocket-science lijkt, is het wel een hele goede opzet om basale problemen van gedistribueerd programmeren duidelijk te maken. Zo was al snel te zien dat op de grenzen van de sectoren, waar de ruimteschepen van de ene Pi naar de andere Pi overgingen, ruimteschepen vaak samenklonterden. Ook liet Arjan zien wat er gebeurde in geval van fail-over. Als hij een of meerdere Pi’s eruit trok, was duidelijk te zien dat het geheel even haperde en dat in eerste instantie de sectoren van de uitgevallen Pi’s wel snel werden overgenomen, maar niet eerlijk verdeeld werden onder de andere Pi’s. Dit evenwicht werd later hersteld. Ook was duidelijk te zien dat ruimteschepen in drukke sectoren langzamer vlogen. Een probleem dat zichzelf alleen maar versterkt, omdat ruimteschepen sneller zo’n sector in vliegen dan eruit.

Voor mij persoonlijk was de grootste eye-opener zijn demonstratie van het split-brain probleem. Hiervoor had hij afgedwongen dat de failover van elke Pi zich in het andere “datacenter” bevond. Een opzet die veel bedrijven in werkelijkheid ook gebruiken om de geografische risico’s te spreiden. Na een tijdje werd de connectie tussen de twee datacenters verbroken (split-brain). Zoals verwacht ging alles in principe gewoon door. Sectoren uit het andere datacenter werden overgenomen door de Pi’s in het overgebleven datacenter. Het interessante deel kwam echter toen de verbinding werd hersteld. Op dat moment waren er twee waarheden: de waarheid in het ene datacenter en de waarheid in het andere datacenter. Het gevolg was dat op beeld de ruimteschepen van hot naar her versprongen. Voor de Facebooks en de Amazons van deze wereld zijn dit serieuze problemen waarvoor een herstelstrategie bedacht moet worden: doe je een merge, kies je de ene waarheid boven de andere? In het geval van Amazon wist Arjan te vertellen dat ze in zo’n geval zo vriendelijk zijn om je twee shopping carts bij elkaar op te tellen: ze willen natuurlijk geen omzetverlies :)

Ondanks dat er maar beperkt code op het scherm te zien was, was dit toch een van de beste sessies van de dag. Een sessie die je aan het denken zet.

Wil je meer weten over PigsInSpace? Arjan heeft de source op GitHub gezet:
https://github.com/First8/pigsinspace

Posted by Eric Gunnewegh at 9:14 on Tuesday 20 August    Add 'JMS 2.0' site to delicious  Add 'JMS 2.0' site to technorati  Add 'JMS 2.0' site to digg  Add 'JMS 2.0' site to dzone

Inleiding

Eén van de vernieuwde API’s in JEE7 is JMS 2.0. De JMS API is lang stabiel gebleven na de release van JMS 1.1 in 2002. Sinds JavaEE 1.4 maakt JMS 1.1 onderdeel uit van het Java EE platform. Twee zaken die opvallen in de nieuwe JMS API zijn het vereenvoudigde programmeermodel en het gebruik van de nieuwe features die het Java SE platform inmiddels biedt met Java SE 7. Daarnaast zijn er aan de JMS API ook een aantal nieuwe features toegevoegd.

Vereenvoudigd programmeermodel

In figuur 1 is het klassieke JMS programmeermodel weergegeven dat bestaat sinds 2002.

 

JMS 1.1

Figuur 1: Het klassieke JMS 1.1 programmeermodel

In JMS 2.0 is dit programmeermodel vereenvoudigd met de introductie van de JMSContext, zoals weergegeven in figuur 2. De JMSContext combineert de Connection en Session objecten in één object. Daarnaast bevat de nieuwe API de nieuwe JMSConsumer en JMSProducer objecten. De klassieke API wordt overigens niet vervangen door de nieuwe API. Beide API’s blijven naast elkaar bestaan. Wat dit vereenvoudigd programmeermodel betekent voor de Java code, laat zich goed illustreren door codefragment 1.

JMS 2.0

Figuur 2: Het vereenvoudigde JMS 2.0 programmeermodel

   @Resource(lookup = “java:comp/DefaultJMSConnectionFactory”)
   private static ConnectionFactory connectionFactory;

   @Resource(lookup = “jms/TestQueue”)
   private static Queue queue;

   String message = “Een test message”;
   try (JMSContext context = connectionFactory.createContext();) {
      context.createProducer().
         setDeliveryMode(DeliveryMode.NON_PERSISTENT).
         setPriority(9).
         setTimeToLive(10000).
         send(queue, message);
   } catch (JMSRuntimeException e) {
      System.out.println(e);
   }

Codefragment 1: Het versturen van een message

Codefragment 1 laat zien hoe je met de vernieuwde JMS API op vereenvoudigde manier een bericht kunt sturen. Vergeleken met de klassieke API vallen een aantal zaken op.

  1. Een Producer creëren gaat sneller via een JMSContext dan in het oude model via achtereenvolgens een Connection en een Session.
  2. Er hoeft niet eerst een TextMessage gecreëerd te worden. De Producer accepteert ook een String.
  3. Het creëren van JMSContext gebeurt in een try-with-resources block, een nieuw feature van het Java SE7 platform. De JMSContext interface extends de AutoCloseable interface, zodat bij het afsluiten van het try-with-resources block automatisch de close() methode wordt aangeroepen.
  4. Bij het creëren van de JMSProducer kan method chaining gebruikt worden voor het zetten van de diverse opties. In JMS 2.0 hebben de diverse setters voor het zetten van opties, headers en properties de JMSProducer als return value, wat method chaining mogelijk maakt.

Ook het ontvangen van berichten is vereenvoudigd. Zie ter illustratie het volgende codevoorbeeld waarbij het niet nodig is om een Message om te zetten naar een TextMessage om hier vervolgens de body uit op te vragen.

   String msg = context.createConsumer(queue).receiveBody(String.class, 1000);

Injectie van JMSContext

In een servlet of EJB is het mogelijk om direct de JMSContext te injecteren, in plaats van deze aan te maken via een geïnjecteerde ConnectionFactory.

   @Inject
   @JMSConnectionFactory(“jms/MyConnectionFactory”)
   private JMSContext context;

Wanneer gebruik gemaakt wordt van de default ConnectionFactory, kan de @JMSConnectionFactory achterwege gelaten worden.

sessionMode

De introductie van de sessionMode biedt de ontwikkelaar een duidelijker keuze in het gebruik van een transactionele sessie of een acknowledge mode. In de klassieke JMS API bevat het Connection object de volgende methode die de ontwikkelaar op het verkeerde been kan zetten.

   Session createSession(boolean transacted, int acknowledgeMode) throws JMSException;

Het probleem met deze methode is dat niet alle combinaties valide zijn. Bij een transactionele sessie (transacted=true) vindt een acknowledgement automatisch plaats na een commit. In deze situatie heeft het geen zin om een acknowledgeMode op te geven. Andersom geldt ook dat een acknowledgeMode alleen betekenis heeft bij transacted=false.

De vernieuwde JMS API biedt meer duidelijkheid met de volgende methode in het Connection object

   Session createSession(int sessionMode) throws JMSException;

of de volgende methode in het ConnectionFactory of JMSContext object.

   JMSContext createContext(int sessionMode);

De sessionMode kan één van de volgende waarden hebben, waardoor de ontwikkelaar moet kiezen tussen een transactionele sessie of een acknowledgement mode.

   Session.SESSION_TRANSACTED
   Session.CLIENT_ACKNOWLEDGE
   Session.AUTO_ACKNOWLEDGE
   Session.DUPS_OK_ACKNOWLEDGE
   Session.TRANSACTED

Hoewel dit een stuk duidelijker is dan in de klassieke JMS API, geldt ook hier dat niet elke waarde in alle situaties geldig is. Bijvoorbeeld, als de methode wordt aangeroepen in een Web of EJB container in een actieve transactionele JTA context, wordt de sessionMode genegeerd. Voor de details wordt verwezen naar de Javadoc, die met betrekking tot dit onderwerp in JMS 2.0 ook een stuk uitgebreider is geworden, zie http://docs.oracle.com/javaee/7/api/javax/jms/Connection.html#createSession(int).

Shared subsriptions

Eén van de nieuwe features in de JMS 2.0 API zijn de shared subscriptions op topics. Voor wat betreft topics waren er voorheen twee varianten, durable en non-durable topics, die beiden alleen unshared subscriptions ondersteunden. In JMS 2.0 kunnen subscriptions ook shared zijn.

In de JMS 1.1 API konden meerdere consumers een eigen subscription hebben op hetzelfde topic. Elke consumer met een eigen subscription (unshared subscription) ontving dan elk bericht dat op het topic gepubliceerd werd. Pas in JMS 2.0 is het mogelijk dat meerdere consumers een subscription kunnen delen (shared subscription). De berichten die op een topic met een shared subscription gepubliceerd worden, worden door de JMS provider verdeeld over de consumers die bij de shared subscription horen, waarmee het mogelijk wordt berichten parallel af te handelen in meerdere threads.

Exception handling

In de JMS 2.0 API wordt de unchecked JMSRuntimeException gebruikt in plaats van de checked JMSException, zie bijvoorbeeld ook codefragment 1. Dit betekent dat de aanroeper van de methodes in de JMS 2.0 API niet verplicht is deze Exception af te vangen.

Zie ter illustratie ook de createTextMessage() methode in respectievelijk de objecten Session en JMSContext.

   //klassieke API
   TextMessage createTextMessage() throws JMSException;

   //JMS 2.0
   TextMessage createTextMessage();

Wat ook een verbetering is in de JMS 2.0 API is dat de JMSRuntimeException nu ook een constructor heeft met een Throwable als argument. Bij de klassieke JMSExcepion ontbrak een dergelijke contstructor. In plaats daarvan heeft de JMSExcepion een linkedException, die in de praktijk vaak over het hoofd wordt gezien.

Aan de slag met JMS 2.0

Voor wie zelf wil ontdekken wat JMS 2.0 nog meer te bieden heeft, kan snel aan de slag met GlassFish en de JEE 7 SDK. De downloads bevatten diverse examples. Wie gebruik maakt van de built-in JMS Provider van GlassFish, is QBrowser een handige tool voor het bekijken van queues, topics en berichten.

http://www.oracle.com/technetwork/java/javaee/downloads/index.html
http://sourceforge.net/projects/qbrowserv2/
http://docs.oracle.com/javaee/7/tutorial/doc/partmessaging.htm#GFIRP3
https://jms-spec.java.net/2.0/apidocs/

Posted by Jaap Coomans at 16:01 on Sunday 30 June    Add 'Java EE 7' site to delicious  Add 'Java EE 7' site to technorati  Add 'Java EE 7' site to digg  Add 'Java EE 7' site to dzone

Op 28 mei is de definitieve versie van de Java EE 7 specificatie (JSR 342) gereleased. Niet lang daarna volgde op 12 juni de reference implementation GlassFish 4. Dat betekent dus dat we flink aan de slag kunnen om alle nieuwe speeltjes in het echt uit te gaan proberen. Om je daarbij op weg te helpen gaan we de komende weken in een serie blogs de meest interessante nieuwe aspecten van Java EE 7 behandelen. In dit eerste deel van de reeks volstaan we met een overzicht van de API’s in Java EE 7, afgezet tegen de API’s is Java EE 6 (JSR 316). Zo kan je in een oogopslag zien waar er iets veranderd is.

Volgens Oracle is er bij Java EE 7 voornamelijk aandacht besteed aan scalability en een vlugge blik op de press release leert dat er ook sterk naar HTML5 is gekeken. Twee van de vier nieuwe API’s (JSON-P en WebSocket) zijn hier een direct gevolg van. Ook het toevoegen van een stevig uitgebreid JAX-RS aan het Web-Profile ligt in die lijn.

API Java EE 6 Java EE 7
JSR Version JSR Version
Enterprise Java Beans (EJB) 318 3.1 345 3.2
Servlet 315 3.0 340 3.1
Java Server Pages (JSP) 245 2.2 245 2.3
Expression Language (EL) 245 2.2 341 3.0
Java Message Service (JMS) 914 1.1 343 2.0
Java Transaction API (JTA) 907 1.1 907 1.2
JavaMail 919 1.4 919 1.5
Java EE Connector Architecture (JCA) 322 1.6 322 1.7
Web Services 109 1.3 109 1.4
JAX-RPC (Optional) 101 1.1 101 1.1
JAX-WS 224 2.2 224 2.2
JAX-RS 311 1.1 339 2.0
WebSocket n.a. 356 1.0
JSON-P n.a. 353 1.0
Concurrency Utils for Java EE n.a. 236 1.0
Batch n.a. 352 1.0
JAXB 222 2.2 222 2.2
JAXR (Optional) 93 1.0 93 1.0
Java EE Management 77 1.1 77 1.1
Java EE Deployment (Optional) 88 1.2 88 1.2
Java Authorization Contract for Containers (JACC) 115 1.4 115 1.5
JASPIC 196 1.0 196 1.1
JSP Debugging 45 1.0 45 1.0
JSTL 52 1.2 52 1.2
Web Services Metadata 181 2.1 181 2.1
JavaServer Faces (JSF) 314 2.0 344 2.2
Common Annotations 250 1.1 250 1.2
Java Persistence API (JPA) 317 2.0 338 2.1
Bean Validation 303 1.0 349 1.1
Managed Beans 316 1.0 316 1.0
Interceptors 318 1.1 318 1.2
Contexts and Dependency Injection for Java (CDI) 299 1.0 346 1.1
Dependency Injection for Java 330 1.0 330 1.0

Posted by Martijn van de Rijdt at 11:53 on Monday 3 June    Add 'Hoe simpel is SimpleDateFormat?' site to delicious  Add 'Hoe simpel is SimpleDateFormat?' site to technorati  Add 'Hoe simpel is SimpleDateFormat?' site to digg  Add 'Hoe simpel is SimpleDateFormat?' site to dzone

Het komt nog wel eens voor dat je een datum/tijd wilt parsen. Hiervoor kunnen we in Java de standaard Java-klasse SimpleDateFormat gebruiken, op de volgende manier:

private void mijnMethode() {
   ...
   DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   Date date = dateFormat.parse(text);
   ...
}

Dit is correct, maar heeft wel een nadeel: elke keer dat mijnMethode uitgevoerd wordt, instantieert de JVM een nieuwe SimpleDateFormat en dat is een dure operatie. Het zou dus beter zijn om deze eenmaal aan te maken en vervolgens te hergebruiken.

Het ligt nogal voor de hand dit te doen door de DateFormat als constante op te slaan:

// DateFormat als constante; LET OP: niet threadsafe!
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
 
private void mijnMethode() {
   ...
   Date date = DATE_FORMAT.parse(text);
   ...
}

Dit heb ik in het verleden ook een aantal keer geschreven, en ik kom dit nog regelmatig tegen in projecten waar ik aan werk. Helaas is deze oplossing niet correct! (Zonder extra synchronisatie tenminste.)

In de kleine lettertjes van de Javadoc van SimpleDateFormat staat namelijk:


Synchronization

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

Als mijnMethode in meerdere threads gebruikt wordt kan de parse-methode falen met een exceptie of, erger nog, een foute Date teruggeven.

Gelukkig geeft de Javadoc ook een tip: maak een instantie aan per thread. Een makkelijke manier om dit te doen is met behulp van ThreadLocal. De code komt er dan als volgt uit te zien:

// SimpleDateFormat gewrapt in een ThreadLocal, omdat SimpleDateFormat niet threadsafe is.
private static final ThreadLocal<DateFormat> DATE_FORMAT = new ThreadLocal<>() {
   @Override
   protected DateFormat initialValue() {
       return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   }
};
 
private void mijnMethode() {
   ...
   Date date = DATE_FORMAT.get().parse(text);
   ...
}

Posted by Roy Wasse at 10:30 on Monday 25 June    Add 'Lancering Java glossy ‘Duke’ & win een Asus tablet' site to delicious  Add 'Lancering Java glossy ‘Duke’ & win een Asus tablet' site to technorati  Add 'Lancering Java glossy ‘Duke’ & win een Asus tablet' site to digg  Add 'Lancering Java glossy ‘Duke’ & win een Asus tablet' site to dzone

DUKE

Wauw! Eindelijk krijgt de mascotte van Java, the ‘Duke’, zijn eigen glossy.
Goede timing ook, aangezien het Java magazine tot nader orde niet meer wordt uitgegeven.

Dus: ben jij een gepassioneerde Java engineer & lees je graag interessante artikelen van collega-ontwikkelaars? Download dan nu ‘Duke’ via deze link! In Duke vind je bovendien een prijsvraag waarmee je een Asus Android tablet kunt winnen.

Wil je ‘Duke’ graag per post ontvangen? Dat kan ook! Laat hier je gegevens achter en wij zorgen dat je een hardcopy thuisgestuurd krijgt (zolang de voorraad strekt).

Posted by Jaap Coomans at 17:52 on Thursday 23 December    Add 'The Deal' site to delicious  Add 'The Deal' site to technorati  Add 'The Deal' site to digg  Add 'The Deal' site to dzone

Stephen Colebourne has a very interesting view on “The Deal” on his blog. The deal between the owner of Java and the Java community to be more precise. At Devoxx 2010 he said more or less the same thing during the Future of Java discussion panel. It thought it was an interesting view on the synergy between Oracle and the Java community, but nearly forgot about it, until I stumbled upon his blog today.

Read Stephen’s post on his blog.

Posted by Martijn van de Rijdt at 11:52 on Tuesday 7 December    Add 'Performance Anxiety' site to delicious  Add 'Performance Anxiety' site to technorati  Add 'Performance Anxiety' site to digg  Add 'Performance Anxiety' site to dzone

As I mentioned in my way-too-long previous post, one of my favourite talks at Devoxx was Joshua Bloch’s Performance Anxiety, about performance measurement and optimisation of (Java) applications.

You can now watch this talk (for free) here!

Posted by Martijn van de Rijdt at 22:14 on Tuesday 23 November    Add 'Devoxx 2010' site to delicious  Add 'Devoxx 2010' site to technorati  Add 'Devoxx 2010' site to digg  Add 'Devoxx 2010' site to dzone

Last week I was at Devoxx! There will probably be more in-depth blog posts here about some of the sessions, but for now, here’s an overview of all of the sessions I was able to attend and my own impressions.

Wednesday

Read the rest of this entry »

Posted by Martijn van de Rijdt at 10:32 on Tuesday 31 August    Add 'HTTP Requester' site to delicious  Add 'HTTP Requester' site to technorati  Add 'HTTP Requester' site to digg  Add 'HTTP Requester' site to dzone

Yesterday I found a nice and simple JavaFX tool for firing off HTTP requests and examining the server’s response: HTTP Requester.

Found it via the blog of Jonathan Giles. His blog has a weekly Java Desktop links of the week feature, which seems worth following if you’re interested in JavaFX and/or other Java (desktop) GUI frameworks.

Posted by Martijn van de Rijdt at 18:18 on Saturday 14 August    Add 'Java sound' site to delicious  Add 'Java sound' site to technorati  Add 'Java sound' site to digg  Add 'Java sound' site to dzone

Recently I’ve been working on an application which, when a certain event occurs, should give off a warning to its end user. A warning in this case literally means displaying a bright red warning screen and blaring an audio clip. Displaying a red screen wasn’t too hard, but I don’t deal with playing audio from Java applications every day, so that took me a little effort.

Read the rest of this entry »


© 2018 Java Competence Network. All Rights Reserved.