Lo que no se sabe expresar, es que no se sabe.
Friedrich Engels

Java Message Service

Messaging is a method of communication between software components where a Client can send messages to and receive messages from any other Client. Each client connects to a messaging Agent that provides facilities for creating, sending, receiving and reading messages.

  • Loosely coupled, the destination is all that the sender and receiver have in common.
  • Reliable, a message is delivered once and only once, though lower levels of reliability are available.

Java Message Service (JMS) is a Java API defines a common set of interfaces and associated semantics that allow applications written in the Java programming language to communicate with other messaging implementations.

  • Application clients, Enterprise JavaBeans components and web components can send or synchronously receive a JMS Message.
    • Can be set a message listener that allows JMS messages to be delivered to it asynchronously by being notified when a message is available.
  • Message-driven beans enable asynchronous consumption of messages in the EJB container.
    • Applications typically pools message-driven beans to implement concurrent processing of messages.
  • Message send and receive can participate in Java Transaction API (JTA) transactions, which allow JMS operations and database accesses to take place within a single transaction.
  • By accessing the JMS provider through a resource adapter in a Java EE Connector architecture
    • Vendors can create JMS providers that can be plugged in to multiple application servers.
    • Application servers can support multiple JMS providers.

The current release, defined in the JSR-343, is 2.0 and is part of Java EE 7.

JMS API Architecture

JMS API Architecture

A JMS application is composed of the following parts

  • JMS provider is a messaging system that implements the JMS interfaces and provides administrative and control features.
  • JMS clients are the components that produce and consume messages.
  • Messages are the objects that communicate information between the JMS clients.
  • Administered objects are JMS objects configured for the use of clients.
    • Destinations
    • Connection factories
    • Point to Point
    • Publish / Subscriber

Messaging Style

  •  Point to Point
  • Publish / Subscriber

JMS - Messaging Style - Point to Point

JMS - Messaging Style - Publish_Subscriber

Message Consumption

  • Synchronous.
  • Asynchronous, register a message listener with a consumer.

JMS API Programming Model

JMS API Programming Model

The basic building blocks of a JMS application are

  • Administered objects, which are portable (ordinarily defined in a JNDI namespace and injected into JMS clients).
    • Connection Factories, may be ConnectionFactory, QueueConnectionFactory or TopicConnectionFactory.
    • Destinations, objects (queue or topic) a client uses to specify the target of messages it produces and the source of messages it consumes.
    • The behavior of the application will depend on the kind of destination you use and not on the kind of connection factory you use.
  • JMSContext objects, which combine a Connection and a Session in one object
    • A Connection encapsulates a virtual connection with a JMS provider (could represent an open TCP/IP socket between a client and a provider service daemon).
    • A Session is a single-threated context for producing and consuming messages
      • Provides a transactional context with which to group a set of sends and receives into an atomic unit of work.
  • Message producers (JMSProducer), is a lightweight object (so no need to store it) created by a JMSContext or a session and used for sending messages to a destination.
  • Message consumers (JMSConsumer)
    • Can be switched on and off (start / stop).
    • Set a MessageListener for asynchronous messages.
    • Use a Message Selector (a String that contains an expresion) for filtering the messages received.
  • Messages. Can have
    • Header (required): JMSMessageID, JMSCorrelationID, JMSType (TextMessage, MapMessage, BytesMessage, StreamMessage, ObjectMessage, Message), JMSDestination, JMSReplyTo, JMSDeliveryMode, JMSDeliveryTime, JMSExpiration, JMSPriority, JMSTimestamp, JMSRedelivered.
    • Properties (optional), if additional values are needed for compatibility or for filtering (message selectors).
    • Body (optional), each of the 6 possible Message Types has different Message Bodies.

In addition

  • Queue browsers.
  • JMSException is the root class for all checked exceptions in the JMS API, JMSRuntimeException is for all unchecked.

Documentation

Related concepts

  •  MOM Messaging-Oriented Middleware.

Logger Interceptor

Credits go to Ionut Posea.

@Aspect
@Component
class LoggerInterceptor {
    @Around("within(eu.europa.ec.comp.genis.metadata..*)")
    public Object profileSaveMethod(ProceedingJoinPoint call) throws Throwable {
        StopWatch clock = new StopWatch("Profiling:::::" + call.signature + ":::::Args::::::" + call.args );
        try {
            clock.start(call.toShortString());
            return call.proceed();
        } finally {
            clock.stop();
            println(clock.prettyPrint());
        }
    }
}

Java8 – Repeating Annotations

Extracted from Java 8 Repeating Annotation Explained in 5 minutes.

Prior to Java8

@Manufactures({
	@Manufacturer(name =”BMW”),
	@Manufacturer(name = “Range Rover”)
})
public class Car{
//code goes in here
}

With Java8, an annotation can be repeatable using @Repeatable annotation.

@Manufacturer(name = “BMW”)
@Manufacturer(name= “Range Rover”)
public class Car{
//code goes in here
}

And can be retrieved

  • via their container annotation using getDeclaredAnnotation() or getAnnotation().
  • via Reflection API using getAnnotationsByType() or getDeclaredAnnotationsByType().

Example

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
 
public class RepeatingAnnotations {
 
   @Retention( RetentionPolicy.RUNTIME )
    public @interface Cars {
        Manufacturer[] value() default{};
    }
 
    @Manufacturer( "Mercedes Benz")
    @Manufacturer( "Toyota")
    @Manufacturer( "BMW")
    @Manufacturer( "Range Rover")
    public interface Car { 
 
    }
 
    @Repeatable(value = Cars.class )
    public @interface Manufacturer {
        String value();
 
    };
 
    public static void main(String[] args) {
        Manufacturer[] a = Car.class.getAnnotationsByType(Manufacturer.class );
        System.out.println("Number of car manufacturers is "+ a.length );
        System.out.println("-------Printing out Car Manufacturers--------");
        Cars cars = Car.class.getAnnotation(Cars.class);
        for(Manufacturer car: cars.value()){
            System.out.println(car.value());
        }
 
    }
}

Produces this output

Number of car manufacturers is 4
——-Printing out Car Manufacturers——–
Mercedes Benz
Toyota
BMW
Range Rover

Understanding Java Memory Management

Conferencia de unos 40 minutos (más 20 de preguntas) de Chris Bailey (IBM) sobre la gestión de memoria en Java.

La memoria disponible será dividida entre

  • Lo que consume el Sistema Operativo y las librerías de C que soportan la JVM (Java, como tantos otros lenguages de programación, basa su máquina virtual en C).
  • Lo que consume la JVM (Java Virtual Machine).
  • Lo que asignamos como Java Heap (tamaño fijo de .Xmx).
  • El resto + lo que consume la JVM es Native Heap.

Durante la ejecución, podemos quedarnos sin memoria tanto en la Native Heap como en la Java Heap.

Las máquinas con arquitecturas 32bits nunca pueden utilizar más de 4 gigas en total.

En una arquitectura de 32bits, el tipo primitivo “int” tiene un tamaño de 32bits, pero Integer es 4 veces mayor : 1 slot de 32bits para el int, otro apuntar a la class, otro para flags y otro para lock, lo que nos da un total de 128bits. Un Array Object tiene lo mismo que Integer más otro slot para la size, lo que nos da un total de 160bits.

Sin embargo, en una arquitectura de 64 bits, el tipo primitivo ”int” mantienetiene un tamaño de 32bits, pero Integer tiene 1 slot de 64bits para apuntar a la class, otro para flags y uno para lock, más el “int” de 32 bits, es decir 224bits en total. Un Array Object tiene lo mismo que Integer más otro slot para la size, lo que ahora da un total de 288bits.

Cuando instanciamos una colección, se reservan un número de instancias por defecto (por ejemplo 16 para HashSet y HashMap). Cuando las colecciones se llenan, para introducir un nuevo elemento se dobla el tamaño que ocupaba. Por eso se desperdicia mucha memoria.

Use Memory Analyzer Tool (as Eclipse Memory Analyzer Tool) for checking your applications. Para obtener un volcado de la memoria en el momento en el que nos quedamos sin memoria, podemos arrancar nuestra app con el flag para la JVM -XX:+HeapDumpOnOutOfMemoryError, opcionalmente también podemos utilizar -XX:HeapDumpPath=.

Double Brace Initialization en Java

How cool is this? Y yo sin conocer esto, deja el código mucho más claro y menos verbose.

new JLabel("Hey there"){{ 
    setBackground(Color.black);
    setForeground(Color.white);
}}
Comenta